From 67aaa6418184e050ee06a1ec25e855a2e86107aa Mon Sep 17 00:00:00 2001 From: Gopalji Gaur Date: Wed, 6 Nov 2024 22:16:35 +0100 Subject: [PATCH 01/24] Fixed `priorband_template.py` example Add non-negative value check for fidelity parameter. --- neps/optimizers/multi_fidelity/successive_halving.py | 2 +- neps/search_spaces/hyperparameters/numerical.py | 6 ++++++ neps_examples/template/priorband_template.py | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/neps/optimizers/multi_fidelity/successive_halving.py b/neps/optimizers/multi_fidelity/successive_halving.py index 3d27b061..08a8cbc2 100644 --- a/neps/optimizers/multi_fidelity/successive_halving.py +++ b/neps/optimizers/multi_fidelity/successive_halving.py @@ -105,7 +105,7 @@ def __init__( self.sample_default_first = sample_default_first self.sample_default_at_target = sample_default_at_target - assert self.pipeline_space.fidelity is not None + assert self.pipeline_space.fidelity is not None, "Fidelity parameter not set." self.min_budget = self.pipeline_space.fidelity.lower self.max_budget = self.pipeline_space.fidelity.upper self.eta = eta diff --git a/neps/search_spaces/hyperparameters/numerical.py b/neps/search_spaces/hyperparameters/numerical.py index a6bd5673..45774195 100644 --- a/neps/search_spaces/hyperparameters/numerical.py +++ b/neps/search_spaces/hyperparameters/numerical.py @@ -119,6 +119,12 @@ def __init__( f"{default_confidence}" ) + if is_fidelity and (lower <= 0 or upper <= 0): + raise ValueError( + f"{_cls_name} parameter: fidelity parameter bounds error (log scale " + f"can't have bounds <= 0). Actual values: lower={lower}, upper={upper}" + ) + # Validate 'log' and 'is_fidelity' types to prevent configuration errors # from the YAML input for param, value in {"log": log, "is_fidelity": is_fidelity}.items(): diff --git a/neps_examples/template/priorband_template.py b/neps_examples/template/priorband_template.py index e2d75433..38154ef8 100644 --- a/neps_examples/template/priorband_template.py +++ b/neps_examples/template/priorband_template.py @@ -48,7 +48,7 @@ def pipeline_space() -> dict: default=1e-3, # a non-None value here acts as the mode of the prior distribution ), wd=neps.Float( - lower=0, + lower=1e-5, upper=1e-1, log=True, default=1e-3, From 4abb9de41079a71e6064f9e655e8449d93c60936 Mon Sep 17 00:00:00 2001 From: Gopalji Gaur Date: Thu, 7 Nov 2024 15:02:40 +0100 Subject: [PATCH 02/24] Fixed pytest with new fidelity parameter checks --- .../correct_config.yaml | 2 +- .../correct_config_including_types.yaml | 2 +- .../incorrect_fidelity_bounds_config.yaml | 22 +++++++++++++++++++ .../test_search_space.py | 10 ++++++++- 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 tests/test_yaml_search_space/incorrect_fidelity_bounds_config.yaml diff --git a/tests/test_yaml_search_space/correct_config.yaml b/tests/test_yaml_search_space/correct_config.yaml index 1264127a..b8c34866 100644 --- a/tests/test_yaml_search_space/correct_config.yaml +++ b/tests/test_yaml_search_space/correct_config.yaml @@ -5,7 +5,7 @@ param_float1: is_fidelity: off param_int1: - lower: -3 + lower: 3 upper: 30 log: false is_fidelity: on diff --git a/tests/test_yaml_search_space/correct_config_including_types.yaml b/tests/test_yaml_search_space/correct_config_including_types.yaml index 95a38074..4ae8cb9c 100644 --- a/tests/test_yaml_search_space/correct_config_including_types.yaml +++ b/tests/test_yaml_search_space/correct_config_including_types.yaml @@ -6,7 +6,7 @@ param_float1: param_int1: type: integer - lower: -3 + lower: 3 upper: 30 is_fidelity: True diff --git a/tests/test_yaml_search_space/incorrect_fidelity_bounds_config.yaml b/tests/test_yaml_search_space/incorrect_fidelity_bounds_config.yaml new file mode 100644 index 00000000..552c775d --- /dev/null +++ b/tests/test_yaml_search_space/incorrect_fidelity_bounds_config.yaml @@ -0,0 +1,22 @@ +param_float1: + lower: 0.00001 + upper: 0.1 + log: TRUE + is_fidelity: off + +param_int1: + lower: -3 # negative fidelity range + upper: 30 + log: false + is_fidelity: on + +param_int2: + type: int + lower: 1E2 + upper: 3e4 + log: ON + is_fidelity: FALSE + +param_float2: + lower: 3.3e-5 + upper: 1.5E-1 diff --git a/tests/test_yaml_search_space/test_search_space.py b/tests/test_yaml_search_space/test_search_space.py index bfc1c84c..6d0b8c5c 100644 --- a/tests/test_yaml_search_space/test_search_space.py +++ b/tests/test_yaml_search_space/test_search_space.py @@ -19,7 +19,7 @@ def test_correct_yaml_file(path): assert isinstance(pipeline_space, dict) float1 = Float(0.00001, 0.1, log=True, is_fidelity=False) assert float1.__eq__(pipeline_space["param_float1"]) is True - int1 = Integer(-3, 30, log=False, is_fidelity=True) + int1 = Integer(3, 30, log=False, is_fidelity=True) assert int1.__eq__(pipeline_space["param_int1"]) is True int2 = Integer(100, 30000, log=True, is_fidelity=False) assert int2.__eq__(pipeline_space["param_int2"]) is True @@ -143,3 +143,11 @@ def test_categorical_default_value_not_in_choices(): with pytest.raises(SearchSpaceFromYamlFileError) as excinfo: pipeline_space_from_yaml(BASE_PATH + "default_value_not_in_choices_config.yaml") assert excinfo.value.exception_type == "ValueError" + +@pytest.mark.neps_api +def test_incorrect_fidelity_parameter_bounds(): + """Test if a ValueError is raised when the bounds of a fidelity parameter are + not correctly specified.""" + with pytest.raises(SearchSpaceFromYamlFileError) as excinfo: + pipeline_space_from_yaml(BASE_PATH + "incorrect_fidelity_bounds_config.yaml") + assert excinfo.value.exception_type == "ValueError" From 4e9efeed729aa809b5bbdff61c794b1e68cea010 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 14 Nov 2024 05:28:40 +0100 Subject: [PATCH 03/24] Fix structuring of CONTRIBUTING docs --- CONTRIBUTING.md | 92 ++++++++++++------------------------------------- 1 file changed, 22 insertions(+), 70 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 176869af..f8d9eda1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,7 +23,7 @@ There are three required steps and one optional: For instructions see below. -## 1. Optional: Install miniconda and create a virtual environment +### 1. Optional: Install miniconda and create a virtual environment To manage python versions install e.g., miniconda with @@ -42,7 +42,7 @@ conda create -n neps python=3.10 conda activate neps ``` -## 2. Install poetry +### 2. Install poetry First, install poetry, e.g., via @@ -59,7 +59,7 @@ export PATH="$HOME/.local/bin:$PATH" to your `.zshrc` / `.bashrc` or alternatively simply running the export manually. -## 3. Install the neps Package Using poetry +### 3. Install the neps Package Using poetry Clone the repository, e.g., @@ -76,7 +76,7 @@ poetry install This will installthe neps package but also additional dev dependencies. -## 4. Activate pre-commit for the repository +### 4. Activate pre-commit for the repository With the python environment used to install the neps package run in the main directory of neps @@ -93,9 +93,6 @@ your choice, e.g. [VSCode](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff), [PyCharm](https://plugins.jetbrains.com/plugin/20574-ruff). - -# Checks and Tests - We have setup checks and tests at several points in the development flow: - At every commit we automatically run a suite of [pre-commit](https://pre-commit.com/) hooks that perform static code analysis, autoformating, and sanity checks. @@ -104,7 +101,9 @@ This is setup during our [installation process](https://automl.github.io/neps/co The tests correspond directly to examples in [neps_examples](https://github.com/automl/neps/tree/master/neps_examples) and only check for crash-causing errors. - At every push all integration tests and regression tests are run automatically using [github actions](https://github.com/automl/neps/actions). -## Linting (Ruff) +## Checks and tests + +### Linting (Ruff) For linting we use `ruff` for checking code quality. You can install it locally and use it as so: ```bash @@ -127,7 +126,7 @@ The configuration of `ruff` is in the `pyproject.toml` file and we refer you to There you can find the documentation for all of the rules employed. -## Type Checking (Mypy) +### Type Checking (Mypy) For type checking we use `mypy`. You can install it locally and use it as so: ```bash @@ -159,64 +158,17 @@ or types defined from NePS, there is probably a good reason for a mypy error. If you have issues regarding typing, please feel free to reach out for help `@eddiebergman`. -## Examples and Integration Tests +### Examples and Integration Tests -We use examples in [neps_examples](https://github.com/automl/neps/tree/master/neps_examples) as integration tests, which we run from the main directory via +We use some examples in [neps_examples](https://github.com/automl/neps/tree/master/neps_examples) as integration tests, which we run from the main directory via ```bash pytest ``` -If tests fail for you on the master, please raise an issue on github, preferabbly with some informationon the error, +If tests fail for you on the master, please raise an issue on github, preferably with some information on the error, traceback and the environment in which you are running, i.e. python version, OS, etc. -## Regression Tests - -Regression tests are run on each push to the repository to assure the performance of the optimizers don't degrade. - -Currently, regression runs are recorded on JAHS-Bench-201 data for 2 tasks: `cifar10` and `fashion_mnist` and only for optimizers: `random_search`, `bayesian_optimization`, `mf_bayesian_optimization`. -This information is stored in the `tests/regression_runner.py` as two lists: `TASKS`, `OPTIMIZERS`. -The recorded results are stored as a json dictionary in the `tests/losses.json` file. - -### Adding new optimizer algorithms - -Once a new algorithm is added to NEPS library, we need to first record the performance of the algorithm for 100 optimization runs. - -- If the algorithm expects standard loss function (pipeline) and accepts fidelity hyperparameters in pipeline space, then recording results only requires adding the optimizer name into `OPTIMIZERS` list in `tests/regression_runner.py` and running `tests/regression_runner.py` - -- In case your algorithm requires custom pipeline and/or pipeline space you can modify the `runner.run_pipeline` and `runner.pipeline_space` attributes of the `RegressionRunner` after initialization (around line `#322` in `tests/regression_runner.py`) - -You can verify the optimizer is recorded by rerunning the `regression_runner.py`. -Now regression test will be run on your new optimizer as well on every push. - -### Regression test metrics - -For each regression test the algorithm is run 10 times to sample its performance, then they are statistically compared to the 100 recorded runs. We use these 3 boolean metrics to define the performance of the algorithm on any task: - -1. [Kolmogorov-Smirnov test for goodness of fit](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.kstest.html) - `pvalue` >= 10% -1. Absolute median distance - bounded within 92.5% confidence range of the expected median distance -1. Median improvement - Median improvement over the recorded median - -Test metrics are run for each `(optimizer, task)` combination separately and then collected. -The collected metrics are then further combined into 2 metrics - -1. Task pass - either both `Kolmogorov-Smirnov test` and `Absolute median distance` test passes or just `Median improvement` -1. Test aggregate - Sum_over_tasks(`Kolmogorov-Smirnov test` + `Absolute median distance` + 2 * `Median improvement`) - -Finally, a test for an optimizer only passes when at least for one of the tasks `Task pass` is true, and `Test aggregate` is higher than 1 + `number of tasks` - -### On regression test failures - -Regression tests are stochastic by nature, so they might fail occasionally even the algorithm performance didn't degrade. -In the case of regression test failure, try running it again first, if the problem still persists, then you can contact [Danny Stoll](mailto:stolld@cs.uni-freiburg.de) or [Samir](mailto:garibovs@cs.uni-freiburg.de). -You can also run tests locally by running: - -``` -poetry run pytest -m regression_all -``` - -## Disabling and Skipping Checks etc. - ### Pre-commit: How to not run hooks? To commit without running `pre-commit` use `git commit --no-verify -m `. @@ -231,11 +183,11 @@ There are two options: code = "foo" # type: ignore ``` -## Managing Dependencies +### Managing Dependencies To manage dependencies and for package distribution we use [poetry](https://python-poetry.org/docs/) (replaces pip). -## Add dependencies +#### Add dependencies To install a dependency use @@ -247,7 +199,7 @@ and commit the updated `pyproject.toml` to git. For more advanced dependency management see examples in `pyproject.toml` or have a look at the [poetry documentation](https://python-poetry.org/). -## Install dependencies added by others +#### Install dependencies added by others When other contributors added dependencies to `pyproject.toml`, you can install them via @@ -256,7 +208,7 @@ poetry lock poetry install ``` -# Documentation +## Documentation We use [MkDocs](https://www.mkdocs.org/getting-started/), more specifically [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/) for documentation. To support documentation for multiple versions, we use the plugin [mike](https://github.com/jimporter/mike). @@ -278,7 +230,7 @@ To publish the documentation run mike deploy 0.5.1 latest -p ``` -# Releasing a New Version +## Releasing a New Version There are four steps to releasing a new version of neps: @@ -288,11 +240,11 @@ There are four steps to releasing a new version of neps: 3. Update Documentation 4. Publish on PyPI -## 0. Understand Semantic Versioning +### 0. Understand Semantic Versioning We follow the [semantic versioning](https://semver.org) scheme. -## 1. Update the Package Version and CITATION.cff +### 1. Update the Package Version and CITATION.cff ```bash poetry version v0.9.0 @@ -300,7 +252,7 @@ poetry version v0.9.0 and manually change the version specified in `CITATION.cff`. -## 2. Commit with a Version Tag +### 2. Commit with a Version Tag First commit and test @@ -318,7 +270,7 @@ git push --tags git push ``` -## 3. Update Documentation +### 3. Update Documentation First check if the documentation has any issues via @@ -335,11 +287,11 @@ Afterwards, publish it via mike deploy 0.9.0 latest -up ``` -## 4. Publish on PyPI +### 4. Publish on PyPI To publish to PyPI: -1. Get publishing rights, e.g., asking Danny or Maciej or Neeratyoy. +1. Get publishing rights, e.g., asking Danny or Neeratyoy. 2. Be careful, once on PyPI we can not change things. 3. Run From cb25249d7aec8c17090c99746d771b789d714717 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 14 Nov 2024 05:29:44 +0100 Subject: [PATCH 04/24] improve conciseness of README --- README.md | 58 +++++++++++---------------------------------------- docs/index.md | 55 ++++++++++-------------------------------------- 2 files changed, 23 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index cf963330..0ff61462 100644 --- a/README.md +++ b/README.md @@ -5,25 +5,24 @@ [![License](https://img.shields.io/pypi/l/neural-pipeline-search?color=informational)](LICENSE) [![Tests](https://github.com/automl/neps/actions/workflows/tests.yaml/badge.svg)](https://github.com/automl/neps/actions) -Welcome to NePS, a powerful and flexible Python library for hyperparameter optimization (HPO) and neural architecture search (NAS) with its primary goal: **make HPO and NAS usable for deep learners in practice**. +Welcome to NePS, a powerful and flexible Python library for hyperparameter optimization (HPO) and neural architecture search (NAS) that **makes HPO and NAS practical for deep learners**. -NePS houses recently published and also well-established algorithms that can all be run massively parallel on distributed setups, with tools to analyze runs, restart runs, etc., all **tailored to the needs of deep learning experts**. +NePS houses recently published and also well-established algorithms that can all be run massively parallel on distributed setups and, in general, NePS is tailored to the needs of deep learning experts. -Take a look at our [documentation](https://automl.github.io/neps/latest/) for all the details on how to use NePS! +To learn about NePS, check-out [the documentation](https://automl.github.io/neps/latest/), [our examples](neps_examples/), or a [colab tutorial](https://colab.research.google.com/drive/11IOhkmMKsIUhWbHyMYzT0v786O9TPWlH?usp=sharing). ## Key Features -In addition to the features offered by traditional HPO and NAS libraries, NePS, e.g., stands out with: +In addition to the features offered by traditional HPO and NAS libraries, NePS stands out with: - -1. [**Hyperparameter Optimization (HPO) with Prior Knowledge and Cheap Proxies:**](neps_examples/template/priorband_template.py)

-NePS excels in efficiently tuning hyperparameters using algorithms that enable users to make use of their prior knowledge within the search space. This is leveraged by the insights presented in: - - [PriorBand: Practical Hyperparameter Optimization in the Age of Deep Learning](https://arxiv.org/abs/2306.12370) - - [πBO: Augmenting Acquisition Functions with User Beliefs for Bayesian Optimization](https://arxiv.org/abs/2204.11051)

-1. [**Neural Architecture Search (NAS) with General Search Spaces:**](neps_examples/basic_usage/architecture.py)

- NePS is equipped to handle context-free grammar search spaces, providing advanced capabilities for designing and optimizing architectures. this is leveraged by the insights presented in: - - [Construction of Hierarchical Neural Architecture Search Spaces based on Context-free Grammars](https://arxiv.org/abs/2211.01842)

-1. [**Easy Parallelization and Design Tailored to DL:**](https://automl.github.io/neps/latest/examples/efficiency/)

+1. **Hyperparameter Optimization (HPO) Efficient Enough For Deep Learning:**
+ NePS excels in efficiently tuning hyperparameters using algorithms that enable users to make use of their prior knowledge, while also using many other efficiency boosters. + - [PriorBand: Practical Hyperparameter Optimization in the Age of Deep Learning (NeurIPS 2023)](https://arxiv.org/abs/2306.12370) + - [πBO: Augmenting Acquisition Functions with User Beliefs for Bayesian Optimization (ICLR 2022)](https://arxiv.org/abs/2204.11051)

+1. **Neural Architecture Search (NAS) with Expressive Search Spaces:**
+ NePS provides capabilities for designing and optimizing architectures in an expressive and natural fashion. + - [Construction of Hierarchical Neural Architecture Search Spaces based on Context-free Grammars (NeurIPS 2023)](https://arxiv.org/abs/2211.01842)

+1. **Zero-effort Parallelization and an Experience Tailored to DL:**
NePS simplifies the process of parallelizing optimization tasks both on individual computers and in distributed computing environments. As NePS is made for deep learners, all technical choices are made with DL in mind and common DL tools such as Tensorboard are [embraced](https://automl.github.io/neps/latest/reference/analyse/#visualizing-results). @@ -36,12 +35,6 @@ To install the latest release from PyPI run pip install neural-pipeline-search ``` -To get the latest version from Github run - -```bash -pip install git+https://github.com/automl/neps.git -``` - ## Basic Usage Using `neps` always follows the same pattern: @@ -90,33 +83,6 @@ neps.run( max_evaluations_total=100, ) ``` -## Declarative Usage - -NePS offers a declarative approach to efficiently manage experiments. This method is particularly suitable for -conducting and managing a large number of experiments with different settings. Below is the example from Basic Usage: -```yaml -run_pipeline: - path: path/to/your/run_pipeline.py # Path to the function file - name: run_pipeline # Function name within the file -root_directory: "path/to/save/results" -pipeline_space: - hyperparameter_a: - lower: 1e-3 - upper: 1e-1 - log: True # Log scale for learning rate - hyperparameter_b: - lower: 1 - upper: 42 - architecture_parameter: - choices: [option_a, option_b] - -max_evaluations_total: 100 -``` -```bash -neps run --run-args path/to/your/config.yaml -``` -If you would like to learn more about how to use this, -[click here](https://automl.github.io/neps/latest/reference/declarative_usage/). ## Examples diff --git a/docs/index.md b/docs/index.md index 2f6f6928..d239d339 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,17 +11,16 @@ NePS houses recently published and also well-established algorithms that can all ## Key Features -In addition to the features offered by traditional HPO and NAS libraries, NePS, e.g., stands out with: - - -1. [**Hyperparameter Optimization (HPO) with Prior Knowledge and Cheap Proxies:**](.examples/template/priorband_template.py)

-NePS excels in efficiently tuning hyperparameters using algorithms that enable users to make use of their prior knowledge within the search space. This is leveraged by the insights presented in: - - [PriorBand: Practical Hyperparameter Optimization in the Age of Deep Learning](https://arxiv.org/abs/2306.12370) - - [πBO: Augmenting Acquisition Functions with User Beliefs for Bayesian Optimization](https://arxiv.org/abs/2204.11051)

-1. [**Neural Architecture Search (NAS) with General Search Spaces:**](neps_examples/basic_usage/architecture.py)

- NePS is equipped to handle context-free grammar search spaces, providing advanced capabilities for designing and optimizing architectures. this is leveraged by the insights presented in: - - [Construction of Hierarchical Neural Architecture Search Spaces based on Context-free Grammars](https://arxiv.org/abs/2211.01842)

-1. [**Easy Parallelization and Design Tailored to DL:**](.examples/efficiency/)

+In addition to the features offered by traditional HPO and NAS libraries, NePS stands out with: + +1. **Hyperparameter Optimization (HPO) Efficient Enough For Deep Learning:**
+ NePS excels in efficiently tuning hyperparameters using algorithms that enable users to make use of their prior knowledge, while also using many other efficiency boosters. + - [PriorBand: Practical Hyperparameter Optimization in the Age of Deep Learning (NeurIPS 2023)](https://arxiv.org/abs/2306.12370) + - [πBO: Augmenting Acquisition Functions with User Beliefs for Bayesian Optimization (ICLR 2022)](https://arxiv.org/abs/2204.11051)

+1. **Neural Architecture Search (NAS) with Expressive Search Spaces:**
+ NePS provides capabilities for designing and optimizing architectures in an expressive and natural fashion. + - [Construction of Hierarchical Neural Architecture Search Spaces based on Context-free Grammars (NeurIPS 2023)](https://arxiv.org/abs/2211.01842)

+1. **Zero-effort Parallelization and an Experience Tailored to DL:**
NePS simplifies the process of parallelizing optimization tasks both on individual computers and in distributed computing environments. As NePS is made for deep learners, all technical choices are made with DL in mind and common DL tools such as Tensorboard are [embraced](https://automl.github.io/neps/latest/reference/analyse/#visualizing-results). @@ -32,6 +31,7 @@ NePS excels in efficiently tuning hyperparameters using algorithms that enable u * [Reference documentation](./reference/neps_run.md) for a quick overview. * [API](./api/neps/api.md) for a more detailed reference. + * [Colab Tutorial](https://colab.research.google.com/drive/11IOhkmMKsIUhWbHyMYzT0v786O9TPWlH?usp=sharing) walking through NePS's main features. * [Examples](./examples/template/basic_template.md) for copy-pastable code to get started. ## Installation @@ -42,12 +42,6 @@ To install the latest release from PyPI run pip install neural-pipeline-search ``` -To get the latest version from Github run - -```bash -pip install git+https://github.com/automl/neps.git -``` - ## Basic Usage Using `neps` always follows the same pattern: @@ -96,33 +90,6 @@ neps.run( max_evaluations_total=100, ) ``` -## Declarative Usage - -NePS offers a declarative approach to efficiently manage experiments. This method is particularly suitable for -conducting and managing a large number of experiments with different settings. Below is the example from Basic Usage: -```yaml -run_pipeline: - path: path/to/your/run_pipeline.py # Path to the function file - name: run_pipeline # Function name within the file -root_directory: "path/to/save/results" -pipeline_space: - hyperparameter_a: - lower: 1e-3 - upper: 1e-1 - log: True # Log scale for learning rate - hyperparameter_b: - lower: 1 - upper: 42 - architecture_parameter: - choices: [option_a, option_b] - -max_evaluations_total: 100 -``` -```bash -neps run --run-args path/to/your/config.yaml -``` -If you would like to learn more about how to use this, -[click here](https://automl.github.io/neps/latest/reference/declarative_usage/). ## Examples From 2842e894b8c3f99574941e16bd7b207854eea833 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 14 Nov 2024 05:35:02 +0100 Subject: [PATCH 05/24] update citations --- CITATION.cff | 8 ++------ CONTRIBUTING.md | 2 +- docs/citations.md | 8 ++++---- pyproject.toml | 4 +--- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index f62a3157..1536ffbe 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -21,13 +21,9 @@ authors: given-names: Carl - family-names: Binxin given-names: Ru - - family-names: Kober - given-names: Nils - - family-names: Vallaeys - given-names: Théophane - family-names: Hutter given-names: Frank title: "Neural Pipeline Search (NePS)" -version: 0.12.1 -date-released: 2024-07-03 +version: 0.12.2 +date-released: 2024-07-09 url: "https://github.com/automl/neps" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f8d9eda1..1f804aaf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -250,7 +250,7 @@ We follow the [semantic versioning](https://semver.org) scheme. poetry version v0.9.0 ``` -and manually change the version specified in `CITATION.cff`. +and manually change the version specified in `CITATION.cff` and `docs/citations.md` ### 2. Commit with a Version Tag diff --git a/docs/citations.md b/docs/citations.md index b697c49f..39b1759d 100644 --- a/docs/citations.md +++ b/docs/citations.md @@ -7,19 +7,19 @@ For citing NePS, please refer to the following: ### APA Style ```apa -Stoll, D., Mallik, N., Schrodi, S., Janowski, M., Garibov, S., Abou Chakra, T., Rogalla, D., Bergman, E., Hvarfner, C., Binxin, R., Kober, N., Vallaeys, T., & Hutter, F. (2023). Neural Pipeline Search (NePS) (Version 0.11.0) [Computer software]. https://github.com/automl/neps +Stoll, D., Mallik, N., Schrodi, S., Bergman, E., Janowski, M., Garibov, S., Abou Chakra, T., Rogalla, D., Bergman, E., Hvarfner, C., Binxin, R., & Hutter, F. (2023). Neural Pipeline Search (NePS) (Version 0.12.2) [Computer software]. https://github.com/automl/neps ``` ### BibTex Style ```bibtex @software{Stoll_Neural_Pipeline_Search_2023, -author = {Stoll, Danny and Mallik, Neeratyoy and Schrodi, Simon and Janowski, Maciej and Garibov, Samir and Abou Chakra, Tarek and Rogalla, Daniel and Bergman, Eddie and Hvarfner, Carl and Binxin, Ru and Kober, Nils and Vallaeys, Théophane and Hutter, Frank}, +author = {Stoll, Danny and Mallik, Neeratyoy and Schrodi, Simon and Bergmann, Eddie and Janowski, Maciej and Garibov, Samir and Abou Chakra, Tarek and Rogalla, Daniel and Bergman, Eddie and Hvarfner, Carl and Binxin, Ru and Hutter, Frank}, month = oct, title = {{Neural Pipeline Search (NePS)}}, url = {https://github.com/automl/neps}, -version = {0.11.0}, -year = {2023} +version = {0.12.2}, +year = {2024} } ``` diff --git a/pyproject.toml b/pyproject.toml index d86c9cf5..8dbaa5fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,8 +13,6 @@ authors = [ "Daniel Rogalla", "Carl Hvarfner", "Binxin Ru", - "Nils Kober", - "Théophane Vallaeys", "Frank Hutter", ] readme = "README.md" @@ -128,7 +126,7 @@ exclude = [ ] [tool.ruff.lint] -# Extend what ruff is allowed to fix, even it it may break +# Extend what ruff is allowed to fix, even if it may break # This is okay given we use it all the time and it ensures # better practices. Would be dangerous if using for first # time on established project. From 310c82544d31bf576889aa93b403e0bb477b3627 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 14 Nov 2024 05:49:13 +0100 Subject: [PATCH 06/24] update roadmap --- docs/dev_docs/roadmap.md | 42 +++++++++++----------------------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/docs/dev_docs/roadmap.md b/docs/dev_docs/roadmap.md index af2cb3a0..9972334e 100644 --- a/docs/dev_docs/roadmap.md +++ b/docs/dev_docs/roadmap.md @@ -10,39 +10,15 @@ - Document large scale - Evaluate and maybe improve ease-of-use of NePS for DDP (Gopalji) - Optimize dependencies (Anton) -- Tensorboard st no one has to Touch it anymore (Tarek) - -### Fixes - -- ignore_errors should work seamlessly with all optimizers, also check different error handling Flags (Gopalji) -- Install all dependencies to run core examples always (Anton) - -### Refactoring - -(Anton) - -- Rename: run_pipeline = evaluate_pipeline -- Rename: loss = objective_to_minimize -- Rename: default = prior, default_confidence = prior_confidence -- Rename: budget = max_cost_total ### Documentation -- Update citations (also docs) (Danny) -- Notebooks add (Danny) - Remove templates (Danny) -- Rework readme (remove declarative API) (Danny) -- Improved examples - - New Lightning example (Gopalji) - - DDP examples (Gopalji) - - Larger examples (Gopalji) - - Tensorboard into new lightning example (Tarek) - - Example spawning cloud instances via run pipeline - -### Tests - -- Pytest needs to work on a fresh install (Anton) -- Regression tests to run on cluster on each version release +- Add New Lightning example (Gopalji) +- Add DDP examples (Gopalji) +- Add some larger examples (Gopalji, Anton) +- Improve new lightning example by adding Tensorboard (Tarek) +- Add optimizer pages (Anton, Neeratyoy) ## Before 1.0.0 version @@ -57,6 +33,10 @@ ### Documentation -- NAS documentation -- Optimizer pages (Anton, Neeratyoy) +- Add example for spawning cloud instances via run pipeline +- Add NAS documentation - Keep a changelog, add to it before each release + +### Tests + +- Regression tests to run on cluster on each version release From edb9e5e97f2f5922f05d903fa09947d429c2c5d7 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 14 Nov 2024 05:53:43 +0100 Subject: [PATCH 07/24] fix typo in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0ff61462..462587ab 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,12 @@ To learn about NePS, check-out [the documentation](https://automl.github.io/neps In addition to the features offered by traditional HPO and NAS libraries, NePS stands out with: -1. **Hyperparameter Optimization (HPO) Efficient Enough For Deep Learning:**
+1. **Hyperparameter Optimization (HPO) Efficient Enough for Deep Learning:**
NePS excels in efficiently tuning hyperparameters using algorithms that enable users to make use of their prior knowledge, while also using many other efficiency boosters. - [PriorBand: Practical Hyperparameter Optimization in the Age of Deep Learning (NeurIPS 2023)](https://arxiv.org/abs/2306.12370) - [πBO: Augmenting Acquisition Functions with User Beliefs for Bayesian Optimization (ICLR 2022)](https://arxiv.org/abs/2204.11051)

1. **Neural Architecture Search (NAS) with Expressive Search Spaces:**
- NePS provides capabilities for designing and optimizing architectures in an expressive and natural fashion. + NePS provides capabilities for optimizing DL architectures in an expressive and natural fashion. - [Construction of Hierarchical Neural Architecture Search Spaces based on Context-free Grammars (NeurIPS 2023)](https://arxiv.org/abs/2211.01842)

1. **Zero-effort Parallelization and an Experience Tailored to DL:**
NePS simplifies the process of parallelizing optimization tasks both on individual computers and in distributed From a1da041701a3d17e5c1a0009f993431db0f03370 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 14 Nov 2024 06:11:26 +0100 Subject: [PATCH 08/24] improve examples --- docs/index.md | 2 +- neps_examples/README.md | 12 +- neps_examples/__init__.py | 2 +- .../basic_usage/hpo_usage_example.py | 35 ---- neps_examples/basic_usage/hyperparameters.py | 3 +- .../declarative_usage/README.md | 0 .../declarative_usage/config.yaml | 0 .../declarative_usage/hpo_example.py | 0 neps_examples/experimental/cost_aware.py | 41 ---- neps_examples/experimental/fault_tolerance.py | 91 --------- .../freeze_thaw.py | 0 neps_examples/template/basic_template.py | 81 -------- neps_examples/template/ifbo_template.py | 37 ---- neps_examples/template/lightning_template.py | 175 ------------------ neps_examples/template/priorband_template.py | 152 --------------- 15 files changed, 6 insertions(+), 625 deletions(-) delete mode 100644 neps_examples/basic_usage/hpo_usage_example.py rename neps_examples/{ => convenience}/declarative_usage/README.md (100%) rename neps_examples/{ => convenience}/declarative_usage/config.yaml (100%) rename neps_examples/{ => convenience}/declarative_usage/hpo_example.py (100%) delete mode 100644 neps_examples/experimental/cost_aware.py delete mode 100644 neps_examples/experimental/fault_tolerance.py rename neps_examples/{efficiency => experimental}/freeze_thaw.py (100%) delete mode 100644 neps_examples/template/basic_template.py delete mode 100644 neps_examples/template/ifbo_template.py delete mode 100644 neps_examples/template/lightning_template.py delete mode 100644 neps_examples/template/priorband_template.py diff --git a/docs/index.md b/docs/index.md index d239d339..ec27c719 100644 --- a/docs/index.md +++ b/docs/index.md @@ -32,7 +32,7 @@ In addition to the features offered by traditional HPO and NAS libraries, NePS s * [Reference documentation](./reference/neps_run.md) for a quick overview. * [API](./api/neps/api.md) for a more detailed reference. * [Colab Tutorial](https://colab.research.google.com/drive/11IOhkmMKsIUhWbHyMYzT0v786O9TPWlH?usp=sharing) walking through NePS's main features. - * [Examples](./examples/template/basic_template.md) for copy-pastable code to get started. + * [Examples](./examples) for basic code snippets to get started. ## Installation diff --git a/neps_examples/README.md b/neps_examples/README.md index 9eb04e5d..b0b642ce 100644 --- a/neps_examples/README.md +++ b/neps_examples/README.md @@ -2,17 +2,11 @@ 1. **Basic usage examples** demonstrate fundamental usage. Learn how to perform Hyperparameter Optimization (HPO), Neural Architecture Search (NAS), and Joint Architecture and Hyperparameter Search (JAHS). -Understand how to analyze runs on a basic level, emphasizing that no neural network training is involved at this stage; the search is performed on functions to introduce NePS. +Understand how to analyze runs on a basic level. 2. **Efficiency examples** showcase how to enhance efficiency in NePS. Learn about expert priors, multi-fidelity, and parallelization to streamline your pipeline and optimize search processes. -3. **Convenience examples** show tensorboard compatibility and its integration, explore the compatibility with PyTorch Lightning, and understand file management within the run pipeline function used in NePS. +3. **Convenience examples** show tensorboard compatibility and its integration, explore the compatibility with PyTorch Lightning, see the declarative API, understand file management within the run pipeline function used in NePS. -4. **Experimental examples** tailored for NePS contributors. -These examples provide insights and practices for experimental scenarios. - -5. **Templates** to find a basic fill-in template to kickstart your hyperparameter search with NePS. -Use this template as a foundation for your projects, saving time and ensuring a structured starting point. - -6. **YAML usage examples** to define NePS configurations and search spaces with YAML files, streamlining the setup and execution of experiments. +4. **Experimental examples** tailored for NePS contributors. These examples provide insights and practices for experimental scenarios. diff --git a/neps_examples/__init__.py b/neps_examples/__init__.py index a48933d7..dc746892 100644 --- a/neps_examples/__init__.py +++ b/neps_examples/__init__.py @@ -3,7 +3,6 @@ "analyse", "architecture", "architecture_and_hyperparameters", - "hpo_usage_example", "hyperparameters", ], "convenience": [ @@ -11,6 +10,7 @@ "neps_tblogger_tutorial", "running_on_slurm_scripts", "neps_x_lightning", + "running_on_slurm_scripts", "working_directory_per_pipeline", ], "efficiency": [ diff --git a/neps_examples/basic_usage/hpo_usage_example.py b/neps_examples/basic_usage/hpo_usage_example.py deleted file mode 100644 index f1c58573..00000000 --- a/neps_examples/basic_usage/hpo_usage_example.py +++ /dev/null @@ -1,35 +0,0 @@ -import logging -import time - -import numpy as np - -import neps - -def run_pipeline( - float_name1, - float_name2, - categorical_name1, - categorical_name2, - integer_name1, - integer_name2, -): - # neps optimize to find values that maximizes sum, for demonstration only - loss = -float( - np.sum( - [float_name1, float_name2, categorical_name1, integer_name1, integer_name2] - ) - ) - if categorical_name2 == "a": - loss += 1 - - return loss - - -logging.basicConfig(level=logging.INFO) -neps.run( - run_pipeline=run_pipeline, - pipeline_space="search_space_example.yaml", - root_directory="results/hyperparameters_example", - post_run_summary=True, - max_evaluations_total=15, -) diff --git a/neps_examples/basic_usage/hyperparameters.py b/neps_examples/basic_usage/hyperparameters.py index 724974ae..914286d6 100644 --- a/neps_examples/basic_usage/hyperparameters.py +++ b/neps_examples/basic_usage/hyperparameters.py @@ -1,5 +1,4 @@ import logging -import time import numpy as np @@ -7,8 +6,8 @@ def run_pipeline(float1, float2, categorical, integer1, integer2): + # In this example we maximize an arbitrary sum for demonstration purposes loss = -float(np.sum([float1, float2, int(categorical), integer1, integer2])) - # time.sleep(0.7) # For demonstration purposes return loss diff --git a/neps_examples/declarative_usage/README.md b/neps_examples/convenience/declarative_usage/README.md similarity index 100% rename from neps_examples/declarative_usage/README.md rename to neps_examples/convenience/declarative_usage/README.md diff --git a/neps_examples/declarative_usage/config.yaml b/neps_examples/convenience/declarative_usage/config.yaml similarity index 100% rename from neps_examples/declarative_usage/config.yaml rename to neps_examples/convenience/declarative_usage/config.yaml diff --git a/neps_examples/declarative_usage/hpo_example.py b/neps_examples/convenience/declarative_usage/hpo_example.py similarity index 100% rename from neps_examples/declarative_usage/hpo_example.py rename to neps_examples/convenience/declarative_usage/hpo_example.py diff --git a/neps_examples/experimental/cost_aware.py b/neps_examples/experimental/cost_aware.py deleted file mode 100644 index 5b08bdcc..00000000 --- a/neps_examples/experimental/cost_aware.py +++ /dev/null @@ -1,41 +0,0 @@ -import logging -import time - -import numpy as np - -import neps - - -def run_pipeline( - pipeline_directory, float1, float2, categorical, integer1, integer2 -): - start = time.time() - y = -float(np.sum([float1, float2, int(categorical), integer1, integer2])) - end = time.time() - return { - "loss": y, - "cost": (end - start) + float1, - } - - -pipeline_space = dict( - float1=neps.Float(lower=0, upper=1, log=False), - float2=neps.Float( - lower=0, upper=10, log=False, default=10, default_confidence="medium" - ), - categorical=neps.Categorical(choices=[0, 1]), - integer1=neps.Integer(lower=0, upper=1, log=False), - integer2=neps.Integer(lower=0, upper=1, log=False), -) - -logging.basicConfig(level=logging.INFO) -neps.run( - run_pipeline=run_pipeline, - pipeline_space=pipeline_space, - root_directory="results/cost_aware_example", - searcher="cost_cooling", - max_evaluations_total=12, # TODO(Jan): remove - initial_design_size=5, - budget=100, -) -previous_results, pending_configs = neps.status("results/cost_aware_example") diff --git a/neps_examples/experimental/fault_tolerance.py b/neps_examples/experimental/fault_tolerance.py deleted file mode 100644 index 8406627e..00000000 --- a/neps_examples/experimental/fault_tolerance.py +++ /dev/null @@ -1,91 +0,0 @@ -""" To test the fault tolerance, run this script multiple times. -""" - -import logging - -import torch -import torch.nn.functional as F -from torch import nn, optim - -import neps - - -class TheModelClass(nn.Module): - """Taken from https://pytorch.org/tutorials/beginner/saving_loading_models.html""" - - def __init__(self): - super().__init__() - self.conv1 = nn.Conv2d(3, 6, 5) - self.pool = nn.MaxPool2d(2, 2) - self.conv2 = nn.Conv2d(6, 16, 5) - self.fc1 = nn.Linear(16 * 5 * 5, 120) - self.fc2 = nn.Linear(120, 84) - self.fc3 = nn.Linear(84, 10) - - def forward(self, x): - x = self.pool(F.relu(self.conv1(x))) - x = self.pool(F.relu(self.conv2(x))) - x = x.view(-1, 16 * 5 * 5) - x = F.relu(self.fc1(x)) - x = F.relu(self.fc2(x)) - x = self.fc3(x) - return x - - -def get_model_and_optimizer(learning_rate): - """Taken from https://pytorch.org/tutorials/beginner/saving_loading_models.html""" - model = TheModelClass() - optimizer = optim.SGD(model.parameters(), lr=learning_rate, momentum=0.9) - return model, optimizer - - -def run_pipeline(pipeline_directory, learning_rate): - model, optimizer = get_model_and_optimizer(learning_rate) - checkpoint_path = pipeline_directory / "checkpoint.pth" - - # Check if there is a previous state of the model training that crashed - if checkpoint_path.exists(): - checkpoint = torch.load(checkpoint_path) - model.load_state_dict(checkpoint["model_state_dict"]) - optimizer.load_state_dict(checkpoint["optimizer_state_dict"]) - epoch_already_trained = checkpoint["epoch"] - print(f"Read in model trained for {epoch_already_trained} epochs") - else: - epoch_already_trained = 0 - - for epoch in range(epoch_already_trained, 101): - epoch += 1 - - # Train model here .... - - # Repeatedly save your progress - if epoch % 10 == 0: - torch.save( - { - "epoch": epoch, - "model_state_dict": model.state_dict(), - "optimizer_state_dict": optimizer.state_dict(), - }, - checkpoint_path, - ) - - # Here we simulate a crash! E.g., due to job runtime limits - if epoch == 50 and learning_rate < 0.2: - print("Oh no! A simulated crash!") - exit() - - return learning_rate # Replace with actual error - - -pipeline_space = dict( - learning_rate=neps.Float(lower=0, upper=1), -) - -logging.basicConfig(level=logging.INFO) -neps.run( - run_pipeline=run_pipeline, - pipeline_space=pipeline_space, - root_directory="results/fault_tolerance_example", - max_evaluations_total=15, -) -previous_results, pending_configs = neps.status("results/fault_tolerance_example") diff --git a/neps_examples/efficiency/freeze_thaw.py b/neps_examples/experimental/freeze_thaw.py similarity index 100% rename from neps_examples/efficiency/freeze_thaw.py rename to neps_examples/experimental/freeze_thaw.py diff --git a/neps_examples/template/basic_template.py b/neps_examples/template/basic_template.py deleted file mode 100644 index 87e6c3ae..00000000 --- a/neps_examples/template/basic_template.py +++ /dev/null @@ -1,81 +0,0 @@ -""" -NOTE!!! This code is not meant to be executed. -It is only to serve as a template to help interface NePS with an existing ML/DL pipeline. - -The following script is designed as a template for using NePS. -It describes the crucial components that a user needs to provide in order to interface -a NePS optimizer. - -The 2 crucial components are: -* The search space, called the `pipeline_space` in NePS - * This defines the set of hyperparameters that the optimizer will search over - * This declaration also allows injecting priors in the form of defaults per hyperparameter -* The `run_pipeline` function - * This function is called by the optimizer and is responsible for running the pipeline - * The function should at the minimum expect the hyperparameters as keyword arguments - * The function should return the loss of the pipeline as a float - * If the return value is a dictionary, it should have a key called "loss" with the loss as a float - - -Overall, running an optimizer from NePS involves 4 clear steps: -1. Importing neccessary packages including neps. -2. Designing the search space as a dictionary. -3. Creating the run_pipeline and returning the loss and other wanted metrics. -4. Using neps run with the optimizer of choice. -""" - -import logging - -import neps - - -logger = logging.getLogger("neps_template.run") - - -def pipeline_space() -> dict: - # Create the search space based on NEPS parameters and return the dictionary. - # Example: - space = dict( - lr=neps.Float( - lower=1e-5, - upper=1e-2, - log=True, # If True, the search space is sampled in log space - default=1e-3, # a non-None value here acts as the mode of the prior distribution - ), - ) - return space - - -def run_pipeline(**config) -> dict | float: - # Run pipeline should include the following steps: - - # 1. Defining the model. - # 1.1 Load any checkpoint if necessary - # 2. Each optimization variable should get its values from the pipeline space. - # Example: - # learning_rate = config["lr"] - # 3. The training loop - # 3.1 Save any checkpoint if necessary - # 4. Returning the loss, which can be either as a single float or as part of - # an info dictionary containing other metrics. - - # Can use global logger to log any information - logger.info(f"Running pipeline with config: {config}") - - return dict or float - - -if __name__ == "__main__": - # 1. Creating the logger - - - # 2. Passing the correct arguments to the neps.run function - # For more information on the searcher, please take a look at this link: - # https://github.com/automl/neps/tree/master/neps/optimizers/README.md - - neps.run( - run_pipeline=run_pipeline, # User TODO (defined above) - pipeline_space=pipeline_space(), # User TODO (defined above) - root_directory="results", - max_evaluations_total=10, - ) diff --git a/neps_examples/template/ifbo_template.py b/neps_examples/template/ifbo_template.py deleted file mode 100644 index 9e99c820..00000000 --- a/neps_examples/template/ifbo_template.py +++ /dev/null @@ -1,37 +0,0 @@ -import numpy as np - -from neps.plot.plot3D import Plotter3D - -from .priorband_template import pipeline_space, run_pipeline - - -ASSUMED_MAX_LOSS = 10 - - -def ifbo_run_pipeline( - pipeline_directory, # The directory where the config is saved - previous_pipeline_directory, # The directory of the config's immediate lower fidelity - **config, # The hyperparameters to be used in the pipeline -) -> dict | float: - result_dict = run_pipeline( - pipeline_directory=pipeline_directory, # NOTE: can only support <=10 HPs and no categoricals - previous_pipeline_directory=previous_pipeline_directory, - **config, - ) - # NOTE: Normalize the loss to be between 0 and 1 - ## crucial for ifBO's FT-PFN surrogate to work as expected - result_dict["loss"] = np.clip(result_dict["loss"], 0, ASSUMED_MAX_LOSS) / ASSUMED_MAX_LOSS - return result_dict - - -if __name__ == "__main__": - import neps - - neps.run( - run_pipeline=run_pipeline, - pipeline_space=pipeline_space(), - root_directory="results", - max_evaluations_total=50, - searcher="ifbo", - ) -# end of ifbo_run_pipeline \ No newline at end of file diff --git a/neps_examples/template/lightning_template.py b/neps_examples/template/lightning_template.py deleted file mode 100644 index d284b692..00000000 --- a/neps_examples/template/lightning_template.py +++ /dev/null @@ -1,175 +0,0 @@ -""" Boilerplate code to optimize a simple PyTorch Lightning model. - -NOTE!!! This code is not meant to be executed. -It is only to serve as a template to help interface NePS with an existing ML/DL pipeline. - - -The following script describes the crucial components that a user needs to provide -in order to interface with Lightning. - -The 3 crucial components are: -* The search space, called the `pipeline_space` in NePS - * This defines the set of hyperparameters that the optimizer will search over - * This declaration also allows injecting priors in the form of defaults per hyperparameter -* The `lightning module` - * This defines the training, validation, and testing of the model - * This distributes the hyperparameters - * This can be used to create the Dataloaders for training, validation, and testing -* The `run_pipeline` function - * This function is called by the optimizer and is responsible for running the pipeline - * The function should at the minimum expect the hyperparameters as keyword arguments - * The function should return the loss of the pipeline as a float - * If the return value is a dictionary, it should have a key called "loss" with the loss as a float - -Overall, running an optimizer from NePS with Lightning involves 5 clear steps: -1. Importing neccessary packages including NePS and Lightning. -2. Designing the search space as a dictionary. -3. Creating the LightningModule with the required parameters -4. Creating the run_pipeline and returning the loss and other wanted metrics. -5. Using neps run with the optimizer of choice. - -For a more detailed guide, please refer to: -https://github.com/automl/neps/blob/master/neps_examples/convenience/neps_x_lightning.py -""" -import logging - -import lightning as L -import torch -from lightning.pytorch.callbacks import ModelCheckpoint -from lightning.pytorch.loggers import TensorBoardLogger - -import neps -from neps.utils.common import get_initial_directory, load_lightning_checkpoint - -logger = logging.getLogger("neps_template.run") - - -def pipeline_space() -> dict: - # Create the search space based on NEPS parameters and return the dictionary. - # IMPORTANT: - space = dict( - lr=neps.Float( - lower=1e-5, - upper=1e-2, - log=True, # If True, the search space is sampled in log space - default=1e-3, # a non-None value here acts as the mode of the prior distribution - ), - optimizer=neps.Categorical(choices=["Adam", "SGD"], default="Adam"), - epochs=neps.Integer( - lower=1, - upper=9, - is_fidelity=True, # IMPORTANT to set this to True for the fidelity parameter - ), - ) - return space - - -class LitModel(L.LightningModule): - def __init__(self, configuration: dict): - super().__init__() - - self.save_hyperparameters(configuration) - - # You can now define your criterion, data transforms, model layers, and - # metrics obtained during training - - def forward(self, x: torch.Tensor) -> torch.Tensor: - # Forward pass function - pass - - def training_step(self, batch: torch.Tensor, batch_idx: int) -> torch.Tensor: - # Training step function - # Training metric of choice - pass - - def validation_step(self, batch: torch.Tensor, batch_idx: int) -> torch.Tensor: - # Validation step function - # Validation metric of choice - pass - - def test_step(self, batch: torch.Tensor, batch_idx: int) -> torch.Tensor: - # Test step function - # Test metric of choice - pass - - def configure_optimizers(self) -> torch.optim.Optimizer: - # Define the optimizer base on the configuration - if self.hparams.optimizer == "Adam": - optimizer = torch.optim.Adam(self.parameters(), lr=self.hparams.lr) - elif self.hparams.optimizer == "SGD": - optimizer = torch.optim.SGD(self.parameters(), lr=self.hparams.lr) - else: - raise ValueError(f"{self.hparams.optimizer} is not a valid optimizer") - return optimizer - - # Here one can now configure the dataloaders for the model - # Further details can be found here: - # https://lightning.ai/docs/pytorch/stable/data/datamodule.html - # https://github.com/automl/neps/blob/master/neps_examples/convenience/neps_x_lightning.py - - -def run_pipeline( - pipeline_directory, # The directory where the config is saved - previous_pipeline_directory, # The directory of the config's immediate lower fidelity - **config, # The hyperparameters to be used in the pipeline -) -> dict | float: - # Start by getting the initial directory which will be used to store tensorboard - # event files and checkpoint files - init_dir = get_initial_directory(pipeline_directory) - checkpoint_dir = init_dir / "checkpoints" - tensorboard_dir = init_dir / "tensorboard" - - # Create the model - model = LitModel(config) - - # Create the TensorBoard logger and the checkpoint callback - logger = TensorBoardLogger( - save_dir=tensorboard_dir, name="data", version="logs", default_hp_metric=False - ) - checkpoint_callback = ModelCheckpoint(dirpath=checkpoint_dir) - - # Checking for any checkpoint files and checkpoint data, returns None if - # no checkpoint files exist. - checkpoint_path, checkpoint_data = load_lightning_checkpoint( - previous_pipeline_directory=previous_pipeline_directory, - checkpoint_dir=checkpoint_dir, - ) - - # Create a PyTorch Lightning Trainer - epochs = config["epochs"] - - trainer = L.Trainer( - logger=logger, - max_epochs=epochs, - callbacks=[checkpoint_callback], - ) - - # Train, test, and get their corresponding metrics - if checkpoint_path: - trainer.fit(model, ckpt_path=checkpoint_path) - else: - trainer.fit(model) - val_loss = trainer.logged_metrics.get("val_loss", None) - - trainer.test(model) - test_loss = trainer.logged_metrics.get("test_loss", None) - - # Return a dictionary with the results, or a single float value (loss) - return { - "loss": val_loss, - "info_dict": { - "test_loss": test_loss, - }, - } - - -# end of run_pipeline - -if __name__ == "__main__": - neps.run( - run_pipeline=run_pipeline, # User TODO (defined above) - pipeline_space=pipeline_space(), # User TODO (defined above) - root_directory="results", - max_evaluations_total=25, # total number of times `run_pipeline` is called - searcher="priorband", # "priorband_bo" for longer budgets, and set `initial_design_size`` - ) diff --git a/neps_examples/template/priorband_template.py b/neps_examples/template/priorband_template.py deleted file mode 100644 index 38154ef8..00000000 --- a/neps_examples/template/priorband_template.py +++ /dev/null @@ -1,152 +0,0 @@ -"""Boilerplate code to optimize a simple PyTorch model using PriorBand. - -NOTE!!! This code is not meant to be executed. -It is only to serve as a template to help interface NePS with an existing ML/DL pipeline. - - -The following script is designed as a template for using `PriorBand` from NePS. -It describes the crucial components that a user needs to provide in order to interface PriorBand. - -The 2 crucial components are: -* The search space, called the `pipeline_space` in NePS - * This defines the set of hyperparameters that the optimizer will search over - * This declaration also allows injecting priors in the form of defaults per hyperparameter -* The `run_pipeline` function - * This function is called by the optimizer and is responsible for running the pipeline - * The function should at the minimum expect the hyperparameters as keyword arguments - * The function should return the loss of the pipeline as a float - * If the return value is a dictionary, it should have a key called "loss" with the loss as a float - - -Overall, running an optimizer from NePS involves 4 clear steps: -1. Importing neccessary packages including neps. -2. Designing the search space as a dictionary. -3. Creating the run_pipeline and returning the loss and other wanted metrics. -4. Using neps run with the optimizer of choice. -""" - -import logging - -import torch -import torch.nn as nn -import torch.nn.functional as F - -import neps -from neps.utils.common import load_checkpoint, save_checkpoint - -logger = logging.getLogger("neps_template.run") - - -def pipeline_space() -> dict: - # Create the search space based on NEPS parameters and return the dictionary. - # IMPORTANT: - space = dict( - lr=neps.Float( - lower=1e-5, - upper=1e-2, - log=True, # If True, the search space is sampled in log space - default=1e-3, # a non-None value here acts as the mode of the prior distribution - ), - wd=neps.Float( - lower=1e-5, - upper=1e-1, - log=True, - default=1e-3, - ), - epoch=neps.Integer( - lower=1, - upper=10, - is_fidelity=True, # IMPORTANT to set this to True for the fidelity parameter - ), - ) - return space - - -def run_pipeline( - pipeline_directory, # The directory where the config is saved - previous_pipeline_directory, # The directory of the config's immediate lower fidelity - **config, # The hyperparameters to be used in the pipeline -) -> dict | float: - # Defining the model - # Can define outside the function or import from a file, package, etc. - class my_model(nn.Module): - def __init__(self) -> None: - super().__init__() - self.linear1 = nn.Linear(in_features=224, out_features=512) - self.linear2 = nn.Linear(in_features=512, out_features=10) - - def forward(self, x): - x = F.relu(self.linear1(x)) - x = self.linear2(x) - return x - - # Instantiates the model - model = my_model() - - # IMPORTANT: Extracting hyperparameters from passed config - learning_rate = config["lr"] - weight_decay = config["wd"] - - # Initializing the optimizer - optimizer = torch.optim.Adam( - model.parameters(), lr=learning_rate, weight_decay=weight_decay - ) - - ## Checkpointing - # loading the checkpoint if it exists - previous_state = load_checkpoint( # predefined function from neps - directory=previous_pipeline_directory, - model=model, # relies on pass-by-reference - optimizer=optimizer, # relies on pass-by-reference - ) - # adjusting run budget based on checkpoint - if previous_state is not None: - epoch_already_trained = previous_state["epochs"] - # + Anything else saved in the checkpoint. - else: - epoch_already_trained = 0 - # + Anything else with default value. - - # Extracting target epochs from config - max_epochs = config["epoch"] - - # User TODO: - # Load relevant data for training and validation - - # Actual model training - for epoch in range(epoch_already_trained, max_epochs): - # Training loop - ... - # Validation loop - ... - logger.info(f"Epoch: {epoch}, Loss: {...}, Val. acc.: {...}") - - # Save the checkpoint data in the current directory - save_checkpoint( - directory=pipeline_directory, - values_to_save={"epochs": max_epochs}, - model=model, - optimizer=optimizer, - ) - - # Return a dictionary with the results, or a single float value (loss) - return { - "loss": ..., - "info_dict": { - "train_accuracy": ..., - "test_accuracy": ..., - }, - } - - -# end of run_pipeline - - -if __name__ == "__main__": - neps.run( - run_pipeline=run_pipeline, # User TODO (defined above) - pipeline_space=pipeline_space(), # User TODO (defined above) - root_directory="results", - max_evaluations_total=25, # total number of times `run_pipeline` is called - searcher="priorband", # "priorband_bo" for longer budgets, and set `initial_design_size`` - ) From ebe5ff5a7045b6674e8bb8a676794b763a891ed7 Mon Sep 17 00:00:00 2001 From: "Timur M. Carstensen" <40788422+timurcarstensen@users.noreply.github.com> Date: Mon, 25 Nov 2024 13:37:12 +0100 Subject: [PATCH 09/24] chore: add python 3.12 support (#158) --- .github/workflows/tests.yaml | 2 +- .gitignore | 3 ++- pyproject.toml | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 0ec1b3ed..a06ffb74 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.10', '3.11'] + python-version: ['3.10', '3.11', '3.12'] os: [ubuntu-latest, macos-latest, windows-latest] defaults: run: diff --git a/.gitignore b/.gitignore index 81642d3e..7dc3a90b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ -#False Python +# False Python __pycache__ dist +**/*.egg-info # Log files *.out diff --git a/pyproject.toml b/pyproject.toml index 8dbaa5fc..d4184347 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ classifiers = [ "Operating System :: MacOS", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: System :: Distributed Computing", ] @@ -44,7 +45,7 @@ packages = [{ include = "neps" }, { include = "neps_examples" }] [tool.poetry.dependencies] -python = ">=3.10,<3.12" +python = ">=3.10,<3.13" ConfigSpace = "^0.7" grakel = "^0.1" numpy = "^1" @@ -61,7 +62,7 @@ pyyaml = "^6" tensorboard = "^2" typing-extensions = "*" torchvision = ">=0.8.0" -ifbo = ">=0.3.10" +ifbo = ">=0.3.11" botorch = ">=0.12" gpytorch = "1.13.0" From a5137c77c145c5b251f19d0f8c64ef5d075d872a Mon Sep 17 00:00:00 2001 From: "Timur M. Carstensen" <40788422+timurcarstensen@users.noreply.github.com> Date: Mon, 25 Nov 2024 13:48:17 +0100 Subject: [PATCH 10/24] ci: enforcing conventional commit naming in PR titles (#160) --- .github/workflows/pr-conventional-commit.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/pr-conventional-commit.yml diff --git a/.github/workflows/pr-conventional-commit.yml b/.github/workflows/pr-conventional-commit.yml new file mode 100644 index 00000000..86f79c0c --- /dev/null +++ b/.github/workflows/pr-conventional-commit.yml @@ -0,0 +1,15 @@ +name: PR Conventional Commit Validation + +on: + pull_request: + types: [opened, synchronize, reopened, edited] + +jobs: + validate-pr-title: + runs-on: ubuntu-latest + steps: + - name: PR Conventional Commit Validation + uses: ytanikin/PRConventionalCommits@1.2.0 + with: + task_types: '["feat","fix","docs","test","ci","refactor","perf","chore","revert"]' + add_label: 'false' \ No newline at end of file From 5e40590ec283d0082f425231057638cbafb2df73 Mon Sep 17 00:00:00 2001 From: "Timur M. Carstensen" <40788422+timurcarstensen@users.noreply.github.com> Date: Mon, 25 Nov 2024 22:12:26 +0100 Subject: [PATCH 11/24] ci: switch from poetry to uv (#152) --- .github/workflows/pre-commit.yaml | 16 ++-- .github/workflows/tests.yaml | 18 ++-- .gitignore | 3 - CONTRIBUTING.md | 138 +++++++++++++++------------- pyproject.toml | 143 ++++++++++++++++++------------ 5 files changed, 185 insertions(+), 133 deletions(-) diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index a7bd4690..33b2e805 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -25,9 +25,15 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - name: install the latest version uv + uses: astral-sh/setup-uv@v3 with: - python-version: '3.10' - - run: pip install pre-commit - - run: pre-commit install - - run: pre-commit run --all-files + version: latest + - name: create virtual environment + run: uv venv --python '3.10' + - name: install pre-commit + run: uv pip install pre-commit + - name: install pre-commit hooks + run: uv run pre-commit install + - name: Run pre-commit hooks + run: uv run pre-commit run --all-files diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index a06ffb74..a7b88cb2 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -25,12 +25,14 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - run: pipx install poetry - - uses: actions/setup-python@v5 + - name: install the latest version uv + uses: astral-sh/setup-uv@v3 with: - python-version: ${{ matrix.python-version }} - cache: 'poetry' - cache-dependency-path: '**/pyproject.toml' - - run: poetry install - - run: poetry run pytest -m "" # Run all markers - + version: latest + - name: create venv + run: uv venv --python ${{ matrix.python-version }} + - name: install dependencies + run: uv pip install -e ".[dev]" + - name: run tests + run: uv run pytest -m "" # Run all markers + diff --git a/.gitignore b/.gitignore index 7dc3a90b..505da327 100644 --- a/.gitignore +++ b/.gitignore @@ -20,9 +20,6 @@ site/* .vscode/ .idea/ -# Poetry -poetry.lock - # Misc *.sh *.model diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1f804aaf..8c3d08ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,62 +16,44 @@ Automatic checks are run on every pull request and on every commit to `master`. There are three required steps and one optional: -1. Optional: Install miniconda and create an environment -1. Install poetry -1. Install the neps package using poetry +1. Install uv +1. Install the neps package using uv 1. Activate pre-commit for the repository For instructions see below. -### 1. Optional: Install miniconda and create a virtual environment +## 1. Install uv -To manage python versions install e.g., miniconda with +First, install uv, e.g., via ```bash -wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O install_miniconda.sh -bash install_miniconda.sh -b -p $HOME/.conda # Change to place of preference -rm install_miniconda.sh +# On macOS and Linux. +curl -LsSf https://astral.sh/uv/install.sh | sh ``` -Consider running `~/.conda/bin/conda init` or `~/.conda/bin/conda init zsh` . - -Then finally create the environment and activate it - -```bash -conda create -n neps python=3.10 -conda activate neps -``` - -### 2. Install poetry - -First, install poetry, e.g., via - ```bash -curl -sSL https://install.python-poetry.org | python3 - -# or directly into your virtual env using `pip install poetry` +# On Windows. +powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" ``` -Then consider appending +## 2. Clone the neps repository ```bash -export PATH="$HOME/.local/bin:$PATH" +git clone https://github.com/automl/neps.git +cd neps ``` -to your `.zshrc` / `.bashrc` or alternatively simply running the export manually. - -### 3. Install the neps Package Using poetry - -Clone the repository, e.g., +## 3. Create a virtual environment and install the neps package ```bash -git clone https://github.com/automl/neps.git -cd neps +uv venv --python 3.11 +source .venv/bin/activate ``` Then, inside the main directory of neps run ```bash -poetry install +uv pip install -e ".[dev]" ``` This will installthe neps package but also additional dev dependencies. @@ -107,7 +89,7 @@ The tests correspond directly to examples in [neps_examples](https://github.com/ For linting we use `ruff` for checking code quality. You can install it locally and use it as so: ```bash -pip install ruff +uv pip install ruff ruff check --fix neps # the --fix flag will try to fix issues it can automatically ``` @@ -130,7 +112,7 @@ There you can find the documentation for all of the rules employed. For type checking we use `mypy`. You can install it locally and use it as so: ```bash -pip install mypy +uv pip install mypy mypy neps ``` @@ -169,6 +151,54 @@ pytest If tests fail for you on the master, please raise an issue on github, preferably with some information on the error, traceback and the environment in which you are running, i.e. python version, OS, etc. +## Regression Tests + +Regression tests are run on each push to the repository to assure the performance of the optimizers don't degrade. + +Currently, regression runs are recorded on JAHS-Bench-201 data for 2 tasks: `cifar10` and `fashion_mnist` and only for optimizers: `random_search`, `bayesian_optimization`, `mf_bayesian_optimization`. +This information is stored in the `tests/regression_runner.py` as two lists: `TASKS`, `OPTIMIZERS`. +The recorded results are stored as a json dictionary in the `tests/losses.json` file. + +### Adding new optimizer algorithms + +Once a new algorithm is added to NEPS library, we need to first record the performance of the algorithm for 100 optimization runs. + +- If the algorithm expects standard loss function (pipeline) and accepts fidelity hyperparameters in pipeline space, then recording results only requires adding the optimizer name into `OPTIMIZERS` list in `tests/regression_runner.py` and running `tests/regression_runner.py` + +- In case your algorithm requires custom pipeline and/or pipeline space you can modify the `runner.run_pipeline` and `runner.pipeline_space` attributes of the `RegressionRunner` after initialization (around line `#322` in `tests/regression_runner.py`) + +You can verify the optimizer is recorded by rerunning the `regression_runner.py`. +Now regression test will be run on your new optimizer as well on every push. + +### Regression test metrics + +For each regression test the algorithm is run 10 times to sample its performance, then they are statistically compared to the 100 recorded runs. We use these 3 boolean metrics to define the performance of the algorithm on any task: + +1. [Kolmogorov-Smirnov test for goodness of fit](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.kstest.html) - `pvalue` >= 10% +1. Absolute median distance - bounded within 92.5% confidence range of the expected median distance +1. Median improvement - Median improvement over the recorded median + +Test metrics are run for each `(optimizer, task)` combination separately and then collected. +The collected metrics are then further combined into 2 metrics + +1. Task pass - either both `Kolmogorov-Smirnov test` and `Absolute median distance` test passes or just `Median improvement` +1. Test aggregate - Sum_over_tasks(`Kolmogorov-Smirnov test` + `Absolute median distance` + 2 * `Median improvement`) + +Finally, a test for an optimizer only passes when at least for one of the tasks `Task pass` is true, and `Test aggregate` is higher than 1 + `number of tasks` + +### On regression test failures + +Regression tests are stochastic by nature, so they might fail occasionally even the algorithm performance didn't degrade. +In the case of regression test failure, try running it again first, if the problem still persists, then you can contact [Danny Stoll](mailto:stolld@cs.uni-freiburg.de) or [Samir](mailto:garibovs@cs.uni-freiburg.de). +You can also run tests locally by running: + +``` +uv run pytest -m regression_all +``` + +## Disabling and Skipping Checks etc. + + ### Pre-commit: How to not run hooks? To commit without running `pre-commit` use `git commit --no-verify -m `. @@ -185,27 +215,26 @@ There are two options: ### Managing Dependencies -To manage dependencies and for package distribution we use [poetry](https://python-poetry.org/docs/) (replaces pip). +To manage dependencies we use [uv](https://docs.astral.sh/uv/getting-started/) (replaces pip). #### Add dependencies To install a dependency use ```bash -poetry add dependency +uv add dependency ``` and commit the updated `pyproject.toml` to git. -For more advanced dependency management see examples in `pyproject.toml` or have a look at the [poetry documentation](https://python-poetry.org/). +For more advanced dependency management see examples in `pyproject.toml` or have a look at the [uv documentation](https://docs.astral.sh/uv/getting-started/). #### Install dependencies added by others When other contributors added dependencies to `pyproject.toml`, you can install them via ```bash -poetry lock -poetry install +uv pip install -e ".[dev]" ``` ## Documentation @@ -244,38 +273,26 @@ There are four steps to releasing a new version of neps: We follow the [semantic versioning](https://semver.org) scheme. -### 1. Update the Package Version and CITATION.cff +## 1. Run tests ```bash -poetry version v0.9.0 +uv run pytest ``` -and manually change the version specified in `CITATION.cff` and `docs/citations.md` - -### 2. Commit with a Version Tag - -First commit and test +## 2. Update the Package Version and CITATION.cff ```bash -git add pyproject.toml -git commit -m "Bump version from v0.8.4 to v0.9.0" -pytest +bump-my-version bump ``` -Then tag and push - -```bash -git tag v0.9.0 -git push --tags -git push -``` +This will automatically update the version in `pyproject.toml` and `CITATION.cff`, tag the commit and push it to the remote repository. ### 3. Update Documentation First check if the documentation has any issues via ```bash -mike deploy 0.9.0 latest -u +mike deploy latest -u mike serve ``` @@ -284,7 +301,7 @@ and then looking at it. Afterwards, publish it via ```bash -mike deploy 0.9.0 latest -up +mike deploy latest -up ``` ### 4. Publish on PyPI @@ -296,7 +313,8 @@ To publish to PyPI: 3. Run ```bash -poetry publish --build +uv build +uv publish ``` This will ask for your PyPI credentials. diff --git a/pyproject.toml b/pyproject.toml index d4184347..b0556963 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,25 +1,24 @@ -[tool.poetry] +[project] name = "neural-pipeline-search" version = "v0.12.2" description = "Neural Pipeline Search helps deep learning experts find the best neural pipeline." authors = [ - "Danny Stoll ", - "Neeratyoy Mallik ", - "Simon Schrodi", - "Eddie Bergman", - "Maciej Janowski", - "Samir Garibov", - "Tarek Abou Chakra", - "Daniel Rogalla", - "Carl Hvarfner", - "Binxin Ru", - "Frank Hutter", + { name = "Danny Stoll", email = "stolld@cs.uni-freiburg.de" }, + { name = "Neeratyoy Mallik", email = "mallik@cs.uni-freiburg.de" }, + { name = "Simon Schrodi" }, + { name = "Eddie Bergman" }, + { name = "Maciej Janowski" }, + { name = "Samir Garibov" }, + { name = "Tarek Abou Chakra" }, + { name = "Daniel Rogalla" }, + { name = "Carl Hvarfner" }, + { name = "Binxin Ru" }, + { name = "Nils Kober" }, + { name = "Théophane Vallaeys" }, + { name = "Frank Hutter" }, ] readme = "README.md" -license = "Apache-2.0" -homepage = "https://github.com/automl/neps" -repository = "https://github.com/automl/neps" -documentation = "https://automl.github.io/neps/" +license = { file = "LICENSE" } keywords = [ "Neural Pipeline Search", "Neural Architecture Search", @@ -29,7 +28,7 @@ keywords = [ classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", - "Intended Audience :: Science/Research", + "Intended Audience :: Science/Research", "Natural Language :: English", "License :: OSI Approved :: Apache Software License", "Operating System :: POSIX :: Linux", @@ -41,49 +40,67 @@ classifiers = [ "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: System :: Distributed Computing", ] -packages = [{ include = "neps" }, { include = "neps_examples" }] +requires-python = ">=3.10,<3.13" +dependencies = [ + "ConfigSpace>=0.7,<1.0", + "grakel>=0.1,<0.2", + "numpy>=1.0,<2.0", + "pandas>=2.0,<3.0", + "networkx>=2.6.3,<3.0", + "nltk>=3.6.4,<4.0", + "scipy>=1.13.1", + "torch>=2.0.1", + "matplotlib>=3.0,<4.0", + "more-itertools", + "portalocker>=2.0,<3.0", + "seaborn>=0.13,<0.14", + "pyyaml>=6.0,<7.0", + "tensorboard>=2.0,<3.0", + "typing-extensions", + "torchvision>=0.8.0", + "ifbo>=0.3.10", + "botorch>=0.12", + "gpytorch==1.13.0", +] -[tool.poetry.dependencies] -python = ">=3.10,<3.13" -ConfigSpace = "^0.7" -grakel = "^0.1" -numpy = "^1" -pandas = "^2" -networkx = "^2.6.3" -nltk = "^3.6.4" -scipy = ">=1.13.1" -torch = ">=2.0.1" -matplotlib = "^3" -more-itertools = "*" -portalocker = "^2" -seaborn = "^0.13" -pyyaml = "^6" -tensorboard = "^2" -typing-extensions = "*" -torchvision = ">=0.8.0" -ifbo = ">=0.3.11" -botorch = ">=0.12" -gpytorch = "1.13.0" +[project.urls] +homepage = "https://github.com/automl/neps" +repository = "https://github.com/automl/neps" +documentation = "https://automl.github.io/neps/" -[tool.poetry.group.dev.dependencies] -ruff = "*" -pre-commit = "^3" -mypy = "^1" -pytest = "^7" -pytest-cases = "^3" -types-PyYAML = "^6" -mkdocs-material = "*" -mkdocs-autorefs = "*" -mkdocs-gen-files = "*" -mkdocstrings = { extras = ["python"], version = "*" } -mkdocs-literate-nav = "*" -mike = "*" -black = "*" # This allows mkdocstrings to format signatures in the docs +[project.optional-dependencies] +dev = [ + "ruff", + "pre-commit>=3,<4", + "mypy>=1,<2", + "pytest>=7,<8", + "pytest-cases>=3,<4", + "types-PyYAML>=6,<7", + "mkdocs-material", + "mkdocs-autorefs", + "mkdocs-gen-files", + "mkdocstrings[python]", + "mkdocs-literate-nav", + "mike", + "black", # This allows mkdocstrings to format signatures in the docs +] + +[tool.setuptools.packages.find] +include = [ + "neps", + "neps.*", + "neps_examples", +] +exclude = [] [build-system] -requires = ["poetry-core>=1.1.0"] -build-backend = "poetry.core.masonry.api" +requires = [ + "setuptools>=68.2.2", + "wheel>=0.41.2", +] + +build-backend = "setuptools.build_meta" # TODO(eddiebergman): Include more of these as we go on in migration # "tests", @@ -319,5 +336,17 @@ module = [ ] ignore_errors = true -[tool.poetry.scripts] -neps = "neps.utils.cli:main" +[tool.bumpversion] +current_version = "0.12.2" +commit = true +tag = true + +[[tool.bumpversion.files]] +filename = "pyproject.toml" +search = "version = \"v{current_version}\"" +replace = "version = \"v{new_version}\"" + +[[tool.bumpversion.files]] +filename = "CITATION.cff" +search = "version: {current_version}" +replace = "version: {new_version}" From 04306d0d667f47bfe41fafe597932bb6c116f2bc Mon Sep 17 00:00:00 2001 From: Meganton Date: Tue, 5 Nov 2024 19:52:31 +0100 Subject: [PATCH 12/24] renaming run_pipeline to evaluate_pipeline no changes in regression_objectives, run_args (and other arg-related occurences) and tests --- neps/api.py | 14 +- neps/optimizers/base_optimizer.py | 8 +- neps/plot/__main__.py | 4 +- neps/plot/plot.py | 2 +- neps/runtime.py | 12 +- neps/utils/cli.py | 24 +- neps/utils/run_args.py | 24 +- neps_examples/basic_usage/hyperparameters.py | 10 +- .../convenience/logging_additional_info.py | 8 +- .../convenience/neps_tblogger_tutorial.py | 10 +- neps_examples/convenience/neps_x_lightning.py | 736 +++++++++--------- .../convenience/running_on_slurm_scripts.py | 10 +- .../working_directory_per_pipeline.py | 7 +- .../expert_priors_for_hyperparameters.py | 8 +- neps_examples/efficiency/multi_fidelity.py | 7 +- .../multi_fidelity_and_expert_priors.py | 7 +- ...rs_for_architecture_and_hyperparameters.py | 7 +- neps_examples/experimental/freeze_thaw.py | 2 +- tests/regression_objectives.py | 17 + tests/regression_runner.py | 2 +- .../testing_scripts/baseoptimizer_neps.py | 13 +- .../testing_scripts/default_neps.py | 15 +- .../testing_scripts/user_yaml_neps.py | 4 +- tests/test_settings/test_settings.py | 24 +- .../test_declarative_usage_docs/neps_run.py | 9 +- .../run_pipeline.py | 11 + .../test_run_args_by_neps_run/neps_run.py | 6 + .../test_yaml_run_args/test_yaml_run_args.py | 12 +- 28 files changed, 565 insertions(+), 448 deletions(-) diff --git a/neps/api.py b/neps/api.py index a140a7f6..d3991f7b 100644 --- a/neps/api.py +++ b/neps/api.py @@ -26,7 +26,7 @@ def run( - run_pipeline: Callable | None = Default(None), + evaluate_pipeline: Callable | None = Default(None), root_directory: str | Path | None = Default(None), pipeline_space: ( dict[str, Parameter] | str | Path | CS.ConfigurationSpace | None @@ -68,14 +68,14 @@ def run( the multiple calls to run(.) will be independent. Args: - run_pipeline: The objective function to minimize. + evaluate_pipeline: The objective function to minimize. pipeline_space: The search space to minimize over. root_directory: The directory to save progress to. This is also used to synchronize multiple calls to run(.) for parallelization. run_args: An option for providing the optimization settings e.g. max_evaluations_total in a YAML file. overwrite_working_directory: If true, delete the working directory at the start of - the run. This is, e.g., useful when debugging a run_pipeline function. + the run. This is, e.g., useful when debugging a evaluate_pipeline function. post_run_summary: If True, creates a csv file after each worker is done, holding summary information about the configs and results. development_stage_id: ID for the current development stage. Only needed if @@ -89,7 +89,7 @@ def run( max_evaluations_total have been completed. This is only relevant in the parallel setting. max_cost_total: No new evaluations will start when this cost is exceeded. Requires - returning a cost in the run_pipeline function, e.g., + returning a cost in the evaluate_pipeline function, e.g., `return dict(loss=loss, cost=cost)`. ignore_errors: Ignore hyperparameter settings that threw an error and do not raise an error. Error configs still count towards max_evaluations_total. @@ -111,7 +111,7 @@ def run( Example: >>> import neps - >>> def run_pipeline(some_parameter: float): + >>> def evaluate_pipeline(some_parameter: float): >>> validation_error = -some_parameter >>> return validation_error @@ -119,7 +119,7 @@ def run( >>> logging.basicConfig(level=logging.INFO) >>> neps.run( - >>> run_pipeline=run_pipeline, + >>> evaluate_pipeline=evaluate_pipeline, >>> pipeline_space=pipeline_space, >>> root_directory="usage_example", >>> max_evaluations_total=5, @@ -223,7 +223,7 @@ def run( ) _launch_runtime( - evaluation_fn=settings.run_pipeline, + evaluation_fn=settings.evaluate_pipeline, optimizer=searcher_instance, optimizer_info=searcher_info, max_cost_total=settings.max_cost_total, diff --git a/neps/optimizers/base_optimizer.py b/neps/optimizers/base_optimizer.py index 898508c7..45d64167 100644 --- a/neps/optimizers/base_optimizer.py +++ b/neps/optimizers/base_optimizer.py @@ -28,7 +28,7 @@ def _get_loss( return loss_value_on_error raise ValueError( - "An error happened during the execution of your run_pipeline function." + "An error happened during the execution of your evaluate_pipeline function." " You have three options: 1. If the error is expected and corresponds to" " a loss value in your application (e.g., 0% accuracy), you can set" " loss_value_on_error to some float. 2. If sometimes your pipeline" @@ -54,9 +54,9 @@ def _get_cost( if cost_value_on_error is None: raise ValueError( - "An error happened during the execution of your run_pipeline function." - " You have three options: 1. If the error is expected and corresponds to" - " a cost value in your application, you can set" + "An error happened during the execution of your evaluate_pipeline" + " function. You have three options: 1. If the error is expected and" + " corresponds to a cost value in your application, you can set" " cost_value_on_error to some float. 2. If sometimes your pipeline" " crashes randomly, you can set ignore_errors=True. 3. Fix your error." ) diff --git a/neps/plot/__main__.py b/neps/plot/__main__.py index 04aaffd2..e94e6559 100644 --- a/neps/plot/__main__.py +++ b/neps/plot/__main__.py @@ -12,7 +12,7 @@ Optional arguments: -h, --help Show this help message and exit --scientific_mode If true, plot from a tree-structured root_directory: benchmark={}/algorithm={}/seed={} - --key_to_extract The metric to be used on the x-axis (if active, make sure run_pipeline returns the metric in the info_dict) + --key_to_extract The metric to be used on the x-axis (if active, make sure evaluate_pipeline returns the metric in the info_dict) --benchmarks List of benchmarks to plot --algorithms List of algorithms to plot --consider_continuations If true, toggle calculation of continuation costs @@ -57,7 +57,7 @@ parser.add_argument( "--key_to_extract", help="The metric to be used on the x-axis (if " - "active, make sure run_pipeline returns " + "active, make sure evaluate_pipeline returns " "the metric in the info_dict)") parser.add_argument( "--benchmarks", diff --git a/neps/plot/plot.py b/neps/plot/plot.py index 020242a4..c36f1842 100644 --- a/neps/plot/plot.py +++ b/neps/plot/plot.py @@ -36,7 +36,7 @@ def plot( # noqa: C901, PLR0913 scientific_mode: If true, plot from a tree-structured root_directory: benchmark={}/algorithm={}/seed={} key_to_extract: The metric to be used on the x-axis - (if active, make sure run_pipeline returns the metric in the info_dict) + (if active, make sure evaluate_pipeline returns the metric in the info_dict) benchmarks: List of benchmarks to plot algorithms: List of algorithms to plot consider_continuations: If true, toggle calculation of continuation costs diff --git a/neps/runtime.py b/neps/runtime.py index 71b72f87..edb6c661 100644 --- a/neps/runtime.py +++ b/neps/runtime.py @@ -65,9 +65,9 @@ def get_workers_neps_state() -> NePSState[Path]: if _WORKER_NEPS_STATE is None: raise RuntimeError( "The worker's NePS state has not been set! This should only be called" - " from within a `run_pipeline` context. If you are not running a pipeline" - " and you did not call this function (`get_workers_neps_state`) yourself," - " this is a bug and should be reported to NePS." + " from within a `evaluate_pipeline` context. If you are not running a" + " pipeline and you did not call this function (`get_workers_neps_state`)" + " yourself, this is a bug and should be reported to NePS." ) return _WORKER_NEPS_STATE @@ -82,9 +82,9 @@ def get_in_progress_trial() -> Trial: if _CURRENTLY_RUNNING_TRIAL_IN_PROCESS is None: raise RuntimeError( "The worker's NePS state has not been set! This should only be called" - " from within a `run_pipeline` context. If you are not running a pipeline" - " and you did not call this function (`get_workers_neps_state`) yourself," - " this is a bug and should be reported to NePS." + " from within a `evaluate_pipeline` context. If you are not running a" + " pipeline and you did not call this function (`get_workers_neps_state`)" + " yourself, this is a bug and should be reported to NePS." ) return _CURRENTLY_RUNNING_TRIAL_IN_PROCESS diff --git a/neps/utils/cli.py b/neps/utils/cli.py index 1ad92d4a..41300f70 100644 --- a/neps/utils/cli.py +++ b/neps/utils/cli.py @@ -20,7 +20,7 @@ import pandas as pd from neps.utils.run_args import ( RUN_ARGS, - RUN_PIPELINE, + EVALUATE_PIPELINE, ROOT_DIRECTORY, POST_RUN_SUMMARY, MAX_EVALUATIONS_PER_RUN, @@ -172,8 +172,8 @@ def init_config(args: argparse.Namespace) -> None: file.write( """# Add your NEPS configuration settings here -run_pipeline: - path: "path/to/your/run_pipeline.py" +evaluate_pipeline: + path: "path/to/your/evaluate_pipeline.py" name: name_of_your_pipeline_function pipeline_space: @@ -199,8 +199,8 @@ def init_config(args: argparse.Namespace) -> None: file.write( """# Full Configuration Template for NePS -run_pipeline: - path: path/to/your/run_pipeline.py # Path to the function file +evaluate_pipeline: + path: path/to/your/evaluate_pipeline.py # Path to the function file name: example_pipeline # Function name within the file pipeline_space: @@ -288,10 +288,12 @@ def run_optimization(args: argparse.Namespace) -> None: run_args = args.run_args if not isinstance(args.run_pipeline, Default): module_path, function_name = args.run_pipeline.split(":") - run_pipeline = load_and_return_object(module_path, function_name, RUN_PIPELINE) + evaluate_pipeline = load_and_return_object( + module_path, function_name, EVALUATE_PIPELINE + ) else: - run_pipeline = args.run_pipeline + evaluate_pipeline = args.run_pipeline kwargs = {} if args.searcher_kwargs: @@ -300,7 +302,7 @@ def run_optimization(args: argparse.Namespace) -> None: # Collect arguments from args and prepare them for neps.run options = { RUN_ARGS: run_args, - RUN_PIPELINE: run_pipeline, + EVALUATE_PIPELINE: evaluate_pipeline, PIPELINE_SPACE: args.pipeline_space, ROOT_DIRECTORY: args.root_directory, OVERWRITE_WORKING_DIRECTORY: args.overwrite_working_directory, @@ -1185,7 +1187,7 @@ def main() -> None: type=str, help="Optional: Provide the path to a Python file and a function name separated " "by a colon, e.g., 'path/to/module.py:function_name'. " - "If provided, it overrides the run_pipeline setting from the YAML " + "If provided, it overrides the evaluate_pipeline setting from the YAML " "configuration.", default=Default(None), ) @@ -1210,7 +1212,7 @@ def main() -> None: action="store_true", default=Default(False), # noqa: FBT003 help="If set, deletes the working directory at the start of the run. " - "This is useful, for example, when debugging a run_pipeline function. " + "This is useful, for example, when debugging a evaluate_pipeline function. " "(default: %(default)s)", ) parser_run.add_argument( @@ -1266,7 +1268,7 @@ def main() -> None: type=float, default=Default(None), help="No new evaluations will start when this cost is exceeded. Requires " - "returning a cost in the run_pipeline function, e.g., `return dict(" + "returning a cost in the evaluate_pipeline function, e.g., `return dict(" "loss=loss, cost=cost)`. (default: %(default)s)", ) parser_run.add_argument( diff --git a/neps/utils/run_args.py b/neps/utils/run_args.py index 9f5cc60d..6520a40e 100644 --- a/neps/utils/run_args.py +++ b/neps/utils/run_args.py @@ -20,7 +20,7 @@ # Define the name of the arguments as variables for easier code maintenance RUN_ARGS = "run_args" -RUN_PIPELINE = "run_pipeline" +EVALUATE_PIPELINE = "run_pipeline" PIPELINE_SPACE = "pipeline_space" ROOT_DIRECTORY = "root_directory" MAX_EVALUATIONS_TOTAL = "max_evaluations_total" @@ -159,7 +159,7 @@ def extract_leaf_keys(d: dict, special_keys: dict | None = None) -> tuple[dict, """ if special_keys is None: special_keys = { - RUN_PIPELINE: None, + EVALUATE_PIPELINE: None, PRE_LOAD_HOOKS: None, SEARCHER: None, PIPELINE_SPACE: None, @@ -194,7 +194,7 @@ def handle_special_argument_cases(settings: dict, special_configs: dict) -> None """ # process special configs - process_run_pipeline(RUN_PIPELINE, special_configs, settings) + process_evaluate_pipeline(EVALUATE_PIPELINE, special_configs, settings) process_pipeline_space(PIPELINE_SPACE, special_configs, settings) process_searcher(SEARCHER, special_configs, settings) @@ -284,7 +284,7 @@ def process_searcher(key: str, special_configs: dict, settings: dict) -> None: settings[key] = searcher -def process_run_pipeline(key: str, special_configs: dict, settings: dict) -> None: +def process_evaluate_pipeline(key: str, special_configs: dict, settings: dict) -> None: """Processes the run pipeline configuration and updates the settings dictionary. Args: @@ -405,7 +405,7 @@ def check_run_args(settings: dict) -> None: # [task_id, development_stage_id, pre_load_hooks] require special handling of type, # that's why they are not listed expected_types = { - RUN_PIPELINE: Callable, + EVALUATE_PIPELINE: Callable, ROOT_DIRECTORY: str, # TODO: Support CS.ConfigurationSpace for pipeline_space PIPELINE_SPACE: (str, dict), @@ -447,7 +447,7 @@ def check_run_args(settings: dict) -> None: def check_essential_arguments( - run_pipeline: Callable | None, + evaluate_pipeline: Callable | None, root_directory: str | None, pipeline_space: dict | None, max_cost_total: int | None, @@ -456,13 +456,13 @@ def check_essential_arguments( ) -> None: """Validates essential NePS configuration arguments. - Ensures 'run_pipeline', 'root_directory', 'pipeline_space', and either + Ensures 'evaluate_pipeline', 'root_directory', 'pipeline_space', and either 'max_cost_total' or 'max_evaluations_total' are provided for NePS execution. Raises ValueError with missing argument details. Additionally, checks 'searcher' is a BaseOptimizer if 'pipeline_space' is absent. Args: - run_pipeline: Function for the pipeline execution. + evaluate_pipeline: Function for the pipeline execution. root_directory (str): Directory path for data storage. pipeline_space: search space for this run. max_cost_total: Max allowed total cost for experiments. @@ -472,8 +472,8 @@ def check_essential_arguments( Raises: ValueError: Missing or invalid essential arguments. """ - if not run_pipeline: - raise ValueError("'run_pipeline' is required but was not provided.") + if not evaluate_pipeline: + raise ValueError("'evaluate_pipeline' is required but was not provided.") if not root_directory: raise ValueError("'root_directory' is required but was not provided.") if not pipeline_space and not isinstance(searcher, BaseOptimizer): @@ -515,7 +515,7 @@ def __init__(self, func_args: dict, yaml_args: Path | str | Default | None = Non func_args (dict): The function arguments directly passed to NePS. yaml_args (dict | None): Optional. YAML file arguments provided via run_args. """ - self.run_pipeline = UNSET + self.evaluate_pipeline = UNSET self.root_directory = UNSET self.pipeline_space = UNSET self.overwrite_working_directory = UNSET @@ -598,7 +598,7 @@ def check(self) -> None: f"{', '.join(unassigned_attributes)}" ) check_essential_arguments( - self.run_pipeline, # type: ignore + self.evaluate_pipeline, # type: ignore self.root_directory, # type: ignore self.pipeline_space, # type: ignore self.max_cost_total, # type: ignore diff --git a/neps_examples/basic_usage/hyperparameters.py b/neps_examples/basic_usage/hyperparameters.py index 914286d6..04590fa1 100644 --- a/neps_examples/basic_usage/hyperparameters.py +++ b/neps_examples/basic_usage/hyperparameters.py @@ -1,12 +1,16 @@ import logging +import time +from warnings import warn import numpy as np import neps +def evaluate_pipeline(float1, float2, categorical, integer1, integer2): + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(float1, float2, categorical, integer1, integer2) -def run_pipeline(float1, float2, categorical, integer1, integer2): - # In this example we maximize an arbitrary sum for demonstration purposes +def evaluate_pipeline(float1, float2, categorical, integer1, integer2): loss = -float(np.sum([float1, float2, int(categorical), integer1, integer2])) return loss @@ -21,7 +25,7 @@ def run_pipeline(float1, float2, categorical, integer1, integer2): logging.basicConfig(level=logging.INFO) neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space, root_directory="results/hyperparameters_example", post_run_summary=True, diff --git a/neps_examples/convenience/logging_additional_info.py b/neps_examples/convenience/logging_additional_info.py index 34470d9f..0b2d4c81 100644 --- a/neps_examples/convenience/logging_additional_info.py +++ b/neps_examples/convenience/logging_additional_info.py @@ -1,12 +1,16 @@ import logging import time +from warnings import warn import numpy as np import neps - def run_pipeline(float1, float2, categorical, integer1, integer2): + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(float1, float2, categorical, integer1, integer2) + +def evaluate_pipeline(float1, float2, categorical, integer1, integer2): start = time.time() loss = -float(np.sum([float1, float2, int(categorical), integer1, integer2])) end = time.time() @@ -28,7 +32,7 @@ def run_pipeline(float1, float2, categorical, integer1, integer2): logging.basicConfig(level=logging.INFO) neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space, root_directory="results/logging_additional_info", max_evaluations_total=5, diff --git a/neps_examples/convenience/neps_tblogger_tutorial.py b/neps_examples/convenience/neps_tblogger_tutorial.py index 1a363e60..6044112c 100644 --- a/neps_examples/convenience/neps_tblogger_tutorial.py +++ b/neps_examples/convenience/neps_tblogger_tutorial.py @@ -51,6 +51,7 @@ import random import time from typing import Tuple +from warnings import warn import numpy as np import torch @@ -243,8 +244,13 @@ def pipeline_space() -> dict: ############################################################# # Implement the pipeline run search. - def run_pipeline(lr, optim, weight_decay): + # Deprecated function, use evaluate_pipeline instead + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(lr, optim, weight_decay) + + +def evaluate_pipeline(lr, optim, weight_decay): # Create the network model. model = MLP() @@ -351,7 +357,7 @@ def run_pipeline(lr, optim, weight_decay): # tblogger.get_status() run_args = dict( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space(), root_directory="results/neps_tblogger_example", searcher="random_search", diff --git a/neps_examples/convenience/neps_x_lightning.py b/neps_examples/convenience/neps_x_lightning.py index a8c873c0..f7949dfa 100644 --- a/neps_examples/convenience/neps_x_lightning.py +++ b/neps_examples/convenience/neps_x_lightning.py @@ -1,363 +1,373 @@ -""" -Exploring NePS Compatibility with PyTorch Lightning -======================================================= - -1. Introduction: ----------------- -Welcome to this tutorial on utilizing NePS-generated files and directories -in conjunction with PyTorch Lightning. - -2. Setup: ---------- -Ensure you have the necessary dependencies installed. You can install the 'NePS' -package by executing the following command: - -```bash -pip install neural-pipeline-search -``` - -Additionally, note that 'NePS' does not include 'torchvision' as a dependency. -You can install it with this command: - -```bash -pip install torchvision==0.14 -``` - -Make sure to download the torchvision version that is compatible with your -pytorch version. More info on this link: - -https://pypi.org/project/torchvision/ - -Additionally, you will need to install the PyTorch Lightning package. This can -be achieved with the following command: - -```bash -pip install lightning -``` - -These dependencies ensure you have everything you need for this tutorial. -""" -import argparse -import glob -import logging -import random -import time -from pathlib import Path -from typing import Tuple - -import lightning as L -import numpy as np -import torch -import torch.nn as nn -import torch.nn.functional as F -from lightning.pytorch.callbacks import ModelCheckpoint -from lightning.pytorch.loggers import TensorBoardLogger -from torch.utils.data import SubsetRandomSampler -from torch.utils.data.dataloader import DataLoader -from torchmetrics import Accuracy -from torchvision.datasets import MNIST -from torchvision.transforms import transforms - -import neps -from neps.utils.common import get_initial_directory, load_lightning_checkpoint - -############################################################# -# Definig the seeds for reproducibility - - -def set_seed(seed=123): - torch.manual_seed(seed) - np.random.seed(seed) - random.seed(seed) - - -############################################################# -# Define the lightning model - - -class LitMNIST(L.LightningModule): - def __init__( - self, - configuration: dict, - n_train: int = 8192, - n_valid: int = 1024, - ): - super().__init__() - - # Initialize the model's hyperparameters with the configuration - self.save_hyperparameters(configuration) - - self.n_train = n_train - self.n_valid = n_valid - - # Define data transformation and loss function - self.transform = transforms.ToTensor() - self.criterion = nn.NLLLoss() - - # Define the model's architecture - self.linear1 = nn.Linear(in_features=784, out_features=392) - self.linear2 = nn.Linear(in_features=392, out_features=196) - self.linear3 = nn.Linear(in_features=196, out_features=10) - - # Define PyTorch Lightning metrics for training, validation, and testing - metric = Accuracy(task="multiclass", num_classes=10) - self.train_accuracy = metric.clone() - self.val_accuracy = metric.clone() - self.test_accuracy = metric.clone() - - def forward(self, x: torch.Tensor) -> torch.Tensor: - # Forward pass function - x = x.view(x.size(0), -1) - x = F.relu(self.linear1(x)) - x = F.relu(self.linear2(x)) - x = self.linear3(x) - - return F.log_softmax(x, dim=1) - - def common_step( - self, batch: Tuple[torch.Tensor, torch.Tensor], batch_idx: int - ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: - """ - Perform a forward pass and compute loss, predictions, and get the ground - truth labels for a batch of data. - """ - x, y = batch - logits = self.forward(x) - loss = self.criterion(logits, y) - preds = torch.argmax(logits, dim=1) - - return loss, preds, y - - def training_step( - self, batch: Tuple[torch.Tensor, torch.Tensor], batch_idx: int - ) -> float: - loss, preds, y = self.common_step(batch, batch_idx) - self.train_accuracy.update(preds, y) - - self.log_dict( - {"train_loss": loss, "train_acc": self.val_accuracy.compute()}, - on_epoch=True, - on_step=False, - prog_bar=True, - ) - - return loss - - def validation_step( - self, batch: Tuple[torch.Tensor, torch.Tensor], batch_idx: int - ) -> None: - loss, preds, y = self.common_step(batch, batch_idx) - self.val_accuracy.update(preds, y) - - self.log_dict( - {"val_loss": loss, "val_acc": self.val_accuracy.compute()}, - on_epoch=True, - on_step=False, - prog_bar=True, - ) - - def test_step( - self, batch: Tuple[torch.Tensor, torch.Tensor], batch_idx: int - ) -> None: - _, preds, y = self.common_step(batch, batch_idx) - self.test_accuracy.update(preds, y) - - self.log(name="test_acc", value=self.test_accuracy.compute()) - - def configure_optimizers(self) -> torch.optim.Optimizer: - # Configure and return the optimizer based on the configuration - if self.hparams.optimizer == "Adam": - optimizer = torch.optim.Adam( - self.parameters(), - lr=self.hparams.lr, - weight_decay=self.hparams.weight_decay, - ) - elif self.hparams.optimizer == "SGD": - optimizer = torch.optim.SGD( - self.parameters(), - lr=self.hparams.lr, - weight_decay=self.hparams.weight_decay, - ) - else: - raise ValueError( - "The optimizer choices is not one of the available optimizers" - ) - return optimizer - - def on_train_end(self): - # Get the metric at the end of the training and log it with respect to - # it's hyperparameters - val_acc_metric = { - "val_accuracy": self.val_accuracy.compute(), - } - - # Log hyperparameters - self.logger.log_hyperparams(self.hparams, metrics=val_acc_metric) - - def prepare_data(self) -> None: - # Downloading the dataste if not already downloaded - MNIST(self.hparams.data_dir, train=True, download=True) - MNIST(self.hparams.data_dir, train=False, download=True) - - def setup(self, stage: str = None) -> None: - # Assign train/val datasets for use in dataloaders - if stage == "fit" or stage is None: - self.mnist_full = MNIST( - self.hparams.data_dir, train=True, transform=self.transform - ) - - # Create random subsets of the training dataset for validation. - self.train_sampler = SubsetRandomSampler(range(self.n_train)) - self.val_sampler = SubsetRandomSampler( - range(self.n_train, self.n_train + self.n_valid) - ) - - # Assign test dataset for use in dataloader - if stage == "test" or stage is None: - self.mnist_test = MNIST( - self.hparams.data_dir, train=False, transform=self.transform - ) - - def train_dataloader(self) -> DataLoader: - return DataLoader( - self.mnist_full, - batch_size=self.hparams.batch_size, - sampler=self.train_sampler, - num_workers=16, - ) - - def val_dataloader(self) -> DataLoader: - return DataLoader( - self.mnist_full, - batch_size=self.hparams.batch_size, - sampler=self.val_sampler, - num_workers=16, - ) - - def test_dataloader(self) -> DataLoader: - return DataLoader( - self.mnist_test, - batch_size=self.hparams.batch_size, - num_workers=16, - ) - - -############################################################# -# Define search space - - -def search_space() -> dict: - # Define a dictionary to represent the hyperparameter search space - space = dict( - data_dir=neps.Constant("./data"), - batch_size=neps.Constant(64), - lr=neps.Float(lower=1e-5, upper=1e-2, log=True, default=1e-3), - weight_decay=neps.Float( - lower=1e-5, upper=1e-3, log=True, default=5e-4 - ), - optimizer=neps.Categorical(choices=["Adam", "SGD"], default="Adam"), - epochs=neps.Integer(lower=1, upper=9, log=False, is_fidelity=True), - ) - return space - - -############################################################# -# Define the run pipeline function - - -def run_pipeline(pipeline_directory, previous_pipeline_directory, **config) -> dict: - # Initialize the first directory to store the event and checkpoints files - init_dir = get_initial_directory(pipeline_directory) - checkpoint_dir = init_dir / "checkpoints" - - # Initialize the model and checkpoint dir - model = LitMNIST(config) - - # Create the TensorBoard logger for logging - logger = TensorBoardLogger( - save_dir=init_dir, name="data", version="logs", default_hp_metric=False - ) - - # Add checkpoints at the end of training - checkpoint_callback = ModelCheckpoint( - dirpath=checkpoint_dir, - filename="{epoch}-{val_loss:.2f}", - ) - - # Use this function to load the previous checkpoint if it exists - checkpoint_path, checkpoint = load_lightning_checkpoint( - previous_pipeline_directory=previous_pipeline_directory, - checkpoint_dir=checkpoint_dir, - ) - - if checkpoint is None: - previously_spent_epochs = 0 - else: - previously_spent_epochs = checkpoint["epoch"] - - # Create a PyTorch Lightning Trainer - epochs = config["epochs"] - - trainer = L.Trainer( - logger=logger, - max_epochs=epochs, - callbacks=[checkpoint_callback], - ) - - # Train the model and retrieve training/validation metrics - if checkpoint_path: - trainer.fit(model, ckpt_path=checkpoint_path) - else: - trainer.fit(model) - - train_accuracy = trainer.logged_metrics.get("train_acc", None) - val_loss = trainer.logged_metrics.get("val_loss", None) - val_accuracy = trainer.logged_metrics.get("val_acc", None) - - # Test the model and retrieve test metrics - trainer.test(model) - - test_accuracy = trainer.logged_metrics.get("test_acc", None) - - return { - "loss": val_loss, - "cost": epochs - previously_spent_epochs, - "info_dict": { - "train_accuracy": train_accuracy, - "val_accuracy": val_accuracy, - "test_accuracy": test_accuracy, - }, - } - - -if __name__ == "__main__": - # Parse command line arguments - parser = argparse.ArgumentParser() - parser.add_argument( - "--max_evaluations_total", - type=int, - default=15, - help="Number of different configurations to train", - ) - args = parser.parse_args() - - # Initialize the logger and record start time - start_time = time.time() - set_seed(112) - logging.basicConfig(level=logging.INFO) - - # Run NePS with specified parameters - neps.run( - run_pipeline=run_pipeline, - pipeline_space=search_space(), - root_directory="results/hyperband", - max_evaluations_total=args.max_evaluations_total, - searcher="hyperband", - ) - - # Record the end time and calculate execution time - end_time = time.time() - execution_time = end_time - start_time - - # Log the execution time - logging.info(f"Execution time: {execution_time} seconds") +""" +Exploring NePS Compatibility with PyTorch Lightning +======================================================= + +1. Introduction: +---------------- +Welcome to this tutorial on utilizing NePS-generated files and directories +in conjunction with PyTorch Lightning. + +2. Setup: +--------- +Ensure you have the necessary dependencies installed. You can install the 'NePS' +package by executing the following command: + +```bash +pip install neural-pipeline-search +``` + +Additionally, note that 'NePS' does not include 'torchvision' as a dependency. +You can install it with this command: + +```bash +pip install torchvision==0.14 +``` + +Make sure to download the torchvision version that is compatible with your +pytorch version. More info on this link: + +https://pypi.org/project/torchvision/ + +Additionally, you will need to install the PyTorch Lightning package. This can +be achieved with the following command: + +```bash +pip install lightning +``` + +These dependencies ensure you have everything you need for this tutorial. +""" +import argparse +import glob +import logging +import random +import time +from pathlib import Path +from typing import Tuple +from warnings import warn + +import lightning as L +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F +from lightning.pytorch.callbacks import ModelCheckpoint +from lightning.pytorch.loggers import TensorBoardLogger +from torch.utils.data import SubsetRandomSampler +from torch.utils.data.dataloader import DataLoader +from torchmetrics import Accuracy +from torchvision.datasets import MNIST +from torchvision.transforms import transforms + +import neps +from neps.utils.common import get_initial_directory, load_lightning_checkpoint + +############################################################# +# Definig the seeds for reproducibility + + +def set_seed(seed=123): + torch.manual_seed(seed) + np.random.seed(seed) + random.seed(seed) + + +############################################################# +# Define the lightning model + + +class LitMNIST(L.LightningModule): + def __init__( + self, + configuration: dict, + n_train: int = 8192, + n_valid: int = 1024, + ): + super().__init__() + + # Initialize the model's hyperparameters with the configuration + self.save_hyperparameters(configuration) + + self.n_train = n_train + self.n_valid = n_valid + + # Define data transformation and loss function + self.transform = transforms.ToTensor() + self.criterion = nn.NLLLoss() + + # Define the model's architecture + self.linear1 = nn.Linear(in_features=784, out_features=392) + self.linear2 = nn.Linear(in_features=392, out_features=196) + self.linear3 = nn.Linear(in_features=196, out_features=10) + + # Define PyTorch Lightning metrics for training, validation, and testing + metric = Accuracy(task="multiclass", num_classes=10) + self.train_accuracy = metric.clone() + self.val_accuracy = metric.clone() + self.test_accuracy = metric.clone() + + def forward(self, x: torch.Tensor) -> torch.Tensor: + # Forward pass function + x = x.view(x.size(0), -1) + x = F.relu(self.linear1(x)) + x = F.relu(self.linear2(x)) + x = self.linear3(x) + + return F.log_softmax(x, dim=1) + + def common_step( + self, batch: Tuple[torch.Tensor, torch.Tensor], batch_idx: int + ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: + """ + Perform a forward pass and compute loss, predictions, and get the ground + truth labels for a batch of data. + """ + x, y = batch + logits = self.forward(x) + loss = self.criterion(logits, y) + preds = torch.argmax(logits, dim=1) + + return loss, preds, y + + def training_step( + self, batch: Tuple[torch.Tensor, torch.Tensor], batch_idx: int + ) -> float: + loss, preds, y = self.common_step(batch, batch_idx) + self.train_accuracy.update(preds, y) + + self.log_dict( + {"train_loss": loss, "train_acc": self.val_accuracy.compute()}, + on_epoch=True, + on_step=False, + prog_bar=True, + ) + + return loss + + def validation_step( + self, batch: Tuple[torch.Tensor, torch.Tensor], batch_idx: int + ) -> None: + loss, preds, y = self.common_step(batch, batch_idx) + self.val_accuracy.update(preds, y) + + self.log_dict( + {"val_loss": loss, "val_acc": self.val_accuracy.compute()}, + on_epoch=True, + on_step=False, + prog_bar=True, + ) + + def test_step( + self, batch: Tuple[torch.Tensor, torch.Tensor], batch_idx: int + ) -> None: + _, preds, y = self.common_step(batch, batch_idx) + self.test_accuracy.update(preds, y) + + self.log(name="test_acc", value=self.test_accuracy.compute()) + + def configure_optimizers(self) -> torch.optim.Optimizer: + # Configure and return the optimizer based on the configuration + if self.hparams.optimizer == "Adam": + optimizer = torch.optim.Adam( + self.parameters(), + lr=self.hparams.lr, + weight_decay=self.hparams.weight_decay, + ) + elif self.hparams.optimizer == "SGD": + optimizer = torch.optim.SGD( + self.parameters(), + lr=self.hparams.lr, + weight_decay=self.hparams.weight_decay, + ) + else: + raise ValueError( + "The optimizer choices is not one of the available optimizers" + ) + return optimizer + + def on_train_end(self): + # Get the metric at the end of the training and log it with respect to + # it's hyperparameters + val_acc_metric = { + "val_accuracy": self.val_accuracy.compute(), + } + + # Log hyperparameters + self.logger.log_hyperparams(self.hparams, metrics=val_acc_metric) + + def prepare_data(self) -> None: + # Downloading the dataste if not already downloaded + MNIST(self.hparams.data_dir, train=True, download=True) + MNIST(self.hparams.data_dir, train=False, download=True) + + def setup(self, stage: str = None) -> None: + # Assign train/val datasets for use in dataloaders + if stage == "fit" or stage is None: + self.mnist_full = MNIST( + self.hparams.data_dir, train=True, transform=self.transform + ) + + # Create random subsets of the training dataset for validation. + self.train_sampler = SubsetRandomSampler(range(self.n_train)) + self.val_sampler = SubsetRandomSampler( + range(self.n_train, self.n_train + self.n_valid) + ) + + # Assign test dataset for use in dataloader + if stage == "test" or stage is None: + self.mnist_test = MNIST( + self.hparams.data_dir, train=False, transform=self.transform + ) + + def train_dataloader(self) -> DataLoader: + return DataLoader( + self.mnist_full, + batch_size=self.hparams.batch_size, + sampler=self.train_sampler, + num_workers=16, + ) + + def val_dataloader(self) -> DataLoader: + return DataLoader( + self.mnist_full, + batch_size=self.hparams.batch_size, + sampler=self.val_sampler, + num_workers=16, + ) + + def test_dataloader(self) -> DataLoader: + return DataLoader( + self.mnist_test, + batch_size=self.hparams.batch_size, + num_workers=16, + ) + + +############################################################# +# Define search space + + +def search_space() -> dict: + # Define a dictionary to represent the hyperparameter search space + space = dict( + data_dir=neps.Constant("./data"), + batch_size=neps.Constant(64), + lr=neps.Float(lower=1e-5, upper=1e-2, log=True, default=1e-3), + weight_decay=neps.Float( + lower=1e-5, upper=1e-3, log=True, default=5e-4 + ), + optimizer=neps.Categorical(choices=["Adam", "SGD"], default="Adam"), + epochs=neps.Integer(lower=1, upper=9, log=False, is_fidelity=True), + ) + return space + + +############################################################# +# Define the run pipeline function + +def run_pipeline(pipeline_directory, previous_pipeline_directory, **config): + # Deprecated function, use evaluate_pipeline instead + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline( + pipeline_directory, + previous_pipeline_directory, + **config, + ) + + +def evaluate_pipeline(pipeline_directory, previous_pipeline_directory, **config) -> dict: + # Initialize the first directory to store the event and checkpoints files + init_dir = get_initial_directory(pipeline_directory) + checkpoint_dir = init_dir / "checkpoints" + + # Initialize the model and checkpoint dir + model = LitMNIST(config) + + # Create the TensorBoard logger for logging + logger = TensorBoardLogger( + save_dir=init_dir, name="data", version="logs", default_hp_metric=False + ) + + # Add checkpoints at the end of training + checkpoint_callback = ModelCheckpoint( + dirpath=checkpoint_dir, + filename="{epoch}-{val_loss:.2f}", + ) + + # Use this function to load the previous checkpoint if it exists + checkpoint_path, checkpoint = load_lightning_checkpoint( + previous_pipeline_directory=previous_pipeline_directory, + checkpoint_dir=checkpoint_dir, + ) + + if checkpoint is None: + previously_spent_epochs = 0 + else: + previously_spent_epochs = checkpoint["epoch"] + + # Create a PyTorch Lightning Trainer + epochs = config["epochs"] + + trainer = L.Trainer( + logger=logger, + max_epochs=epochs, + callbacks=[checkpoint_callback], + ) + + # Train the model and retrieve training/validation metrics + if checkpoint_path: + trainer.fit(model, ckpt_path=checkpoint_path) + else: + trainer.fit(model) + + train_accuracy = trainer.logged_metrics.get("train_acc", None) + val_loss = trainer.logged_metrics.get("val_loss", None) + val_accuracy = trainer.logged_metrics.get("val_acc", None) + + # Test the model and retrieve test metrics + trainer.test(model) + + test_accuracy = trainer.logged_metrics.get("test_acc", None) + + return { + "loss": val_loss, + "cost": epochs - previously_spent_epochs, + "info_dict": { + "train_accuracy": train_accuracy, + "val_accuracy": val_accuracy, + "test_accuracy": test_accuracy, + }, + } + + +if __name__ == "__main__": + # Parse command line arguments + parser = argparse.ArgumentParser() + parser.add_argument( + "--max_evaluations_total", + type=int, + default=15, + help="Number of different configurations to train", + ) + args = parser.parse_args() + + # Initialize the logger and record start time + start_time = time.time() + set_seed(112) + logging.basicConfig(level=logging.INFO) + + # Run NePS with specified parameters + neps.run( + evaluate_pipeline=evaluate_pipeline, + pipeline_space=search_space(), + root_directory="results/hyperband", + max_evaluations_total=args.max_evaluations_total, + searcher="hyperband", + ) + + # Record the end time and calculate execution time + end_time = time.time() + execution_time = end_time - start_time + + # Log the execution time + logging.info(f"Execution time: {execution_time} seconds") diff --git a/neps_examples/convenience/running_on_slurm_scripts.py b/neps_examples/convenience/running_on_slurm_scripts.py index 03a73c96..7a52c21b 100644 --- a/neps_examples/convenience/running_on_slurm_scripts.py +++ b/neps_examples/convenience/running_on_slurm_scripts.py @@ -5,6 +5,7 @@ import os import time from pathlib import Path +from warnings import warn import neps @@ -27,9 +28,14 @@ def _get_validation_error(pipeline_directory: Path): return float(validation_error_file.read_text()) return None - def run_pipeline_via_slurm( pipeline_directory: Path, optimizer: str, learning_rate: float +): + warn("run_pipeline_via_slurm is deprecated, use evaluate_pipeline_via_slurm instead", DeprecationWarning) + return evaluate_pipeline_via_slurm(pipeline_directory, optimizer, learning_rate) + +def evaluate_pipeline_via_slurm( + pipeline_directory: Path, optimizer: str, learning_rate: float ): script = f"""#!/bin/bash #SBATCH --time 0-00:05 @@ -58,7 +64,7 @@ def run_pipeline_via_slurm( logging.basicConfig(level=logging.INFO) neps.run( - run_pipeline=run_pipeline_via_slurm, + evaluate_pipeline=evaluate_pipeline_via_slurm, pipeline_space=pipeline_space, root_directory="results/slurm_script_example", max_evaluations_total=5, diff --git a/neps_examples/convenience/working_directory_per_pipeline.py b/neps_examples/convenience/working_directory_per_pipeline.py index 7aa26197..4cce4633 100644 --- a/neps_examples/convenience/working_directory_per_pipeline.py +++ b/neps_examples/convenience/working_directory_per_pipeline.py @@ -1,5 +1,6 @@ import logging from pathlib import Path +from warnings import warn import numpy as np @@ -7,6 +8,10 @@ def run_pipeline(pipeline_directory: Path, float1, categorical, integer1): + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(pipeline_directory, float1, categorical, integer1) + +def evaluate_pipeline(pipeline_directory: Path, float1, categorical, integer1): # When adding pipeline_directory to run_pipeline, neps detects its presence and # passes a directory unique for each pipeline configuration. You can then use this # pipeline_directory to create / save files pertaining to a specific pipeline, e.g.: @@ -25,7 +30,7 @@ def run_pipeline(pipeline_directory: Path, float1, categorical, integer1): logging.basicConfig(level=logging.INFO) neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space, root_directory="results/working_directory_per_pipeline", max_evaluations_total=5, diff --git a/neps_examples/efficiency/expert_priors_for_hyperparameters.py b/neps_examples/efficiency/expert_priors_for_hyperparameters.py index 46ed9325..352d94dc 100644 --- a/neps_examples/efficiency/expert_priors_for_hyperparameters.py +++ b/neps_examples/efficiency/expert_priors_for_hyperparameters.py @@ -1,10 +1,14 @@ import logging import time +from warnings import warn import neps - def run_pipeline(some_float, some_integer, some_cat): + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(some_float, some_integer, some_cat) + +def evaluate_pipeline(some_float, some_integer, some_cat): start = time.time() if some_cat != "a": y = some_float + some_integer @@ -36,7 +40,7 @@ def run_pipeline(some_float, some_integer, some_cat): logging.basicConfig(level=logging.INFO) neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space, root_directory="results/user_priors_example", max_evaluations_total=15, diff --git a/neps_examples/efficiency/multi_fidelity.py b/neps_examples/efficiency/multi_fidelity.py index 3e58eefa..b9848c3a 100644 --- a/neps_examples/efficiency/multi_fidelity.py +++ b/neps_examples/efficiency/multi_fidelity.py @@ -1,4 +1,5 @@ import logging +from warnings import warn import numpy as np import torch @@ -43,6 +44,10 @@ def get_model_and_optimizer(learning_rate): def run_pipeline(pipeline_directory, previous_pipeline_directory, learning_rate, epoch): + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(pipeline_directory, previous_pipeline_directory, learning_rate, epoch) + +def evaluate_pipeline(pipeline_directory, previous_pipeline_directory, learning_rate, epoch): model, optimizer = get_model_and_optimizer(learning_rate) checkpoint_name = "checkpoint.pth" @@ -79,7 +84,7 @@ def run_pipeline(pipeline_directory, previous_pipeline_directory, learning_rate, logging.basicConfig(level=logging.INFO) neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space, root_directory="results/multi_fidelity_example", # Optional: Do not start another evaluation after <=50 epochs, corresponds to cost diff --git a/neps_examples/efficiency/multi_fidelity_and_expert_priors.py b/neps_examples/efficiency/multi_fidelity_and_expert_priors.py index 1de28617..6ea2d8b8 100644 --- a/neps_examples/efficiency/multi_fidelity_and_expert_priors.py +++ b/neps_examples/efficiency/multi_fidelity_and_expert_priors.py @@ -1,4 +1,5 @@ import logging +from warnings import warn import numpy as np @@ -6,6 +7,10 @@ def run_pipeline(float1, float2, integer1, fidelity): + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(float1, float2, integer1, fidelity) + +def evaluate_pipeline(float1, float2, integer1, fidelity): loss = -float(np.sum([float1, float2, integer1])) / fidelity return loss @@ -25,7 +30,7 @@ def run_pipeline(float1, float2, integer1, fidelity): logging.basicConfig(level=logging.INFO) neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space, root_directory="results/multifidelity_priors", max_evaluations_total=25, # For an alternate stopping method see multi_fidelity.py diff --git a/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py b/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py index c0d1f5f6..dc4b7084 100644 --- a/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py +++ b/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py @@ -1,5 +1,6 @@ import logging import time +from warnings import warn from torch import nn @@ -70,6 +71,10 @@ def set_recursive_attribute(op_name, predecessor_values): def run_pipeline(some_architecture, some_float, some_integer, some_cat): + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(some_architecture, some_float, some_integer, some_cat) + +def evaluate_pipeline(some_architecture, some_float, some_integer, some_cat): start = time.time() in_channels = 3 @@ -126,7 +131,7 @@ def run_pipeline(some_architecture, some_float, some_integer, some_cat): logging.basicConfig(level=logging.INFO) neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space, root_directory="results/user_priors_with_graphs", max_evaluations_total=15, diff --git a/neps_examples/experimental/freeze_thaw.py b/neps_examples/experimental/freeze_thaw.py index 32943ec2..b4af7b40 100644 --- a/neps_examples/experimental/freeze_thaw.py +++ b/neps_examples/experimental/freeze_thaw.py @@ -157,7 +157,7 @@ def training_pipeline( neps.run( pipeline_space=pipeline_space, - run_pipeline=training_pipeline, + evaluate_pipeline=training_pipeline, searcher="ifbo", max_evaluations_total=50, root_directory="./debug/ifbo-mnist/", diff --git a/tests/regression_objectives.py b/tests/regression_objectives.py index e6bec6c5..90adb892 100644 --- a/tests/regression_objectives.py +++ b/tests/regression_objectives.py @@ -39,6 +39,7 @@ def pipeline_space(self, value): @property def run_pipeline(self) -> Callable: + warnings.warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) if self._run_pipeline is None: raise NotImplementedError( f"run_pipeline can not be None, " @@ -48,8 +49,24 @@ def run_pipeline(self) -> Callable: else: return self._run_pipeline + @property + def evaluate_pipeline(self) -> Callable: + if self._run_pipeline is None: + raise NotImplementedError( + f"evaluate_pipeline can not be None, " + f"the subclass {type(self)} must " + f"implement a evaluate_pipeline Callable" + ) + else: + return self._run_pipeline + @run_pipeline.setter def run_pipeline(self, value): + warnings.warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + self._run_pipeline = value + + @evaluate_pipeline.setter + def evaluate_pipeline(self, value): self._run_pipeline = value def __call__(self, *args, **kwargs) -> dict[str, Any]: diff --git a/tests/regression_runner.py b/tests/regression_runner.py index d102a1df..eead3639 100644 --- a/tests/regression_runner.py +++ b/tests/regression_runner.py @@ -131,7 +131,7 @@ def save_losses(self): def neps_run(self, working_directory: Path): neps.run( - run_pipeline=self.objective, + evaluate_pipeline=self.objective, pipeline_space=self.pipeline_space, searcher=self.optimizer, max_cost_total=self.budget, diff --git a/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py b/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py index 63ca6670..16e714f3 100644 --- a/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py +++ b/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py @@ -1,4 +1,5 @@ import logging +from warnings import warn import neps from neps.optimizers.bayesian_optimization.optimizer import BayesianOptimization @@ -17,11 +18,19 @@ def run_pipeline(val1, val2): + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(val1, val2) + +def evaluate_pipeline(val1, val2): loss = val1 * val2 return loss def run_pipeline_fidelity(val1, val2): + warn("run_pipeline_fidelity is deprecated, use evaluate_pipeline_fidelity instead", DeprecationWarning) + return evaluate_pipeline_fidelity(val1, val2) + +def evaluate_pipeline_fidelity(val1, val2): loss = val1 * val2 return {"loss": loss, "cost": 1} @@ -34,7 +43,7 @@ def run_pipeline_fidelity(val1, val2): pipeline_space=search_space, initial_design_size=5 ) neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, root_directory="bo_custom_created", max_evaluations_total=1, searcher=my_custom_searcher_1, @@ -44,7 +53,7 @@ def run_pipeline_fidelity(val1, val2): search_space_fidelity = SearchSpace(**pipeline_space_fidelity) my_custom_searcher_2 = Hyperband(pipeline_space=search_space_fidelity, budget=1) neps.run( - run_pipeline=run_pipeline_fidelity, + evaluate_pipeline=evaluate_pipeline_fidelity, root_directory="hyperband_custom_created", max_cost_total=1, searcher=my_custom_searcher_2, diff --git a/tests/test_neps_api/testing_scripts/default_neps.py b/tests/test_neps_api/testing_scripts/default_neps.py index 11b41dca..03adda4c 100644 --- a/tests/test_neps_api/testing_scripts/default_neps.py +++ b/tests/test_neps_api/testing_scripts/default_neps.py @@ -1,4 +1,5 @@ import logging +from warnings import warn import neps @@ -24,6 +25,10 @@ def run_pipeline(val1, val2): + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(val1, val2) + +def evaluate_pipeline(val1, val2): loss = val1 * val2 return loss @@ -36,7 +41,7 @@ def run_pipeline(val1, val2): # Case 1: Choosing priorband neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space_fidelity_priors, root_directory="priorband_bo_user_decided", max_evaluations_total=1, @@ -50,7 +55,7 @@ def run_pipeline(val1, val2): # Case 1: Choosing priorband neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space_fidelity_priors, root_directory="priorband_neps_decided", max_evaluations_total=1, @@ -60,7 +65,7 @@ def run_pipeline(val1, val2): # Case 2: Choosing bayesian_optimization neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space_not_fidelity, root_directory="bo_neps_decided", max_evaluations_total=1, @@ -68,7 +73,7 @@ def run_pipeline(val1, val2): # Case 3: Choosing pibo neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space_not_fidelity_priors, root_directory="pibo_neps_decided", max_evaluations_total=1, @@ -77,7 +82,7 @@ def run_pipeline(val1, val2): # Case 4: Choosing hyperband neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space_fidelity, root_directory="hyperband_neps_decided", max_evaluations_total=1, diff --git a/tests/test_neps_api/testing_scripts/user_yaml_neps.py b/tests/test_neps_api/testing_scripts/user_yaml_neps.py index d28cbbed..448e941a 100644 --- a/tests/test_neps_api/testing_scripts/user_yaml_neps.py +++ b/tests/test_neps_api/testing_scripts/user_yaml_neps.py @@ -1,6 +1,7 @@ import logging import os from pathlib import Path +from warnings import warn import neps pipeline_space = dict( @@ -10,6 +11,7 @@ def run_pipeline(val1, val2): + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) loss = val1 * val2 return loss @@ -21,7 +23,7 @@ def run_pipeline(val1, val2): parent_directory = os.path.join(script_directory, os.pardir) searcher_path = Path(parent_directory) / "testing_yaml" / "optimizer_test" neps.run( - run_pipeline=run_pipeline, + evaluate_pipeline=run_pipeline, pipeline_space=pipeline_space, root_directory="user_yaml_bo", max_evaluations_total=1, diff --git a/tests/test_settings/test_settings.py b/tests/test_settings/test_settings.py index 1244bcf6..83051a23 100644 --- a/tests/test_settings/test_settings.py +++ b/tests/test_settings/test_settings.py @@ -4,7 +4,7 @@ import pytest from pathlib import Path from tests.test_yaml_run_args.test_yaml_run_args import ( - run_pipeline, + evaluate_pipeline, hook1, hook2, pipeline_space, @@ -12,7 +12,7 @@ from neps.optimizers.bayesian_optimization.optimizer import BayesianOptimization BASE_PATH = Path("tests") / "test_settings" -run_pipeline = run_pipeline +evaluate_pipeline = evaluate_pipeline hook1 = hook1 hook2 = hook2 pipeline_space = pipeline_space @@ -25,7 +25,7 @@ [ ( { # only essential arguments provided by func_args, no yaml - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "run_args": Default(None), @@ -46,7 +46,7 @@ }, Default(None), { - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": False, @@ -88,7 +88,7 @@ }, "run_args_required.yaml", { - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": False, @@ -109,7 +109,7 @@ ), ( { # required via func_args, optional via yaml - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "run_args": "tests/path/to/run_args", # will be ignored by Settings @@ -130,7 +130,7 @@ }, "run_args_optional.yaml", { - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": True, @@ -151,7 +151,7 @@ ), ( { # overwrite all yaml values - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "run_args": "test", @@ -172,7 +172,7 @@ }, "overwrite_run_args.yaml", { - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": False, @@ -193,7 +193,7 @@ ), ( { # optimizer args special case - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "run_args": "test", @@ -220,7 +220,7 @@ }, "run_args_optimizer_settings.yaml", { - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": False, @@ -278,7 +278,7 @@ }, "run_args_optimizer_outside.yaml", { - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": True, diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py b/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py index c504c112..0306db94 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py @@ -1,10 +1,15 @@ import argparse +from warnings import warn import neps import numpy as np def run_pipeline_constant(learning_rate, optimizer, epochs, batch_size): - """func for test loading of run_pipeline""" + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline_constant(learning_rate, optimizer, epochs, batch_size) + +def evaluate_pipeline_constant(learning_rate, optimizer, epochs, batch_size): + """func for test loading of evaluate_pipeline""" if optimizer == "a": eval_score = np.random.choice([learning_rate, epochs], 1) else: @@ -22,6 +27,6 @@ def run_pipeline_constant(learning_rate, optimizer, epochs, batch_size): args = parser.parse_args() if args.run_pipeline: - neps.run(run_args=args.run_args, run_pipeline=run_pipeline_constant) + neps.run(run_args=args.run_args, evaluate_pipeline=run_pipeline_constant) else: neps.run(run_args=args.run_args) diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py b/tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py index f44e6e71..cd89b1ca 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py @@ -1,8 +1,14 @@ +from warnings import warn import numpy as np def run_pipeline(learning_rate, optimizer, epochs): """func for test loading of run_pipeline""" + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(learning_rate, optimizer, epochs) + +def evaluate_pipeline(learning_rate, optimizer, epochs): + """func for test loading of evaluate_pipeline""" if optimizer == "a": eval_score = np.random.choice([learning_rate, epochs], 1) else: @@ -12,6 +18,11 @@ def run_pipeline(learning_rate, optimizer, epochs): def run_pipeline_constant(learning_rate, optimizer, epochs, batch_size): """func for test loading of run_pipeline""" + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline_constant(learning_rate, optimizer, epochs, batch_size) + +def evaluate_pipeline_constant(learning_rate, optimizer, epochs, batch_size): + """func for test loading of evaluate_pipeline""" if optimizer == "a": eval_score = np.random.choice([learning_rate, epochs], 1) else: diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py b/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py index 404fea46..14778024 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py @@ -1,3 +1,4 @@ +from warnings import warn import argparse import numpy as np import neps @@ -5,6 +6,11 @@ def run_pipeline(learning_rate, epochs, optimizer, batch_size): """func for test loading of run_pipeline""" + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(learning_rate, epochs, optimizer, batch_size) + +def evaluate_pipeline(learning_rate, epochs, optimizer, batch_size): + """func for test loading of evaluate_pipeline""" if optimizer == "a": eval_score = np.random.choice([learning_rate, epochs], 1) else: diff --git a/tests/test_yaml_run_args/test_yaml_run_args.py b/tests/test_yaml_run_args/test_yaml_run_args.py index aebd2a37..31023554 100644 --- a/tests/test_yaml_run_args/test_yaml_run_args.py +++ b/tests/test_yaml_run_args/test_yaml_run_args.py @@ -1,3 +1,4 @@ +from warnings import warn import pytest import neps from neps.utils.run_args import get_run_args_from_yaml @@ -15,6 +16,11 @@ def run_pipeline(): """func to test loading of run_pipeline""" + warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline() + +def evaluate_pipeline(): + """func to test loading of evaluate_pipeline""" return @@ -99,7 +105,7 @@ def are_functions_equivalent( ( "run_args_full.yaml", { - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "pipeline_space": pipeline_space, "root_directory": "test_yaml", "max_evaluations_total": 20, @@ -123,7 +129,7 @@ def are_functions_equivalent( ( "run_args_full_same_level.yaml", { - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "pipeline_space": pipeline_space, "root_directory": "test_yaml", "max_evaluations_total": 20, @@ -175,7 +181,7 @@ def are_functions_equivalent( ( "run_args_optional_loading_format.yaml", { - "run_pipeline": run_pipeline, + "run_pipeline": evaluate_pipeline, "pipeline_space": pipeline_space, "root_directory": "test_yaml", "max_evaluations_total": 20, From ff3a7f9b783fe10b9f043d09bdcfc20c97b95c01 Mon Sep 17 00:00:00 2001 From: Meganton Date: Fri, 8 Nov 2024 17:12:05 +0100 Subject: [PATCH 13/24] renamed run_pipline args to evaluate pipeline --- neps/utils/cli.py | 6 +++--- neps/utils/run_args.py | 6 +++--- .../test_declarative_usage_docs/neps_run.py | 6 +++--- .../test_declarative_usage_docs.py | 2 +- tests/test_yaml_run_args/test_yaml_run_args.py | 8 ++++---- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/neps/utils/cli.py b/neps/utils/cli.py index 41300f70..99adc282 100644 --- a/neps/utils/cli.py +++ b/neps/utils/cli.py @@ -286,14 +286,14 @@ def run_optimization(args: argparse.Namespace) -> None: run_args = Path("run_config.yaml") else: run_args = args.run_args - if not isinstance(args.run_pipeline, Default): - module_path, function_name = args.run_pipeline.split(":") + if not isinstance(args.evaluate_pipeline, Default): + module_path, function_name = args.evaluate_pipeline.split(":") evaluate_pipeline = load_and_return_object( module_path, function_name, EVALUATE_PIPELINE ) else: - evaluate_pipeline = args.run_pipeline + evaluate_pipeline = args.evaluate_pipeline kwargs = {} if args.searcher_kwargs: diff --git a/neps/utils/run_args.py b/neps/utils/run_args.py index 6520a40e..99f83aec 100644 --- a/neps/utils/run_args.py +++ b/neps/utils/run_args.py @@ -49,7 +49,7 @@ def get_run_args_from_yaml(path: str | Path) -> dict: validates these arguments, and then returns them in a dictionary. It checks for the presence and validity of expected parameters, and distinctively handles more complex configurations, specifically those that are dictionaries(e.g. pipeline_space) or - objects(e.g. run_pipeline) requiring loading. + objects(e.g. evaluate_pipeline) requiring loading. Args: path (str): The file path to the YAML configuration file. @@ -67,7 +67,7 @@ def get_run_args_from_yaml(path: str | Path) -> dict: settings = {} # List allowed NePS run arguments with simple types (e.g., string, int). Parameters - # like 'run_pipeline', 'preload_hooks', 'pipeline_space', + # like 'evaluate_pipeline', 'preload_hooks', 'pipeline_space', # and 'searcher' are excluded due to needing specialized processing. expected_parameters = [ ROOT_DIRECTORY, @@ -146,7 +146,7 @@ def config_loader(path: str | Path) -> dict: def extract_leaf_keys(d: dict, special_keys: dict | None = None) -> tuple[dict, dict]: """Recursive function to extract leaf keys and their values from a nested dictionary. - Special keys (e.g.'run_pipeline') are also extracted if present + Special keys (e.g.'evaluate_pipeline') are also extracted if present and their corresponding values (dict) at any level in the nested structure. Args: diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py b/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py index 0306db94..77fa841e 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py @@ -23,10 +23,10 @@ def evaluate_pipeline_constant(learning_rate, optimizer, epochs, batch_size): description="Run NEPS optimization with run_args.yml." ) parser.add_argument("run_args", type=str, help="Path to the YAML configuration file.") - parser.add_argument("--run_pipeline", action="store_true") + parser.add_argument("--evaluate_pipeline", action="store_true") args = parser.parse_args() - if args.run_pipeline: - neps.run(run_args=args.run_args, evaluate_pipeline=run_pipeline_constant) + if args.evaluate_pipeline: + neps.run(run_args=args.run_args, evaluate_pipeline=evaluate_pipeline_constant) else: neps.run(run_args=args.run_args) diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/test_declarative_usage_docs.py b/tests/test_yaml_run_args/test_declarative_usage_docs/test_declarative_usage_docs.py index 3b49ae05..4a026689 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/test_declarative_usage_docs.py +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/test_declarative_usage_docs.py @@ -48,7 +48,7 @@ def test_run_with_yaml_and_run_pipeline() -> None: try: subprocess.check_call( - [sys.executable, BASE_PATH / "neps_run.py", yaml_path, "--run_pipeline"] + [sys.executable, BASE_PATH / "neps_run.py", yaml_path, "--evaluate_pipeline"] ) except subprocess.CalledProcessError as e: pytest.fail( diff --git a/tests/test_yaml_run_args/test_yaml_run_args.py b/tests/test_yaml_run_args/test_yaml_run_args.py index 31023554..bec40d1b 100644 --- a/tests/test_yaml_run_args/test_yaml_run_args.py +++ b/tests/test_yaml_run_args/test_yaml_run_args.py @@ -80,7 +80,7 @@ def are_functions_equivalent( # Compare keys with a function/list of functions as their values # Special because they include a module loading procedure by a path and the name of # the function - for special_key in ["run_pipeline", "pre_load_hooks"]: + for special_key in ["evaluate_pipeline", "pre_load_hooks"]: if special_key in expected_output: func_expected = expected_output.pop(special_key) func_output = output.pop(special_key) @@ -105,7 +105,7 @@ def are_functions_equivalent( ( "run_args_full.yaml", { - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "pipeline_space": pipeline_space, "root_directory": "test_yaml", "max_evaluations_total": 20, @@ -129,7 +129,7 @@ def are_functions_equivalent( ( "run_args_full_same_level.yaml", { - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "pipeline_space": pipeline_space, "root_directory": "test_yaml", "max_evaluations_total": 20, @@ -181,7 +181,7 @@ def are_functions_equivalent( ( "run_args_optional_loading_format.yaml", { - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "pipeline_space": pipeline_space, "root_directory": "test_yaml", "max_evaluations_total": 20, From e7da84f17eb01e45a0b08002e152fe8e08e4dbb4 Mon Sep 17 00:00:00 2001 From: Meganton Date: Mon, 30 Dec 2024 17:57:09 +0100 Subject: [PATCH 14/24] change run-arg from run_pipeline to evaluate_pipeline --- neps/utils/run_args.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/utils/run_args.py b/neps/utils/run_args.py index 99f83aec..572cd6ff 100644 --- a/neps/utils/run_args.py +++ b/neps/utils/run_args.py @@ -20,7 +20,7 @@ # Define the name of the arguments as variables for easier code maintenance RUN_ARGS = "run_args" -EVALUATE_PIPELINE = "run_pipeline" +EVALUATE_PIPELINE = "evaluate_pipeline" PIPELINE_SPACE = "pipeline_space" ROOT_DIRECTORY = "root_directory" MAX_EVALUATIONS_TOTAL = "max_evaluations_total" From a88bf047887163f71111dc2717bd6c7130a32c9e Mon Sep 17 00:00:00 2001 From: Meganton Date: Tue, 31 Dec 2024 01:48:23 +0100 Subject: [PATCH 15/24] renamed run_pipeline in test_settings --- tests/test_settings/test_settings.py | 24 +- uv.lock | 2088 ++++++++++++++++++++++++++ 2 files changed, 2100 insertions(+), 12 deletions(-) create mode 100644 uv.lock diff --git a/tests/test_settings/test_settings.py b/tests/test_settings/test_settings.py index 83051a23..cd9b5663 100644 --- a/tests/test_settings/test_settings.py +++ b/tests/test_settings/test_settings.py @@ -25,7 +25,7 @@ [ ( { # only essential arguments provided by func_args, no yaml - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "run_args": Default(None), @@ -46,7 +46,7 @@ }, Default(None), { - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": False, @@ -67,7 +67,7 @@ ), ( { # only required elements of run_args - "run_pipeline": Default(None), + "evaluate_pipeline": Default(None), "root_directory": Default(None), "pipeline_space": Default(None), "run_args": Default(None), @@ -88,7 +88,7 @@ }, "run_args_required.yaml", { - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": False, @@ -109,7 +109,7 @@ ), ( { # required via func_args, optional via yaml - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "run_args": "tests/path/to/run_args", # will be ignored by Settings @@ -130,7 +130,7 @@ }, "run_args_optional.yaml", { - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": True, @@ -151,7 +151,7 @@ ), ( { # overwrite all yaml values - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "run_args": "test", @@ -172,7 +172,7 @@ }, "overwrite_run_args.yaml", { - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": False, @@ -193,7 +193,7 @@ ), ( { # optimizer args special case - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "run_args": "test", @@ -220,7 +220,7 @@ }, "run_args_optimizer_settings.yaml", { - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": False, @@ -255,7 +255,7 @@ ), ( { # load optimizer with args - "run_pipeline": Default(None), + "evaluate_pipeline": Default(None), "root_directory": Default(None), "pipeline_space": Default(None), "run_args": Default(None), @@ -278,7 +278,7 @@ }, "run_args_optimizer_outside.yaml", { - "run_pipeline": evaluate_pipeline, + "evaluate_pipeline": evaluate_pipeline, "root_directory": "path/to/root_directory", "pipeline_space": pipeline_space, "overwrite_working_directory": True, diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..c4543f07 --- /dev/null +++ b/uv.lock @@ -0,0 +1,2088 @@ +version = 1 +requires-python = ">=3.10, <3.13" +resolution-markers = [ + "python_full_version < '3.11'", + "python_full_version == '3.11.*'", + "python_full_version >= '3.12'", +] + +[[package]] +name = "absl-py" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7a/8f/fc001b92ecc467cc32ab38398bd0bfb45df46e7523bf33c2ad22a505f06e/absl-py-2.1.0.tar.gz", hash = "sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff", size = 118055 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/ad/e0d3c824784ff121c03cc031f944bc7e139a8f1870ffd2845cc2dd76f6c4/absl_py-2.1.0-py3-none-any.whl", hash = "sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308", size = 133706 }, +] + +[[package]] +name = "babel" +version = "2.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, +] + +[[package]] +name = "black" +version = "24.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "mypy-extensions" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/0d/cc2fb42b8c50d80143221515dd7e4766995bd07c56c9a3ed30baf080b6dc/black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875", size = 645813 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/f3/465c0eb5cddf7dbbfe1fecd9b875d1dcf51b88923cd2c1d7e9ab95c6336b/black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812", size = 1623211 }, + { url = "https://files.pythonhosted.org/packages/df/57/b6d2da7d200773fdfcc224ffb87052cf283cec4d7102fab450b4a05996d8/black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea", size = 1457139 }, + { url = "https://files.pythonhosted.org/packages/6e/c5/9023b7673904a5188f9be81f5e129fff69f51f5515655fbd1d5a4e80a47b/black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f", size = 1753774 }, + { url = "https://files.pythonhosted.org/packages/e1/32/df7f18bd0e724e0d9748829765455d6643ec847b3f87e77456fc99d0edab/black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e", size = 1414209 }, + { url = "https://files.pythonhosted.org/packages/c2/cc/7496bb63a9b06a954d3d0ac9fe7a73f3bf1cd92d7a58877c27f4ad1e9d41/black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad", size = 1607468 }, + { url = "https://files.pythonhosted.org/packages/2b/e3/69a738fb5ba18b5422f50b4f143544c664d7da40f09c13969b2fd52900e0/black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50", size = 1437270 }, + { url = "https://files.pythonhosted.org/packages/c9/9b/2db8045b45844665c720dcfe292fdaf2e49825810c0103e1191515fc101a/black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392", size = 1737061 }, + { url = "https://files.pythonhosted.org/packages/a3/95/17d4a09a5be5f8c65aa4a361444d95edc45def0de887810f508d3f65db7a/black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175", size = 1423293 }, + { url = "https://files.pythonhosted.org/packages/90/04/bf74c71f592bcd761610bbf67e23e6a3cff824780761f536512437f1e655/black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3", size = 1644256 }, + { url = "https://files.pythonhosted.org/packages/4c/ea/a77bab4cf1887f4b2e0bce5516ea0b3ff7d04ba96af21d65024629afedb6/black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65", size = 1448534 }, + { url = "https://files.pythonhosted.org/packages/4e/3e/443ef8bc1fbda78e61f79157f303893f3fddf19ca3c8989b163eb3469a12/black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f", size = 1761892 }, + { url = "https://files.pythonhosted.org/packages/52/93/eac95ff229049a6901bc84fec6908a5124b8a0b7c26ea766b3b8a5debd22/black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8", size = 1434796 }, + { url = "https://files.pythonhosted.org/packages/8d/a7/4b27c50537ebca8bec139b872861f9d2bf501c5ec51fcf897cb924d9e264/black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d", size = 206898 }, +] + +[[package]] +name = "botorch" +version = "0.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gpytorch" }, + { name = "linear-operator" }, + { name = "mpmath" }, + { name = "multipledispatch" }, + { name = "pyro-ppl" }, + { name = "scipy" }, + { name = "torch" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cc/f7/49652f8470344605365a8d5a42f235571e1f3b1212e54981d10fa7479c10/botorch-0.12.0.tar.gz", hash = "sha256:6c810efa0a9cba4cca8ccd829ae8e9bee88ed4e08548c072a19b423c114bd211", size = 953000 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/a7/2d7f30b820fe61ccd0b239c3929920095a76cb2114db547af1df6c8284b4/botorch-0.12.0-py3-none-any.whl", hash = "sha256:7534566c1722d6997d4f6fd1ad0818f6a97d2975159b02ee94d410b34985347e", size = 644792 }, +] + +[[package]] +name = "certifi" +version = "2024.12.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, +] + +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", size = 198013 }, + { url = "https://files.pythonhosted.org/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", size = 141285 }, + { url = "https://files.pythonhosted.org/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", size = 151449 }, + { url = "https://files.pythonhosted.org/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", size = 143892 }, + { url = "https://files.pythonhosted.org/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", size = 146123 }, + { url = "https://files.pythonhosted.org/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", size = 147943 }, + { url = "https://files.pythonhosted.org/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", size = 142063 }, + { url = "https://files.pythonhosted.org/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", size = 150578 }, + { url = "https://files.pythonhosted.org/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", size = 153629 }, + { url = "https://files.pythonhosted.org/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", size = 150778 }, + { url = "https://files.pythonhosted.org/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", size = 146453 }, + { url = "https://files.pythonhosted.org/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", size = 95479 }, + { url = "https://files.pythonhosted.org/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", size = 102790 }, + { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995 }, + { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471 }, + { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831 }, + { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335 }, + { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862 }, + { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673 }, + { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211 }, + { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039 }, + { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939 }, + { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075 }, + { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340 }, + { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205 }, + { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441 }, + { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, + { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, + { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, + { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, + { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, + { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, + { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, + { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, + { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, + { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, + { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, + { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, + { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, +] + +[[package]] +name = "click" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "platform_system == 'Windows'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, +] + +[[package]] +name = "cloudpickle" +version = "3.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/97/c7/f746cadd08c4c08129215cf1b984b632f9e579fc781301e63da9e85c76c1/cloudpickle-3.1.0.tar.gz", hash = "sha256:81a929b6e3c7335c863c771d673d105f02efdb89dfaba0c90495d1c64796601b", size = 66155 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/41/e1d85ca3cab0b674e277c8c4f678cf66a91cd2cecf93df94353a606fe0db/cloudpickle-3.1.0-py3-none-any.whl", hash = "sha256:fe11acda67f61aaaec473e3afe030feb131d78a43461b718185363384f1ba12e", size = 22021 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "configspace" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "more-itertools" }, + { name = "numpy" }, + { name = "pyparsing" }, + { name = "scipy" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/e8/7834ed7b8f639f7c8d356dd598dccad6781d0315bdfa886eec2fcbe041dd/ConfigSpace-0.7.1.tar.gz", hash = "sha256:57b5b8e28ed6ee14ecf6206fdca43ca698ef63bc1531f081d482b26acf4edf1a", size = 1562121 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/f7/76e5c6b626edc03e145e25234c061a9d34cb94828c8742bf8162e5346aa5/ConfigSpace-0.7.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9a2fe6ac3304ed11cf2a10c16810310471a5eae27e8c83ca0669e748ab363165", size = 3152867 }, + { url = "https://files.pythonhosted.org/packages/d5/d6/e02eb41e3212d2daba89668dd62647d41bd39addca6435b671792fb0a1ba/ConfigSpace-0.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:44b09f9c4acde4322fb5c2df27b8159f3645b1b6f9c3b33da24fda7b3db0d033", size = 2339129 }, + { url = "https://files.pythonhosted.org/packages/06/60/3b888979f7aebcfa920fca9a62d3e1a22bb367059d1fc18072c4e172d0a8/ConfigSpace-0.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa995137a90d00c1cb9a24db74d7fdd0ad64c272183e230134c26c9f85ba3dc3", size = 6317912 }, + { url = "https://files.pythonhosted.org/packages/38/bd/7a87ec226f2456fff6d6e2052eda4106c6cba771104e2cf8b1df48fffcad/ConfigSpace-0.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92288850a751446b8b0a3afd992a88618181a8c16e682dc123be5e7cbed603af", size = 6342052 }, + { url = "https://files.pythonhosted.org/packages/aa/aa/fa3fd1c95568ea7454f04ab16ced6a40e9407e1a1bf225f8faa6cccd4e1a/ConfigSpace-0.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:316779b41b9a9cbbdd83b2e1737f3de7b60616c0892f6cc782b305d0ebcd947c", size = 2164601 }, + { url = "https://files.pythonhosted.org/packages/f8/97/e62d112b1889a328cc09cdf0ccd7e563a169e267f544e2d6536b721cdfe1/ConfigSpace-0.7.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f09d91b1dd525269ed9aefd5880cf71ab27eace95200f3ce3824b43a3148a8b7", size = 3098901 }, + { url = "https://files.pythonhosted.org/packages/6c/c7/b7f3e487515b701fc0af30296efae8a2210a8ca1b83b02ce8972d28df138/ConfigSpace-0.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f0b08da62afd544568f339b4c3cc0945121b6785550db52c9685d3a0e30f93ce", size = 2314313 }, + { url = "https://files.pythonhosted.org/packages/34/f7/8de4575fa8cebe65542eb8cdecb06ca4fdb4bf9c3832e6c3f0ac6554d0ee/ConfigSpace-0.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee1e2066545a29a2fe174c9675a357898db852b6ee68f70703c312c612fe07a3", size = 6707758 }, + { url = "https://files.pythonhosted.org/packages/f0/15/99e0b0cde47fb94a72e6a1f94d3709bdd8bc46bec3ad779587358d167102/ConfigSpace-0.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41940de621cfb41aa16a329520b2d01db6587f8cafc77ad7cf81fef3d9f673e5", size = 6726572 }, + { url = "https://files.pythonhosted.org/packages/5c/42/a5c7f84510b666890281fe5ccbf566b237dc951895a47d213a37ea9f7e5a/ConfigSpace-0.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:3ebed7637a58a3d8df46a0e7123d2a804c8767764d8679245e47e266ed803895", size = 2151915 }, +] + +[[package]] +name = "contourpy" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/25/c2/fc7193cc5383637ff390a712e88e4ded0452c9fbcf84abe3de5ea3df1866/contourpy-1.3.1.tar.gz", hash = "sha256:dfd97abd83335045a913e3bcc4a09c0ceadbe66580cf573fe961f4a825efa699", size = 13465753 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/a3/80937fe3efe0edacf67c9a20b955139a1a622730042c1ea991956f2704ad/contourpy-1.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a045f341a77b77e1c5de31e74e966537bba9f3c4099b35bf4c2e3939dd54cdab", size = 268466 }, + { url = "https://files.pythonhosted.org/packages/82/1d/e3eaebb4aa2d7311528c048350ca8e99cdacfafd99da87bc0a5f8d81f2c2/contourpy-1.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:500360b77259914f7805af7462e41f9cb7ca92ad38e9f94d6c8641b089338124", size = 253314 }, + { url = "https://files.pythonhosted.org/packages/de/f3/d796b22d1a2b587acc8100ba8c07fb7b5e17fde265a7bb05ab967f4c935a/contourpy-1.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2f926efda994cdf3c8d3fdb40b9962f86edbc4457e739277b961eced3d0b4c1", size = 312003 }, + { url = "https://files.pythonhosted.org/packages/bf/f5/0e67902bc4394daee8daa39c81d4f00b50e063ee1a46cb3938cc65585d36/contourpy-1.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:adce39d67c0edf383647a3a007de0a45fd1b08dedaa5318404f1a73059c2512b", size = 351896 }, + { url = "https://files.pythonhosted.org/packages/1f/d6/e766395723f6256d45d6e67c13bb638dd1fa9dc10ef912dc7dd3dcfc19de/contourpy-1.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abbb49fb7dac584e5abc6636b7b2a7227111c4f771005853e7d25176daaf8453", size = 320814 }, + { url = "https://files.pythonhosted.org/packages/a9/57/86c500d63b3e26e5b73a28b8291a67c5608d4aa87ebd17bd15bb33c178bc/contourpy-1.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0cffcbede75c059f535725c1680dfb17b6ba8753f0c74b14e6a9c68c29d7ea3", size = 324969 }, + { url = "https://files.pythonhosted.org/packages/b8/62/bb146d1289d6b3450bccc4642e7f4413b92ebffd9bf2e91b0404323704a7/contourpy-1.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ab29962927945d89d9b293eabd0d59aea28d887d4f3be6c22deaefbb938a7277", size = 1265162 }, + { url = "https://files.pythonhosted.org/packages/18/04/9f7d132ce49a212c8e767042cc80ae390f728060d2eea47058f55b9eff1c/contourpy-1.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:974d8145f8ca354498005b5b981165b74a195abfae9a8129df3e56771961d595", size = 1324328 }, + { url = "https://files.pythonhosted.org/packages/46/23/196813901be3f97c83ababdab1382e13e0edc0bb4e7b49a7bff15fcf754e/contourpy-1.3.1-cp310-cp310-win32.whl", hash = "sha256:ac4578ac281983f63b400f7fe6c101bedc10651650eef012be1ccffcbacf3697", size = 173861 }, + { url = "https://files.pythonhosted.org/packages/e0/82/c372be3fc000a3b2005061ca623a0d1ecd2eaafb10d9e883a2fc8566e951/contourpy-1.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:174e758c66bbc1c8576992cec9599ce8b6672b741b5d336b5c74e35ac382b18e", size = 218566 }, + { url = "https://files.pythonhosted.org/packages/12/bb/11250d2906ee2e8b466b5f93e6b19d525f3e0254ac8b445b56e618527718/contourpy-1.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e8b974d8db2c5610fb4e76307e265de0edb655ae8169e8b21f41807ccbeec4b", size = 269555 }, + { url = "https://files.pythonhosted.org/packages/67/71/1e6e95aee21a500415f5d2dbf037bf4567529b6a4e986594d7026ec5ae90/contourpy-1.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:20914c8c973f41456337652a6eeca26d2148aa96dd7ac323b74516988bea89fc", size = 254549 }, + { url = "https://files.pythonhosted.org/packages/31/2c/b88986e8d79ac45efe9d8801ae341525f38e087449b6c2f2e6050468a42c/contourpy-1.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19d40d37c1c3a4961b4619dd9d77b12124a453cc3d02bb31a07d58ef684d3d86", size = 313000 }, + { url = "https://files.pythonhosted.org/packages/c4/18/65280989b151fcf33a8352f992eff71e61b968bef7432fbfde3a364f0730/contourpy-1.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:113231fe3825ebf6f15eaa8bc1f5b0ddc19d42b733345eae0934cb291beb88b6", size = 352925 }, + { url = "https://files.pythonhosted.org/packages/f5/c7/5fd0146c93220dbfe1a2e0f98969293b86ca9bc041d6c90c0e065f4619ad/contourpy-1.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dbbc03a40f916a8420e420d63e96a1258d3d1b58cbdfd8d1f07b49fcbd38e85", size = 323693 }, + { url = "https://files.pythonhosted.org/packages/85/fc/7fa5d17daf77306840a4e84668a48ddff09e6bc09ba4e37e85ffc8e4faa3/contourpy-1.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a04ecd68acbd77fa2d39723ceca4c3197cb2969633836ced1bea14e219d077c", size = 326184 }, + { url = "https://files.pythonhosted.org/packages/ef/e7/104065c8270c7397c9571620d3ab880558957216f2b5ebb7e040f85eeb22/contourpy-1.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c414fc1ed8ee1dbd5da626cf3710c6013d3d27456651d156711fa24f24bd1291", size = 1268031 }, + { url = "https://files.pythonhosted.org/packages/e2/4a/c788d0bdbf32c8113c2354493ed291f924d4793c4a2e85b69e737a21a658/contourpy-1.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:31c1b55c1f34f80557d3830d3dd93ba722ce7e33a0b472cba0ec3b6535684d8f", size = 1325995 }, + { url = "https://files.pythonhosted.org/packages/a6/e6/a2f351a90d955f8b0564caf1ebe4b1451a3f01f83e5e3a414055a5b8bccb/contourpy-1.3.1-cp311-cp311-win32.whl", hash = "sha256:f611e628ef06670df83fce17805c344710ca5cde01edfdc72751311da8585375", size = 174396 }, + { url = "https://files.pythonhosted.org/packages/a8/7e/cd93cab453720a5d6cb75588cc17dcdc08fc3484b9de98b885924ff61900/contourpy-1.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:b2bdca22a27e35f16794cf585832e542123296b4687f9fd96822db6bae17bfc9", size = 219787 }, + { url = "https://files.pythonhosted.org/packages/37/6b/175f60227d3e7f5f1549fcb374592be311293132207e451c3d7c654c25fb/contourpy-1.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0ffa84be8e0bd33410b17189f7164c3589c229ce5db85798076a3fa136d0e509", size = 271494 }, + { url = "https://files.pythonhosted.org/packages/6b/6a/7833cfae2c1e63d1d8875a50fd23371394f540ce809d7383550681a1fa64/contourpy-1.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805617228ba7e2cbbfb6c503858e626ab528ac2a32a04a2fe88ffaf6b02c32bc", size = 255444 }, + { url = "https://files.pythonhosted.org/packages/7f/b3/7859efce66eaca5c14ba7619791b084ed02d868d76b928ff56890d2d059d/contourpy-1.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ade08d343436a94e633db932e7e8407fe7de8083967962b46bdfc1b0ced39454", size = 307628 }, + { url = "https://files.pythonhosted.org/packages/48/b2/011415f5e3f0a50b1e285a0bf78eb5d92a4df000553570f0851b6e309076/contourpy-1.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47734d7073fb4590b4a40122b35917cd77be5722d80683b249dac1de266aac80", size = 347271 }, + { url = "https://files.pythonhosted.org/packages/84/7d/ef19b1db0f45b151ac78c65127235239a8cf21a59d1ce8507ce03e89a30b/contourpy-1.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ba94a401342fc0f8b948e57d977557fbf4d515f03c67682dd5c6191cb2d16ec", size = 318906 }, + { url = "https://files.pythonhosted.org/packages/ba/99/6794142b90b853a9155316c8f470d2e4821fe6f086b03e372aca848227dd/contourpy-1.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efa874e87e4a647fd2e4f514d5e91c7d493697127beb95e77d2f7561f6905bd9", size = 323622 }, + { url = "https://files.pythonhosted.org/packages/3c/0f/37d2c84a900cd8eb54e105f4fa9aebd275e14e266736778bb5dccbf3bbbb/contourpy-1.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1bf98051f1045b15c87868dbaea84f92408337d4f81d0e449ee41920ea121d3b", size = 1266699 }, + { url = "https://files.pythonhosted.org/packages/3a/8a/deb5e11dc7d9cc8f0f9c8b29d4f062203f3af230ba83c30a6b161a6effc9/contourpy-1.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:61332c87493b00091423e747ea78200659dc09bdf7fd69edd5e98cef5d3e9a8d", size = 1326395 }, + { url = "https://files.pythonhosted.org/packages/1a/35/7e267ae7c13aaf12322ccc493531f1e7f2eb8fba2927b9d7a05ff615df7a/contourpy-1.3.1-cp312-cp312-win32.whl", hash = "sha256:e914a8cb05ce5c809dd0fe350cfbb4e881bde5e2a38dc04e3afe1b3e58bd158e", size = 175354 }, + { url = "https://files.pythonhosted.org/packages/a1/35/c2de8823211d07e8a79ab018ef03960716c5dff6f4d5bff5af87fd682992/contourpy-1.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:08d9d449a61cf53033612cb368f3a1b26cd7835d9b8cd326647efe43bca7568d", size = 220971 }, + { url = "https://files.pythonhosted.org/packages/3e/4f/e56862e64b52b55b5ddcff4090085521fc228ceb09a88390a2b103dccd1b/contourpy-1.3.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b457d6430833cee8e4b8e9b6f07aa1c161e5e0d52e118dc102c8f9bd7dd060d6", size = 265605 }, + { url = "https://files.pythonhosted.org/packages/b0/2e/52bfeeaa4541889f23d8eadc6386b442ee2470bd3cff9baa67deb2dd5c57/contourpy-1.3.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb76c1a154b83991a3cbbf0dfeb26ec2833ad56f95540b442c73950af2013750", size = 315040 }, + { url = "https://files.pythonhosted.org/packages/52/94/86bfae441707205634d80392e873295652fc313dfd93c233c52c4dc07874/contourpy-1.3.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:44a29502ca9c7b5ba389e620d44f2fbe792b1fb5734e8b931ad307071ec58c53", size = 218221 }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 }, +] + +[[package]] +name = "cython" +version = "3.0.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/4d/b720d6000f4ca77f030bd70f12550820f0766b568e43f11af7f7ad9061aa/cython-3.0.11.tar.gz", hash = "sha256:7146dd2af8682b4ca61331851e6aebce9fe5158e75300343f80c07ca80b1faff", size = 2755544 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/7f/ab5796a0951328d7818b771c36fe7e1a2077cffa28c917d9fa4a642728c3/Cython-3.0.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:44292aae17524abb4b70a25111fe7dec1a0ad718711d47e3786a211d5408fdaa", size = 3100879 }, + { url = "https://files.pythonhosted.org/packages/d8/3b/67480e609537e9fc899864847910ded481b82d033fea1b7fcf85893a2fc4/Cython-3.0.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a75d45fbc20651c1b72e4111149fed3b33d270b0a4fb78328c54d965f28d55e1", size = 3461957 }, + { url = "https://files.pythonhosted.org/packages/f0/89/b1ae45689abecca777f95462781a76e67ff46b55495a481ec5a73a739994/Cython-3.0.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d89a82937ce4037f092e9848a7bbcc65bc8e9fc9aef2bb74f5c15e7d21a73080", size = 3627062 }, + { url = "https://files.pythonhosted.org/packages/44/77/a651da74d5d41c6045bbe0b6990b1515bf4850cd7a8d8580333c90dfce2e/Cython-3.0.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a8ea2e7e2d3bc0d8630dafe6c4a5a89485598ff8a61885b74f8ed882597efd5", size = 3680431 }, + { url = "https://files.pythonhosted.org/packages/59/45/60e7e8db93c3eb8b2af8c64020c1fa502e355f4b762886a24d46e433f395/Cython-3.0.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cee29846471ce60226b18e931d8c1c66a158db94853e3e79bc2da9bd22345008", size = 3497314 }, + { url = "https://files.pythonhosted.org/packages/f8/0b/6919025958926625319f83523ee7f45e7e7ae516b8054dcff6eb710daf32/Cython-3.0.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eeb6860b0f4bfa402de8929833fe5370fa34069c7ebacb2d543cb017f21fb891", size = 3709091 }, + { url = "https://files.pythonhosted.org/packages/52/3c/c21b9b9271dfaa46fa2938de730f62fc94b9c2ec25ec400585e372f35dcd/Cython-3.0.11-cp310-cp310-win32.whl", hash = "sha256:3699391125ab344d8d25438074d1097d9ba0fb674d0320599316cfe7cf5f002a", size = 2576110 }, + { url = "https://files.pythonhosted.org/packages/f9/de/19fdd1c7a52e0534bf5f544e0346c15d71d20338dbd013117f763b94613f/Cython-3.0.11-cp310-cp310-win_amd64.whl", hash = "sha256:d02f4ebe15aac7cdacce1a628e556c1983f26d140fd2e0ac5e0a090e605a2d38", size = 2776386 }, + { url = "https://files.pythonhosted.org/packages/f8/73/e55be864199cd674cb3426a052726c205589b1ac66fb0090e7fe793b60b3/Cython-3.0.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75ba1c70b6deeaffbac123856b8d35f253da13552207aa969078611c197377e4", size = 3113599 }, + { url = "https://files.pythonhosted.org/packages/09/c9/537108d0980beffff55336baaf8b34162ad0f3f33ededcb5db07069bc8ef/Cython-3.0.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af91497dc098718e634d6ec8f91b182aea6bb3690f333fc9a7777bc70abe8810", size = 3441131 }, + { url = "https://files.pythonhosted.org/packages/93/03/e330b241ad8aa12bb9d98b58fb76d4eb7dcbe747479aab5c29fce937b9e7/Cython-3.0.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3999fb52d3328a6a5e8c63122b0a8bd110dfcdb98dda585a3def1426b991cba7", size = 3595065 }, + { url = "https://files.pythonhosted.org/packages/4a/84/a3c40f2c0439d425daa5aa4e3a6fdbbb41341a14a6fd97f94906f528d9a4/Cython-3.0.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d566a4e09b8979be8ab9f843bac0dd216c81f5e5f45661a9b25cd162ed80508c", size = 3641667 }, + { url = "https://files.pythonhosted.org/packages/6d/93/bdb61e0254ed8f1d21a14088a473584ecb1963d68dba5682158aa45c70ef/Cython-3.0.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:46aec30f217bdf096175a1a639203d44ac73a36fe7fa3dd06bd012e8f39eca0f", size = 3503650 }, + { url = "https://files.pythonhosted.org/packages/f8/62/0da548144c71176155ff5355c4cc40fb28b9effe22e830b55cec8072bdf2/Cython-3.0.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ddd1fe25af330f4e003421636746a546474e4ccd8f239f55d2898d80983d20ed", size = 3709662 }, + { url = "https://files.pythonhosted.org/packages/56/d3/d9c9eaf3611a9fe5256266d07b6a5f9069aa84d20d9f6aa5824289513315/Cython-3.0.11-cp311-cp311-win32.whl", hash = "sha256:221de0b48bf387f209003508e602ce839a80463522fc6f583ad3c8d5c890d2c1", size = 2577870 }, + { url = "https://files.pythonhosted.org/packages/fd/10/236fcc0306f85a2db1b8bc147aea714b66a2f27bac4d9e09e5b2c5d5dcca/Cython-3.0.11-cp311-cp311-win_amd64.whl", hash = "sha256:3ff8ac1f0ecd4f505db4ab051e58e4531f5d098b6ac03b91c3b902e8d10c67b3", size = 2785053 }, + { url = "https://files.pythonhosted.org/packages/58/50/fbb23239efe2183e4eaf76689270d6f5b3bbcf9be9ad1eb97cc34349e6fc/Cython-3.0.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:11996c40c32abf843ba652a6d53cb15944c88d91f91fc4e6f0028f5df8a8f8a1", size = 3141274 }, + { url = "https://files.pythonhosted.org/packages/87/e5/76379edb21fd5bb9e2aaa1d305492bc35bba96dfb51f5d96867d9863b6df/Cython-3.0.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63f2c892e9f9c1698ecfee78205541623eb31cd3a1b682668be7ac12de94aa8e", size = 3340904 }, + { url = "https://files.pythonhosted.org/packages/9a/ef/44af6aded89444dc45f4466ff207a05d3376c641cf1146c03fd14c55ae64/Cython-3.0.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b14c24f1dc4c4c9d997cca8d1b7fb01187a218aab932328247dcf5694a10102", size = 3514052 }, + { url = "https://files.pythonhosted.org/packages/e0/d5/ef8c7b6aa7a83c508f5c3bf0dfb9eb0a2a9be910c0b1f205f842128269c3/Cython-3.0.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8eed5c015685106db15dd103fd040948ddca9197b1dd02222711815ea782a27", size = 3573721 }, + { url = "https://files.pythonhosted.org/packages/e5/4a/58d6c208563504a35febff94904bb291b368a8b0f28a5e0593c770967caa/Cython-3.0.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780f89c95b8aec1e403005b3bf2f0a2afa060b3eba168c86830f079339adad89", size = 3393594 }, + { url = "https://files.pythonhosted.org/packages/a0/92/a60a400be286dc661609da9db903680bba1423362000b689cf8ef0aec811/Cython-3.0.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a690f2ff460682ea985e8d38ec541be97e0977fa0544aadc21efc116ff8d7579", size = 3601319 }, + { url = "https://files.pythonhosted.org/packages/ac/11/f02fc24d1a071b93e1d07497b0a528687b1f93bb4945c635119480fab3c0/Cython-3.0.11-cp312-cp312-win32.whl", hash = "sha256:2252b5aa57621848e310fe7fa6f7dce5f73aa452884a183d201a8bcebfa05a00", size = 2608335 }, + { url = "https://files.pythonhosted.org/packages/35/00/78ffea3a0ab176267a25ff049518b2582db7ac265bbf27944243d1a81ce2/Cython-3.0.11-cp312-cp312-win_amd64.whl", hash = "sha256:da394654c6da15c1d37f0b7ec5afd325c69a15ceafee2afba14b67a5df8a82c8", size = 2792586 }, + { url = "https://files.pythonhosted.org/packages/43/39/bdbec9142bc46605b54d674bf158a78b191c2b75be527c6dcf3e6dfe90b8/Cython-3.0.11-py2.py3-none-any.whl", hash = "sha256:0e25f6425ad4a700d7f77cd468da9161e63658837d1bc34861a9861a4ef6346d", size = 1171267 }, +] + +[[package]] +name = "decopatch" +version = "1.4.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "makefun" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/90/4c/8ca1f193428cbc4d63d0f07db9b8bd96be2db8ee5deefa93e7e8a28f2812/decopatch-1.4.10.tar.gz", hash = "sha256:957f49c93f4150182c23f8fb51d13bb3213e0f17a79e09c8cca7057598b55720", size = 69538 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/fa/8e4a51e1afda8d4bd73d784bfe4a60cfdeeced9bea419eff5c271180377e/decopatch-1.4.10-py2.py3-none-any.whl", hash = "sha256:e151f7f93de2b1b3fd3f3272dcc7cefd1a69f68ec1c2d8e288ecd9deb36dc5f7", size = 18015 }, +] + +[[package]] +name = "distlib" +version = "0.3.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973 }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, +] + +[[package]] +name = "filelock" +version = "3.16.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 }, +] + +[[package]] +name = "fonttools" +version = "4.55.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/61/a300d1574dc381393424047c0396a0e213db212e28361123af9830d71a8d/fonttools-4.55.3.tar.gz", hash = "sha256:3983313c2a04d6cc1fe9251f8fc647754cf49a61dac6cb1e7249ae67afaafc45", size = 3498155 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/f3/9ac8c6705e4a0ff3c29e524df1caeee6f2987b02fb630129f21cc99a8212/fonttools-4.55.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1dcc07934a2165ccdc3a5a608db56fb3c24b609658a5b340aee4ecf3ba679dc0", size = 2769857 }, + { url = "https://files.pythonhosted.org/packages/d8/24/e8b8edd280bdb7d0ecc88a5d952b1dec2ee2335be71cc5a33c64871cdfe8/fonttools-4.55.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f7d66c15ba875432a2d2fb419523f5d3d347f91f48f57b8b08a2dfc3c39b8a3f", size = 2299705 }, + { url = "https://files.pythonhosted.org/packages/f8/9e/e1ba20bd3b71870207fd45ca3b90208a7edd8ae3b001081dc31c45adb017/fonttools-4.55.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27e4ae3592e62eba83cd2c4ccd9462dcfa603ff78e09110680a5444c6925d841", size = 4576104 }, + { url = "https://files.pythonhosted.org/packages/34/db/d423bc646e6703fe3e6aea0edd22a2df47b9d188c5f7f1b49070be4d2205/fonttools-4.55.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62d65a3022c35e404d19ca14f291c89cc5890032ff04f6c17af0bd1927299674", size = 4618282 }, + { url = "https://files.pythonhosted.org/packages/75/a0/e5062ac960a385b984ba74e7b55132e7f2c65e449e8330ab0f595407a3de/fonttools-4.55.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d342e88764fb201286d185093781bf6628bbe380a913c24adf772d901baa8276", size = 4570539 }, + { url = "https://files.pythonhosted.org/packages/1f/33/0d744ff518ebe50020b63e5018b8b278efd6a930c1d2eedda7defc42153b/fonttools-4.55.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:dd68c87a2bfe37c5b33bcda0fba39b65a353876d3b9006fde3adae31f97b3ef5", size = 4742411 }, + { url = "https://files.pythonhosted.org/packages/7e/6c/2f768652dba6b801f1567fc5d1829cda369bcd6e95e315a91e628f91c702/fonttools-4.55.3-cp310-cp310-win32.whl", hash = "sha256:1bc7ad24ff98846282eef1cbeac05d013c2154f977a79886bb943015d2b1b261", size = 2175132 }, + { url = "https://files.pythonhosted.org/packages/19/d1/4dcd865360fb2c499749a913fe80e41c26e8ae18629d87dfffa3de27e831/fonttools-4.55.3-cp310-cp310-win_amd64.whl", hash = "sha256:b54baf65c52952db65df39fcd4820668d0ef4766c0ccdf32879b77f7c804d5c5", size = 2219430 }, + { url = "https://files.pythonhosted.org/packages/4b/18/14be25545600bd100e5b74a3ac39089b7c1cb403dc513b7ca348be3381bf/fonttools-4.55.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8c4491699bad88efe95772543cd49870cf756b019ad56294f6498982408ab03e", size = 2771005 }, + { url = "https://files.pythonhosted.org/packages/b2/51/2e1a5d3871cd7c2ae2054b54e92604e7d6abc3fd3656e9583c399648fe1c/fonttools-4.55.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5323a22eabddf4b24f66d26894f1229261021dacd9d29e89f7872dd8c63f0b8b", size = 2300654 }, + { url = "https://files.pythonhosted.org/packages/73/1a/50109bb2703bc6f774b52ea081db21edf2a9fa4b6d7485faadf9d1b997e9/fonttools-4.55.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5480673f599ad410695ca2ddef2dfefe9df779a9a5cda89503881e503c9c7d90", size = 4877541 }, + { url = "https://files.pythonhosted.org/packages/5d/52/c0b9857fa075da1b8806c5dc2d8342918a8cc2065fd14fbddb3303282693/fonttools-4.55.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da9da6d65cd7aa6b0f806556f4985bcbf603bf0c5c590e61b43aa3e5a0f822d0", size = 4906304 }, + { url = "https://files.pythonhosted.org/packages/0b/1b/55f85c7e962d295e456d5209581c919620ee3e877b95cd86245187a5050f/fonttools-4.55.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e894b5bd60d9f473bed7a8f506515549cc194de08064d829464088d23097331b", size = 4888087 }, + { url = "https://files.pythonhosted.org/packages/83/13/6f2809c612ea2ac51391f92468ff861c63473601530fca96458b453212bf/fonttools-4.55.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:aee3b57643827e237ff6ec6d28d9ff9766bd8b21e08cd13bff479e13d4b14765", size = 5056958 }, + { url = "https://files.pythonhosted.org/packages/c1/28/d0ea9e872fa4208b9dfca686e1dd9ca22f6c9ef33ecff2f0ebc2dbe7c29b/fonttools-4.55.3-cp311-cp311-win32.whl", hash = "sha256:eb6ca911c4c17eb51853143624d8dc87cdcdf12a711fc38bf5bd21521e79715f", size = 2173939 }, + { url = "https://files.pythonhosted.org/packages/be/36/d74ae1020bc41a1dff3e6f5a99f646563beecb97e386d27abdac3ba07650/fonttools-4.55.3-cp311-cp311-win_amd64.whl", hash = "sha256:6314bf82c54c53c71805318fcf6786d986461622dd926d92a465199ff54b1b72", size = 2220363 }, + { url = "https://files.pythonhosted.org/packages/89/58/fbcf5dff7e3ea844bb00c4d806ca1e339e1f2dce5529633bf4842c0c9a1f/fonttools-4.55.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f9e736f60f4911061235603a6119e72053073a12c6d7904011df2d8fad2c0e35", size = 2765380 }, + { url = "https://files.pythonhosted.org/packages/81/dd/da6e329e51919b4f421c8738f3497e2ab08c168e76aaef7b6d5351862bdf/fonttools-4.55.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a8aa2c5e5b8b3bcb2e4538d929f6589a5c6bdb84fd16e2ed92649fb5454f11c", size = 2297940 }, + { url = "https://files.pythonhosted.org/packages/00/44/f5ee560858425c99ef07e04919e736db09d6416408e5a8d3bbfb4a6623fd/fonttools-4.55.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07f8288aacf0a38d174445fc78377a97fb0b83cfe352a90c9d9c1400571963c7", size = 4793327 }, + { url = "https://files.pythonhosted.org/packages/24/da/0a001926d791c55e29ac3c52964957a20dbc1963615446b568b7432891c3/fonttools-4.55.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8d5e8916c0970fbc0f6f1bece0063363bb5857a7f170121a4493e31c3db3314", size = 4865624 }, + { url = "https://files.pythonhosted.org/packages/3d/d8/1edd8b13a427a9fb6418373437caa586c0caa57f260af8e0548f4d11e340/fonttools-4.55.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ae3b6600565b2d80b7c05acb8e24d2b26ac407b27a3f2e078229721ba5698427", size = 4774166 }, + { url = "https://files.pythonhosted.org/packages/9c/ec/ade054097976c3d6debc9032e09a351505a0196aa5493edf021be376f75e/fonttools-4.55.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:54153c49913f45065c8d9e6d0c101396725c5621c8aee744719300f79771d75a", size = 5001832 }, + { url = "https://files.pythonhosted.org/packages/e2/cd/233f0e31ad799bb91fc78099c8b4e5ec43b85a131688519640d6bae46f6a/fonttools-4.55.3-cp312-cp312-win32.whl", hash = "sha256:827e95fdbbd3e51f8b459af5ea10ecb4e30af50221ca103bea68218e9615de07", size = 2162228 }, + { url = "https://files.pythonhosted.org/packages/46/45/a498b5291f6c0d91b2394b1ed7447442a57d1c9b9cf8f439aee3c316a56e/fonttools-4.55.3-cp312-cp312-win_amd64.whl", hash = "sha256:e6e8766eeeb2de759e862004aa11a9ea3d6f6d5ec710551a88b476192b64fd54", size = 2209118 }, + { url = "https://files.pythonhosted.org/packages/99/3b/406d17b1f63e04a82aa621936e6e1c53a8c05458abd66300ac85ea7f9ae9/fonttools-4.55.3-py3-none-any.whl", hash = "sha256:f412604ccbeee81b091b420272841e5ec5ef68967a9790e80bffd0e30b8e2977", size = 1111638 }, +] + +[[package]] +name = "fsspec" +version = "2024.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/11/de70dee31455c546fbc88301971ec03c328f3d1138cfba14263f651e9551/fsspec-2024.12.0.tar.gz", hash = "sha256:670700c977ed2fb51e0d9f9253177ed20cbde4a3e5c0283cc5385b5870c8533f", size = 291600 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/86/5486b0188d08aa643e127774a99bac51ffa6cf343e3deb0583956dca5b22/fsspec-2024.12.0-py3-none-any.whl", hash = "sha256:b520aed47ad9804237ff878b504267a3b0b441e97508bd6d2d8774e3db85cee2", size = 183862 }, +] + +[[package]] +name = "future" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/b2/4140c69c6a66432916b26158687e821ba631a4c9273c474343badf84d3ba/future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05", size = 1228490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/71/ae30dadffc90b9006d77af76b393cb9dfbfc9629f339fc1574a1c52e6806/future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216", size = 491326 }, +] + +[[package]] +name = "ghp-import" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034 }, +] + +[[package]] +name = "gpytorch" +version = "1.13" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jaxtyping" }, + { name = "linear-operator" }, + { name = "mpmath" }, + { name = "scikit-learn" }, + { name = "scipy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/65/9b66ad6faaff5ef9a3f7896d964419cb11c5b1776eb212cbe9f9d1502e7a/gpytorch-1.13.tar.gz", hash = "sha256:f4a488633a2a7a4ab37d12553d1d1dd39690043dbceef14ca428b7d5f89f73ba", size = 2472751 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/77/e19f17291dba1ad21206b632f2e638376cdfccb7cce852e4c34692c6f9f0/gpytorch-1.13-py3-none-any.whl", hash = "sha256:97da5b07a524952612e8d265ec89d4a5ec0ef0587e76d6178961ce26ef9679d1", size = 277804 }, +] + +[[package]] +name = "grakel" +version = "0.1.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cython" }, + { name = "future" }, + { name = "joblib" }, + { name = "numpy" }, + { name = "scikit-learn" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/8a/e6b4d4bcb1e34c91248675984ee1ebb96e57a2254f955dfde8fd1da5043a/GraKeL-0.1.10.tar.gz", hash = "sha256:0c87f716d8cd69741cf1aa63a230a74c3a8957f8485b2a18689274934ef8fd51", size = 1004389 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/e3/60997210ba1726d7a321d90dd885e598835c554076de399cc2a85a88ef0f/GraKeL-0.1.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:10e42a1d90f07da217c74b80ef663a081f12c36d2754f3245c965a4bb2b1bb14", size = 1040988 }, + { url = "https://files.pythonhosted.org/packages/77/ab/93a4d0e41168afa832a8da0932a7d726f57cdca19082e7d76c8eef37d187/GraKeL-0.1.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e86dfa967d8ea7b22b0bd7d4a5bb49cc9849ef230811c31d9509087bf9bdfbd6", size = 719314 }, + { url = "https://files.pythonhosted.org/packages/fd/6d/5cb7a1f5686895c5a8cff391f3d52ae43f95e2f34c4a6636f3124a688485/GraKeL-0.1.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7afd00a1272a78e2f11df86f159e347dee212e0a18c02ed1a93dbdc0f9abad8", size = 1901551 }, + { url = "https://files.pythonhosted.org/packages/f7/94/f1c66c73f3cea179a65e51bfd2567bd83990c68976c0d07cb6f39e6ee049/GraKeL-0.1.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8012ac44fc779a1d89b7d903ac68d3ab72b333da91736016e1841c939744a471", size = 1933615 }, + { url = "https://files.pythonhosted.org/packages/8b/ac/62a02d45df0165312bdf022834fe97f8dc1a479c8c2a7daebfdb7282ba9d/GraKeL-0.1.10-cp310-cp310-win_amd64.whl", hash = "sha256:e44a72c503967890ff4923654b9c87f1187ff63e217acd0852613ca4355c83d1", size = 678978 }, + { url = "https://files.pythonhosted.org/packages/cf/59/54726f4b988d859c97b9017af639090904c2bef04dd288d99733fcc1489e/GraKeL-0.1.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:10fa86a4b884ae9b873d2ca5fd55ec1cd9e138a5e2fceeeafaf3f1e3b3571c8d", size = 1042774 }, + { url = "https://files.pythonhosted.org/packages/bd/5a/0f1fa0b532bd56dabdfce3aaacd0952aa74edfc4137b5b33d55d5fcf9323/GraKeL-0.1.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f66f171801c8a0133a0be540630c8424345502548a5279af481df3215bcced24", size = 720092 }, + { url = "https://files.pythonhosted.org/packages/06/a9/e6da6ba79c7a961c4ef1007f67d4145fa52a1d4c9e29c018dda0f2ba5f22/GraKeL-0.1.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aed2fd06e793d8330667daebf9b93a5f776d6d45403b179d74e16df0168d3360", size = 2000266 }, + { url = "https://files.pythonhosted.org/packages/c9/9c/4e727cf567187d31b8d0290c8eb2421bf387c7d72bb83b258779641356bd/GraKeL-0.1.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0826b67750517e01c658dad4e068f71e92ae9384bcbbf34f156e698229bd262e", size = 2029461 }, + { url = "https://files.pythonhosted.org/packages/6b/29/714f7a3d09d3defaea6ef556bd8ea04abd2eb356479847cba459ef3bfe39/GraKeL-0.1.10-cp311-cp311-win_amd64.whl", hash = "sha256:a73f54c5c3d0a4c8b0967ef67ff12be286d06997b1ee365a531aeef1f632139b", size = 679135 }, +] + +[[package]] +name = "griffe" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/9b/0bc9d53ed6628aae43223dd3c081637da54f66ed17a8c1d9fd36ee5da244/griffe-1.5.4.tar.gz", hash = "sha256:073e78ad3e10c8378c2f798bd4ef87b92d8411e9916e157fd366a17cc4fd4e52", size = 389376 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/29/d0f156c076ec71eb485e70cbcde4872e3c045cda965a48d1d938aa3d9f76/griffe-1.5.4-py3-none-any.whl", hash = "sha256:ed33af890586a5bebc842fcb919fc694b3dc1bc55b7d9e0228de41ce566b4a1d", size = 128102 }, +] + +[[package]] +name = "grpcio" +version = "1.68.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/ec/b76ff6d86bdfd1737a5ec889394b54c18b1ec3832d91041e25023fbcb67d/grpcio-1.68.1.tar.gz", hash = "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054", size = 12694654 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f5/88/d1ac9676a0809e3efec154d45246474ec12a4941686da71ffb3d34190294/grpcio-1.68.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d", size = 5171054 }, + { url = "https://files.pythonhosted.org/packages/ec/cb/94ca41e100201fee8876a4b44d64e43ac7405929909afe1fa943d65b25ef/grpcio-1.68.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78", size = 11078566 }, + { url = "https://files.pythonhosted.org/packages/d5/b0/ad4c66f2e3181b4eab99885686c960c403ae2300bacfe427526282facc07/grpcio-1.68.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9", size = 5690039 }, + { url = "https://files.pythonhosted.org/packages/67/1e/f5d3410674d021831c9fef2d1d7ca2357b08d09c840ad4e054ea8ffc302e/grpcio-1.68.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e", size = 6317470 }, + { url = "https://files.pythonhosted.org/packages/91/93/701d5f33b163a621c8f2d4453f9e22f6c14e996baed54118d0dea93fc8c7/grpcio-1.68.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330", size = 5941884 }, + { url = "https://files.pythonhosted.org/packages/67/44/06917ffaa35ca463b93dde60f324015fe4192312b0f4dd0faec061e7ca7f/grpcio-1.68.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079", size = 6646332 }, + { url = "https://files.pythonhosted.org/packages/d4/94/074db039532687ec8ef07ebbcc747c46547c94329016e22b97d97b9e5f3b/grpcio-1.68.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1", size = 6212515 }, + { url = "https://files.pythonhosted.org/packages/c5/f2/0c939264c36c6038fae1732a2a3e01a7075ba171a2154d86842ee0ac9b0a/grpcio-1.68.1-cp310-cp310-win32.whl", hash = "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5", size = 3650459 }, + { url = "https://files.pythonhosted.org/packages/b6/90/b0e9278e88f747879d13b79fb893c9acb381fb90541ad9e416c7816c5eaf/grpcio-1.68.1-cp310-cp310-win_amd64.whl", hash = "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746", size = 4399144 }, + { url = "https://files.pythonhosted.org/packages/fe/0d/fde5a5777d65696c39bb3e622fe1239dd0a878589bf6c5066980e7d19154/grpcio-1.68.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c", size = 5180919 }, + { url = "https://files.pythonhosted.org/packages/07/fd/e5fa75b5ddf5d9f16606196973f9c2b4b1adf5a1735117eb7129fc33d2ec/grpcio-1.68.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73", size = 11150922 }, + { url = "https://files.pythonhosted.org/packages/86/1e/aaf5a1dae87fe47f277c5a1be72b31d2c209d095bebb0ce1d2df5cb8779c/grpcio-1.68.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515", size = 5685685 }, + { url = "https://files.pythonhosted.org/packages/a9/69/c4fdf87d5c5696207e2ed232e4bdde656d8c99ba91f361927f3f06aa41ca/grpcio-1.68.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd", size = 6316535 }, + { url = "https://files.pythonhosted.org/packages/6f/c6/539660516ea7db7bc3d39e07154512ae807961b14ec6b5b0c58d15657ff1/grpcio-1.68.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600", size = 5939920 }, + { url = "https://files.pythonhosted.org/packages/38/f3/97a74dc4dd95bf195168d6da2ca4731ab7d3d0b03078f2833b4ff9c4f48f/grpcio-1.68.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe", size = 6644770 }, + { url = "https://files.pythonhosted.org/packages/cb/36/79a5e04073e58106aff442509a0c459151fa4f43202395db3eb8f77b78e9/grpcio-1.68.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0", size = 6211743 }, + { url = "https://files.pythonhosted.org/packages/73/0f/2250f4a0de1a0bec0726c47a021cbf71af6105f512ecaf67703e2eb1ad2f/grpcio-1.68.1-cp311-cp311-win32.whl", hash = "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9", size = 3650734 }, + { url = "https://files.pythonhosted.org/packages/4b/29/061c93a35f498238dc35eb8fb039ce168aa99cac2f0f1ce0c8a0a4bdb274/grpcio-1.68.1-cp311-cp311-win_amd64.whl", hash = "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2", size = 4400816 }, + { url = "https://files.pythonhosted.org/packages/f5/15/674a1468fef234fa996989509bbdfc0d695878cbb385b9271f5d690d5cd3/grpcio-1.68.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666", size = 5148351 }, + { url = "https://files.pythonhosted.org/packages/62/f5/edce368682d6d0b3573b883b134df022a44b1c888ea416dd7d78d480ab24/grpcio-1.68.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1", size = 11127559 }, + { url = "https://files.pythonhosted.org/packages/ce/14/a6fde3114eafd9e4e345d1ebd0291c544d83b22f0554b1678a2968ae39e1/grpcio-1.68.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684", size = 5645221 }, + { url = "https://files.pythonhosted.org/packages/21/21/d1865bd6a22f9a26217e4e1b35f9105f7a0cdfb7a5fffe8be48e1a1afafc/grpcio-1.68.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e", size = 6292270 }, + { url = "https://files.pythonhosted.org/packages/3a/f6/19798be6c3515a7b1fb9570198c91710472e2eb21f1900109a76834829e3/grpcio-1.68.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60", size = 5905978 }, + { url = "https://files.pythonhosted.org/packages/9b/43/c3670a657445cd55be1246f64dbc3a6a33cab0f0141c5836df2e04f794c8/grpcio-1.68.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475", size = 6630444 }, + { url = "https://files.pythonhosted.org/packages/80/69/fbbebccffd266bea4268b685f3e8e03613405caba69e93125dc783036465/grpcio-1.68.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613", size = 6200324 }, + { url = "https://files.pythonhosted.org/packages/65/5c/27a26c21916f94f0c1585111974a5d5a41d8420dcb42c2717ee514c97a97/grpcio-1.68.1-cp312-cp312-win32.whl", hash = "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5", size = 3638381 }, + { url = "https://files.pythonhosted.org/packages/a3/ba/ba6b65ccc93c7df1031c6b41e45b79a5a37e46b81d816bb3ea68ba476d77/grpcio-1.68.1-cp312-cp312-win_amd64.whl", hash = "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c", size = 4389959 }, +] + +[[package]] +name = "identify" +version = "2.6.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/a5/7de3053524ee006b91099968d7ecb2e0b420f7ae728094394c33e8a2a2b9/identify-2.6.4.tar.gz", hash = "sha256:285a7d27e397652e8cafe537a6cc97dd470a970f48fb2e9d979aa38eae5513ac", size = 99209 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/9d/52f036403ae86474804f699c0d084b4b071e333a390b20269bb8accc65e0/identify-2.6.4-py2.py3-none-any.whl", hash = "sha256:993b0f01b97e0568c179bb9196391ff391bfb88a99099dbf5ce392b68f42d0af", size = 99072 }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "ifbo" +version = "0.3.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cloudpickle" }, + { name = "numpy" }, + { name = "requests" }, + { name = "scipy" }, + { name = "submitit" }, + { name = "torch" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bb/31/2c8b7271097629d474bac7c46f9caad673e33e2d7d1fb35e84655358e366/ifbo-0.3.11.tar.gz", hash = "sha256:473da139225ec2ffdbf7f92718acb049b20f0919a4e00ae9173a99134c3fc3d4", size = 710936 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/5b/cf97e109e572a3f204175dffe19cdc7101c229d335ba4c7ebe0cb6073277/ifBO-0.3.11-py3-none-any.whl", hash = "sha256:1927aae7fc52bcdab899bdef9ee7377e9f8dc4010bf2830b203d2e3748245d4d", size = 713420 }, +] + +[[package]] +name = "importlib-metadata" +version = "8.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", size = 55304 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/d9/a1e041c5e7caa9a05c925f4bdbdfb7f006d1f74996af53467bc394c97be7/importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", size = 26514 }, +] + +[[package]] +name = "importlib-resources" +version = "6.4.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/be/f3e8c6081b684f176b761e6a2fef02a0be939740ed6f54109a2951d806f3/importlib_resources-6.4.5.tar.gz", hash = "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065", size = 43372 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/6a/4604f9ae2fa62ef47b9de2fa5ad599589d28c9fd1d335f32759813dfa91e/importlib_resources-6.4.5-py3-none-any.whl", hash = "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717", size = 36115 }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "jaxtyping" +version = "0.2.19" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "typeguard" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6b/9f/1f8b63965b795803c5bc38afcfcf8ce8d922ffc65a26d4a08071279b0403/jaxtyping-0.2.19.tar.gz", hash = "sha256:21ff4c3caec6781cadfe980b019dde856c1011e17d11dfe8589298040056325a", size = 16653 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/8f/b39d40fef81d7def4898ad11bbe686185e09cb9e39db905e2afc77f1d350/jaxtyping-0.2.19-py3-none-any.whl", hash = "sha256:651352032799d422987e783fd1b77699b53c3bb28ffa644bbca5f75ec4fbb843", size = 24145 }, +] + +[[package]] +name = "jinja2" +version = "3.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/92/b3130cbbf5591acf9ade8708c365f3238046ac7cb8ccba6e81abccb0ccff/jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", size = 244674 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 }, +] + +[[package]] +name = "joblib" +version = "1.4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/64/33/60135848598c076ce4b231e1b1895170f45fbcaeaa2c9d5e38b04db70c35/joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e", size = 2116621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/29/df4b9b42f2be0b623cbd5e2140cafcaa2bef0759a00b7b70104dcfe2fb51/joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6", size = 301817 }, +] + +[[package]] +name = "kiwisolver" +version = "1.4.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/59/7c91426a8ac292e1cdd53a63b6d9439abd573c875c3f92c146767dd33faf/kiwisolver-1.4.8.tar.gz", hash = "sha256:23d5f023bdc8c7e54eb65f03ca5d5bb25b601eac4d7f1a042888a1f45237987e", size = 97538 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/5f/4d8e9e852d98ecd26cdf8eaf7ed8bc33174033bba5e07001b289f07308fd/kiwisolver-1.4.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88c6f252f6816a73b1f8c904f7bbe02fd67c09a69f7cb8a0eecdbf5ce78e63db", size = 124623 }, + { url = "https://files.pythonhosted.org/packages/1d/70/7f5af2a18a76fe92ea14675f8bd88ce53ee79e37900fa5f1a1d8e0b42998/kiwisolver-1.4.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72941acb7b67138f35b879bbe85be0f6c6a70cab78fe3ef6db9c024d9223e5b", size = 66720 }, + { url = "https://files.pythonhosted.org/packages/c6/13/e15f804a142353aefd089fadc8f1d985561a15358c97aca27b0979cb0785/kiwisolver-1.4.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce2cf1e5688edcb727fdf7cd1bbd0b6416758996826a8be1d958f91880d0809d", size = 65413 }, + { url = "https://files.pythonhosted.org/packages/ce/6d/67d36c4d2054e83fb875c6b59d0809d5c530de8148846b1370475eeeece9/kiwisolver-1.4.8-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c8bf637892dc6e6aad2bc6d4d69d08764166e5e3f69d469e55427b6ac001b19d", size = 1650826 }, + { url = "https://files.pythonhosted.org/packages/de/c6/7b9bb8044e150d4d1558423a1568e4f227193662a02231064e3824f37e0a/kiwisolver-1.4.8-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:034d2c891f76bd3edbdb3ea11140d8510dca675443da7304205a2eaa45d8334c", size = 1628231 }, + { url = "https://files.pythonhosted.org/packages/b6/38/ad10d437563063eaaedbe2c3540a71101fc7fb07a7e71f855e93ea4de605/kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d47b28d1dfe0793d5e96bce90835e17edf9a499b53969b03c6c47ea5985844c3", size = 1408938 }, + { url = "https://files.pythonhosted.org/packages/52/ce/c0106b3bd7f9e665c5f5bc1e07cc95b5dabd4e08e3dad42dbe2faad467e7/kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb158fe28ca0c29f2260cca8c43005329ad58452c36f0edf298204de32a9a3ed", size = 1422799 }, + { url = "https://files.pythonhosted.org/packages/d0/87/efb704b1d75dc9758087ba374c0f23d3254505edaedd09cf9d247f7878b9/kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5536185fce131780ebd809f8e623bf4030ce1b161353166c49a3c74c287897f", size = 1354362 }, + { url = "https://files.pythonhosted.org/packages/eb/b3/fd760dc214ec9a8f208b99e42e8f0130ff4b384eca8b29dd0efc62052176/kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:369b75d40abedc1da2c1f4de13f3482cb99e3237b38726710f4a793432b1c5ff", size = 2222695 }, + { url = "https://files.pythonhosted.org/packages/a2/09/a27fb36cca3fc01700687cc45dae7a6a5f8eeb5f657b9f710f788748e10d/kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:641f2ddf9358c80faa22e22eb4c9f54bd3f0e442e038728f500e3b978d00aa7d", size = 2370802 }, + { url = "https://files.pythonhosted.org/packages/3d/c3/ba0a0346db35fe4dc1f2f2cf8b99362fbb922d7562e5f911f7ce7a7b60fa/kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d561d2d8883e0819445cfe58d7ddd673e4015c3c57261d7bdcd3710d0d14005c", size = 2334646 }, + { url = "https://files.pythonhosted.org/packages/41/52/942cf69e562f5ed253ac67d5c92a693745f0bed3c81f49fc0cbebe4d6b00/kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1732e065704b47c9afca7ffa272f845300a4eb959276bf6970dc07265e73b605", size = 2467260 }, + { url = "https://files.pythonhosted.org/packages/32/26/2d9668f30d8a494b0411d4d7d4ea1345ba12deb6a75274d58dd6ea01e951/kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bcb1ebc3547619c3b58a39e2448af089ea2ef44b37988caf432447374941574e", size = 2288633 }, + { url = "https://files.pythonhosted.org/packages/98/99/0dd05071654aa44fe5d5e350729961e7bb535372935a45ac89a8924316e6/kiwisolver-1.4.8-cp310-cp310-win_amd64.whl", hash = "sha256:89c107041f7b27844179ea9c85d6da275aa55ecf28413e87624d033cf1f6b751", size = 71885 }, + { url = "https://files.pythonhosted.org/packages/6c/fc/822e532262a97442989335394d441cd1d0448c2e46d26d3e04efca84df22/kiwisolver-1.4.8-cp310-cp310-win_arm64.whl", hash = "sha256:b5773efa2be9eb9fcf5415ea3ab70fc785d598729fd6057bea38d539ead28271", size = 65175 }, + { url = "https://files.pythonhosted.org/packages/da/ed/c913ee28936c371418cb167b128066ffb20bbf37771eecc2c97edf8a6e4c/kiwisolver-1.4.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a4d3601908c560bdf880f07d94f31d734afd1bb71e96585cace0e38ef44c6d84", size = 124635 }, + { url = "https://files.pythonhosted.org/packages/4c/45/4a7f896f7467aaf5f56ef093d1f329346f3b594e77c6a3c327b2d415f521/kiwisolver-1.4.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:856b269c4d28a5c0d5e6c1955ec36ebfd1651ac00e1ce0afa3e28da95293b561", size = 66717 }, + { url = "https://files.pythonhosted.org/packages/5f/b4/c12b3ac0852a3a68f94598d4c8d569f55361beef6159dce4e7b624160da2/kiwisolver-1.4.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c2b9a96e0f326205af81a15718a9073328df1173a2619a68553decb7097fd5d7", size = 65413 }, + { url = "https://files.pythonhosted.org/packages/a9/98/1df4089b1ed23d83d410adfdc5947245c753bddfbe06541c4aae330e9e70/kiwisolver-1.4.8-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5020c83e8553f770cb3b5fc13faac40f17e0b205bd237aebd21d53d733adb03", size = 1343994 }, + { url = "https://files.pythonhosted.org/packages/8d/bf/b4b169b050c8421a7c53ea1ea74e4ef9c335ee9013216c558a047f162d20/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dace81d28c787956bfbfbbfd72fdcef014f37d9b48830829e488fdb32b49d954", size = 1434804 }, + { url = "https://files.pythonhosted.org/packages/66/5a/e13bd341fbcf73325ea60fdc8af752addf75c5079867af2e04cc41f34434/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11e1022b524bd48ae56c9b4f9296bce77e15a2e42a502cceba602f804b32bb79", size = 1450690 }, + { url = "https://files.pythonhosted.org/packages/9b/4f/5955dcb376ba4a830384cc6fab7d7547bd6759fe75a09564910e9e3bb8ea/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b9b4d2892fefc886f30301cdd80debd8bb01ecdf165a449eb6e78f79f0fabd6", size = 1376839 }, + { url = "https://files.pythonhosted.org/packages/3a/97/5edbed69a9d0caa2e4aa616ae7df8127e10f6586940aa683a496c2c280b9/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a96c0e790ee875d65e340ab383700e2b4891677b7fcd30a699146f9384a2bb0", size = 1435109 }, + { url = "https://files.pythonhosted.org/packages/13/fc/e756382cb64e556af6c1809a1bbb22c141bbc2445049f2da06b420fe52bf/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23454ff084b07ac54ca8be535f4174170c1094a4cff78fbae4f73a4bcc0d4dab", size = 2245269 }, + { url = "https://files.pythonhosted.org/packages/76/15/e59e45829d7f41c776d138245cabae6515cb4eb44b418f6d4109c478b481/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:87b287251ad6488e95b4f0b4a79a6d04d3ea35fde6340eb38fbd1ca9cd35bbbc", size = 2393468 }, + { url = "https://files.pythonhosted.org/packages/e9/39/483558c2a913ab8384d6e4b66a932406f87c95a6080112433da5ed668559/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b21dbe165081142b1232a240fc6383fd32cdd877ca6cc89eab93e5f5883e1c25", size = 2355394 }, + { url = "https://files.pythonhosted.org/packages/01/aa/efad1fbca6570a161d29224f14b082960c7e08268a133fe5dc0f6906820e/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:768cade2c2df13db52475bd28d3a3fac8c9eff04b0e9e2fda0f3760f20b3f7fc", size = 2490901 }, + { url = "https://files.pythonhosted.org/packages/c9/4f/15988966ba46bcd5ab9d0c8296914436720dd67fca689ae1a75b4ec1c72f/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d47cfb2650f0e103d4bf68b0b5804c68da97272c84bb12850d877a95c056bd67", size = 2312306 }, + { url = "https://files.pythonhosted.org/packages/2d/27/bdf1c769c83f74d98cbc34483a972f221440703054894a37d174fba8aa68/kiwisolver-1.4.8-cp311-cp311-win_amd64.whl", hash = "sha256:ed33ca2002a779a2e20eeb06aea7721b6e47f2d4b8a8ece979d8ba9e2a167e34", size = 71966 }, + { url = "https://files.pythonhosted.org/packages/4a/c9/9642ea855604aeb2968a8e145fc662edf61db7632ad2e4fb92424be6b6c0/kiwisolver-1.4.8-cp311-cp311-win_arm64.whl", hash = "sha256:16523b40aab60426ffdebe33ac374457cf62863e330a90a0383639ce14bf44b2", size = 65311 }, + { url = "https://files.pythonhosted.org/packages/fc/aa/cea685c4ab647f349c3bc92d2daf7ae34c8e8cf405a6dcd3a497f58a2ac3/kiwisolver-1.4.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6af5e8815fd02997cb6ad9bbed0ee1e60014438ee1a5c2444c96f87b8843502", size = 124152 }, + { url = "https://files.pythonhosted.org/packages/c5/0b/8db6d2e2452d60d5ebc4ce4b204feeb16176a851fd42462f66ade6808084/kiwisolver-1.4.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bade438f86e21d91e0cf5dd7c0ed00cda0f77c8c1616bd83f9fc157fa6760d31", size = 66555 }, + { url = "https://files.pythonhosted.org/packages/60/26/d6a0db6785dd35d3ba5bf2b2df0aedc5af089962c6eb2cbf67a15b81369e/kiwisolver-1.4.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b83dc6769ddbc57613280118fb4ce3cd08899cc3369f7d0e0fab518a7cf37fdb", size = 65067 }, + { url = "https://files.pythonhosted.org/packages/c9/ed/1d97f7e3561e09757a196231edccc1bcf59d55ddccefa2afc9c615abd8e0/kiwisolver-1.4.8-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111793b232842991be367ed828076b03d96202c19221b5ebab421ce8bcad016f", size = 1378443 }, + { url = "https://files.pythonhosted.org/packages/29/61/39d30b99954e6b46f760e6289c12fede2ab96a254c443639052d1b573fbc/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:257af1622860e51b1a9d0ce387bf5c2c4f36a90594cb9514f55b074bcc787cfc", size = 1472728 }, + { url = "https://files.pythonhosted.org/packages/0c/3e/804163b932f7603ef256e4a715e5843a9600802bb23a68b4e08c8c0ff61d/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b5637c3f316cab1ec1c9a12b8c5f4750a4c4b71af9157645bf32830e39c03a", size = 1478388 }, + { url = "https://files.pythonhosted.org/packages/8a/9e/60eaa75169a154700be74f875a4d9961b11ba048bef315fbe89cb6999056/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:782bb86f245ec18009890e7cb8d13a5ef54dcf2ebe18ed65f795e635a96a1c6a", size = 1413849 }, + { url = "https://files.pythonhosted.org/packages/bc/b3/9458adb9472e61a998c8c4d95cfdfec91c73c53a375b30b1428310f923e4/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc978a80a0db3a66d25767b03688f1147a69e6237175c0f4ffffaaedf744055a", size = 1475533 }, + { url = "https://files.pythonhosted.org/packages/e4/7a/0a42d9571e35798de80aef4bb43a9b672aa7f8e58643d7bd1950398ffb0a/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:36dbbfd34838500a31f52c9786990d00150860e46cd5041386f217101350f0d3", size = 2268898 }, + { url = "https://files.pythonhosted.org/packages/d9/07/1255dc8d80271400126ed8db35a1795b1a2c098ac3a72645075d06fe5c5d/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:eaa973f1e05131de5ff3569bbba7f5fd07ea0595d3870ed4a526d486fe57fa1b", size = 2425605 }, + { url = "https://files.pythonhosted.org/packages/84/df/5a3b4cf13780ef6f6942df67b138b03b7e79e9f1f08f57c49957d5867f6e/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a66f60f8d0c87ab7f59b6fb80e642ebb29fec354a4dfad687ca4092ae69d04f4", size = 2375801 }, + { url = "https://files.pythonhosted.org/packages/8f/10/2348d068e8b0f635c8c86892788dac7a6b5c0cb12356620ab575775aad89/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858416b7fb777a53f0c59ca08190ce24e9abbd3cffa18886a5781b8e3e26f65d", size = 2520077 }, + { url = "https://files.pythonhosted.org/packages/32/d8/014b89fee5d4dce157d814303b0fce4d31385a2af4c41fed194b173b81ac/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:085940635c62697391baafaaeabdf3dd7a6c3643577dde337f4d66eba021b2b8", size = 2338410 }, + { url = "https://files.pythonhosted.org/packages/bd/72/dfff0cc97f2a0776e1c9eb5bef1ddfd45f46246c6533b0191887a427bca5/kiwisolver-1.4.8-cp312-cp312-win_amd64.whl", hash = "sha256:01c3d31902c7db5fb6182832713d3b4122ad9317c2c5877d0539227d96bb2e50", size = 71853 }, + { url = "https://files.pythonhosted.org/packages/dc/85/220d13d914485c0948a00f0b9eb419efaf6da81b7d72e88ce2391f7aed8d/kiwisolver-1.4.8-cp312-cp312-win_arm64.whl", hash = "sha256:a3c44cb68861de93f0c4a8175fbaa691f0aa22550c331fefef02b618a9dcb476", size = 65424 }, + { url = "https://files.pythonhosted.org/packages/1f/f9/ae81c47a43e33b93b0a9819cac6723257f5da2a5a60daf46aa5c7226ea85/kiwisolver-1.4.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e7a019419b7b510f0f7c9dceff8c5eae2392037eae483a7f9162625233802b0a", size = 60403 }, + { url = "https://files.pythonhosted.org/packages/58/ca/f92b5cb6f4ce0c1ebfcfe3e2e42b96917e16f7090e45b21102941924f18f/kiwisolver-1.4.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:286b18e86682fd2217a48fc6be6b0f20c1d0ed10958d8dc53453ad58d7be0bf8", size = 58657 }, + { url = "https://files.pythonhosted.org/packages/80/28/ae0240f732f0484d3a4dc885d055653c47144bdf59b670aae0ec3c65a7c8/kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4191ee8dfd0be1c3666ccbac178c5a05d5f8d689bbe3fc92f3c4abec817f8fe0", size = 84948 }, + { url = "https://files.pythonhosted.org/packages/5d/eb/78d50346c51db22c7203c1611f9b513075f35c4e0e4877c5dde378d66043/kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cd2785b9391f2873ad46088ed7599a6a71e762e1ea33e87514b1a441ed1da1c", size = 81186 }, + { url = "https://files.pythonhosted.org/packages/43/f8/7259f18c77adca88d5f64f9a522792e178b2691f3748817a8750c2d216ef/kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c07b29089b7ba090b6f1a669f1411f27221c3662b3a1b7010e67b59bb5a6f10b", size = 80279 }, + { url = "https://files.pythonhosted.org/packages/3a/1d/50ad811d1c5dae091e4cf046beba925bcae0a610e79ae4c538f996f63ed5/kiwisolver-1.4.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:65ea09a5a3faadd59c2ce96dc7bf0f364986a315949dc6374f04396b0d60e09b", size = 71762 }, +] + +[[package]] +name = "linear-operator" +version = "0.5.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jaxtyping" }, + { name = "mpmath" }, + { name = "scipy" }, + { name = "torch" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/90/f4/d3f2e2aecf1fc23c5007b40312b0461e1426720a8e2e5a5ef67554670dd6/linear_operator-0.5.3.tar.gz", hash = "sha256:16122661cd8b8a89ea965c845f650affe0f688f315893bb8dfa1182f148a1a41", size = 186038 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/5e/4cff4e634151884502a260f5fc3f92303775133b0e0fedb7d3c7f2a56d4c/linear_operator-0.5.3-py3-none-any.whl", hash = "sha256:908df4e64e25312edfa5502b30b71df97383cb604a13f420921030ae40c47838", size = 176406 }, +] + +[[package]] +name = "makefun" +version = "1.15.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/00/62966769824620717a3c2d76b1d442489648398b599bdcd490af13bff101/makefun-1.15.6.tar.gz", hash = "sha256:26bc63442a6182fb75efed8b51741dd2d1db2f176bec8c64e20a586256b8f149", size = 72583 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/a1/3e145759e776c8866488a71270c399bf7c4e554551ac2e247aa0a18a0596/makefun-1.15.6-py2.py3-none-any.whl", hash = "sha256:e69b870f0bb60304765b1e3db576aaecf2f9b3e5105afe8cfeff8f2afe6ad067", size = 22946 }, +] + +[[package]] +name = "markdown" +version = "3.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/28/3af612670f82f4c056911fbbbb42760255801b3068c48de792d354ff4472/markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2", size = 357086 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/08/83871f3c50fc983b88547c196d11cf8c3340e37c32d2e9d6152abe2c61f7/Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803", size = 106349 }, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357 }, + { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393 }, + { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732 }, + { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866 }, + { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964 }, + { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977 }, + { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366 }, + { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091 }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, +] + +[[package]] +name = "matplotlib" +version = "3.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/68/dd/fa2e1a45fce2d09f4aea3cee169760e672c8262325aa5796c49d543dc7e6/matplotlib-3.10.0.tar.gz", hash = "sha256:b886d02a581b96704c9d1ffe55709e49b4d2d52709ccebc4be42db856e511278", size = 36686418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/ec/3cdff7b5239adaaacefcc4f77c316dfbbdf853c4ed2beec467e0fec31b9f/matplotlib-3.10.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2c5829a5a1dd5a71f0e31e6e8bb449bc0ee9dbfb05ad28fc0c6b55101b3a4be6", size = 8160551 }, + { url = "https://files.pythonhosted.org/packages/41/f2/b518f2c7f29895c9b167bf79f8529c63383ae94eaf49a247a4528e9a148d/matplotlib-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2a43cbefe22d653ab34bb55d42384ed30f611bcbdea1f8d7f431011a2e1c62e", size = 8034853 }, + { url = "https://files.pythonhosted.org/packages/ed/8d/45754b4affdb8f0d1a44e4e2bcd932cdf35b256b60d5eda9f455bb293ed0/matplotlib-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:607b16c8a73943df110f99ee2e940b8a1cbf9714b65307c040d422558397dac5", size = 8446724 }, + { url = "https://files.pythonhosted.org/packages/09/5a/a113495110ae3e3395c72d82d7bc4802902e46dc797f6b041e572f195c56/matplotlib-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01d2b19f13aeec2e759414d3bfe19ddfb16b13a1250add08d46d5ff6f9be83c6", size = 8583905 }, + { url = "https://files.pythonhosted.org/packages/12/b1/8b1655b4c9ed4600c817c419f7eaaf70082630efd7556a5b2e77a8a3cdaf/matplotlib-3.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e6c6461e1fc63df30bf6f80f0b93f5b6784299f721bc28530477acd51bfc3d1", size = 9395223 }, + { url = "https://files.pythonhosted.org/packages/5a/85/b9a54d64585a6b8737a78a61897450403c30f39e0bd3214270bb0b96f002/matplotlib-3.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:994c07b9d9fe8d25951e3202a68c17900679274dadfc1248738dcfa1bd40d7f3", size = 8025355 }, + { url = "https://files.pythonhosted.org/packages/0c/f1/e37f6c84d252867d7ddc418fff70fc661cfd363179263b08e52e8b748e30/matplotlib-3.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:fd44fc75522f58612ec4a33958a7e5552562b7705b42ef1b4f8c0818e304a363", size = 8171677 }, + { url = "https://files.pythonhosted.org/packages/c7/8b/92e9da1f28310a1f6572b5c55097b0c0ceb5e27486d85fb73b54f5a9b939/matplotlib-3.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c58a9622d5dbeb668f407f35f4e6bfac34bb9ecdcc81680c04d0258169747997", size = 8044945 }, + { url = "https://files.pythonhosted.org/packages/c5/cb/49e83f0fd066937a5bd3bc5c5d63093703f3637b2824df8d856e0558beef/matplotlib-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:845d96568ec873be63f25fa80e9e7fae4be854a66a7e2f0c8ccc99e94a8bd4ef", size = 8458269 }, + { url = "https://files.pythonhosted.org/packages/b2/7d/2d873209536b9ee17340754118a2a17988bc18981b5b56e6715ee07373ac/matplotlib-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5439f4c5a3e2e8eab18e2f8c3ef929772fd5641876db71f08127eed95ab64683", size = 8599369 }, + { url = "https://files.pythonhosted.org/packages/b8/03/57d6cbbe85c61fe4cbb7c94b54dce443d68c21961830833a1f34d056e5ea/matplotlib-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4673ff67a36152c48ddeaf1135e74ce0d4bce1bbf836ae40ed39c29edf7e2765", size = 9405992 }, + { url = "https://files.pythonhosted.org/packages/14/cf/e382598f98be11bf51dd0bc60eca44a517f6793e3dc8b9d53634a144620c/matplotlib-3.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:7e8632baebb058555ac0cde75db885c61f1212e47723d63921879806b40bec6a", size = 8034580 }, + { url = "https://files.pythonhosted.org/packages/44/c7/6b2d8cb7cc251d53c976799cacd3200add56351c175ba89ab9cbd7c1e68a/matplotlib-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4659665bc7c9b58f8c00317c3c2a299f7f258eeae5a5d56b4c64226fca2f7c59", size = 8172465 }, + { url = "https://files.pythonhosted.org/packages/42/2a/6d66d0fba41e13e9ca6512a0a51170f43e7e7ed3a8dfa036324100775612/matplotlib-3.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d44cb942af1693cced2604c33a9abcef6205601c445f6d0dc531d813af8a2f5a", size = 8043300 }, + { url = "https://files.pythonhosted.org/packages/90/60/2a60342b27b90a16bada939a85e29589902b41073f59668b904b15ea666c/matplotlib-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a994f29e968ca002b50982b27168addfd65f0105610b6be7fa515ca4b5307c95", size = 8448936 }, + { url = "https://files.pythonhosted.org/packages/a7/b2/d872fc3d753516870d520595ddd8ce4dd44fa797a240999f125f58521ad7/matplotlib-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b0558bae37f154fffda54d779a592bc97ca8b4701f1c710055b609a3bac44c8", size = 8594151 }, + { url = "https://files.pythonhosted.org/packages/f4/bd/b2f60cf7f57d014ab33e4f74602a2b5bdc657976db8196bbc022185f6f9c/matplotlib-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:503feb23bd8c8acc75541548a1d709c059b7184cde26314896e10a9f14df5f12", size = 9400347 }, + { url = "https://files.pythonhosted.org/packages/9f/6e/264673e64001b99d747aff5a288eca82826c024437a3694e19aed1decf46/matplotlib-3.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:c40ba2eb08b3f5de88152c2333c58cee7edcead0a2a0d60fcafa116b17117adc", size = 8039144 }, + { url = "https://files.pythonhosted.org/packages/32/5f/29def7ce4e815ab939b56280976ee35afffb3bbdb43f332caee74cb8c951/matplotlib-3.10.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:81713dd0d103b379de4516b861d964b1d789a144103277769238c732229d7f03", size = 8155500 }, + { url = "https://files.pythonhosted.org/packages/de/6d/d570383c9f7ca799d0a54161446f9ce7b17d6c50f2994b653514bcaa108f/matplotlib-3.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:359f87baedb1f836ce307f0e850d12bb5f1936f70d035561f90d41d305fdacea", size = 8032398 }, + { url = "https://files.pythonhosted.org/packages/c9/b4/680aa700d99b48e8c4393fa08e9ab8c49c0555ee6f4c9c0a5e8ea8dfde5d/matplotlib-3.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae80dc3a4add4665cf2faa90138384a7ffe2a4e37c58d83e115b54287c4f06ef", size = 8587361 }, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354 }, +] + +[[package]] +name = "mike" +version = "2.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata" }, + { name = "importlib-resources" }, + { name = "jinja2" }, + { name = "mkdocs" }, + { name = "pyparsing" }, + { name = "pyyaml" }, + { name = "pyyaml-env-tag" }, + { name = "verspec" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/f7/2933f1a1fb0e0f077d5d6a92c6c7f8a54e6128241f116dff4df8b6050bbf/mike-2.1.3.tar.gz", hash = "sha256:abd79b8ea483fb0275b7972825d3082e5ae67a41820f8d8a0dc7a3f49944e810", size = 38119 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl", hash = "sha256:d90c64077e84f06272437b464735130d380703a76a5738b152932884c60c062a", size = 33754 }, +] + +[[package]] +name = "mkdocs" +version = "1.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "ghp-import" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mergedeep" }, + { name = "mkdocs-get-deps" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "pyyaml" }, + { name = "pyyaml-env-tag" }, + { name = "watchdog" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451 }, +] + +[[package]] +name = "mkdocs-autorefs" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/ae/0f1154c614d6a8b8a36fff084e5b82af3a15f7d2060cf0dcdb1c53297a71/mkdocs_autorefs-1.2.0.tar.gz", hash = "sha256:a86b93abff653521bda71cf3fc5596342b7a23982093915cb74273f67522190f", size = 40262 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/26/4d39d52ea2219604053a4d05b98e90d6a335511cc01806436ec4886b1028/mkdocs_autorefs-1.2.0-py3-none-any.whl", hash = "sha256:d588754ae89bd0ced0c70c06f58566a4ee43471eeeee5202427da7de9ef85a2f", size = 16522 }, +] + +[[package]] +name = "mkdocs-gen-files" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/85/2d634462fd59136197d3126ca431ffb666f412e3db38fd5ce3a60566303e/mkdocs_gen_files-0.5.0.tar.gz", hash = "sha256:4c7cf256b5d67062a788f6b1d035e157fc1a9498c2399be9af5257d4ff4d19bc", size = 7539 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/0f/1e55b3fd490ad2cecb6e7b31892d27cb9fc4218ec1dab780440ba8579e74/mkdocs_gen_files-0.5.0-py3-none-any.whl", hash = "sha256:7ac060096f3f40bd19039e7277dd3050be9a453c8ac578645844d4d91d7978ea", size = 8380 }, +] + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mergedeep" }, + { name = "platformdirs" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521 }, +] + +[[package]] +name = "mkdocs-literate-nav" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/f9/c48a04f3cf484f8016a343c1d7d99c3a1ef01dbb33ceabb1d02e0ecabda7/mkdocs_literate_nav-0.6.1.tar.gz", hash = "sha256:78a7ab6d878371728acb0cdc6235c9b0ffc6e83c997b037f4a5c6ff7cef7d759", size = 16437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/3b/e00d839d3242844c77e248f9572dd34644a04300839a60fe7d6bf652ab19/mkdocs_literate_nav-0.6.1-py3-none-any.whl", hash = "sha256:e70bdc4a07050d32da79c0b697bd88e9a104cf3294282e9cb20eec94c6b0f401", size = 13182 }, +] + +[[package]] +name = "mkdocs-material" +version = "9.5.49" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "colorama" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "mkdocs" }, + { name = "mkdocs-material-extensions" }, + { name = "paginate" }, + { name = "pygments" }, + { name = "pymdown-extensions" }, + { name = "regex" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e2/14/8daeeecee2e25bd84239a843fdcb92b20db88ebbcb26e0d32f414ca54a22/mkdocs_material-9.5.49.tar.gz", hash = "sha256:3671bb282b4f53a1c72e08adbe04d2481a98f85fed392530051f80ff94a9621d", size = 3949559 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/2d/2dd23a36b48421db54f118bb6f6f733dbe2d5c78fe7867375e48649fd3df/mkdocs_material-9.5.49-py3-none-any.whl", hash = "sha256:c3c2d8176b18198435d3a3e119011922f3e11424074645c24019c2dcf08a360e", size = 8684098 }, +] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728 }, +] + +[[package]] +name = "mkdocstrings" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mkdocs" }, + { name = "mkdocs-autorefs" }, + { name = "platformdirs" }, + { name = "pymdown-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e2/5a/5de70538c2cefae7ac3a15b5601e306ef3717290cb2aab11d51cbbc2d1c0/mkdocstrings-0.27.0.tar.gz", hash = "sha256:16adca6d6b0a1f9e0c07ff0b02ced8e16f228a9d65a37c063ec4c14d7b76a657", size = 94830 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/10/4c27c3063c2b3681a4b7942f8dbdeb4fa34fecb2c19b594e7345ebf4f86f/mkdocstrings-0.27.0-py3-none-any.whl", hash = "sha256:6ceaa7ea830770959b55a16203ac63da24badd71325b96af950e59fd37366332", size = 30658 }, +] + +[package.optional-dependencies] +python = [ + { name = "mkdocstrings-python" }, +] + +[[package]] +name = "mkdocstrings-python" +version = "1.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "griffe" }, + { name = "mkdocs-autorefs" }, + { name = "mkdocstrings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/ae/32703e35d74040051c672400fd9f5f2b48a6ea094f5071dd8a0e3be35322/mkdocstrings_python-1.13.0.tar.gz", hash = "sha256:2dbd5757e8375b9720e81db16f52f1856bf59905428fd7ef88005d1370e2f64c", size = 185697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/23/d02d86553327296c3bf369d444194ea83410cce8f0e690565264f37f3261/mkdocstrings_python-1.13.0-py3-none-any.whl", hash = "sha256:b88bbb207bab4086434743849f8e796788b373bd32e7bfefbf8560ac45d88f97", size = 112254 }, +] + +[[package]] +name = "more-itertools" +version = "10.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/78/65922308c4248e0eb08ebcbe67c95d48615cc6f27854b6f2e57143e9178f/more-itertools-10.5.0.tar.gz", hash = "sha256:5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6", size = 121020 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/7e/3a64597054a70f7c86eb0a7d4fc315b8c1ab932f64883a297bdffeb5f967/more_itertools-10.5.0-py3-none-any.whl", hash = "sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef", size = 60952 }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198 }, +] + +[[package]] +name = "multipledispatch" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/3e/a62c3b824c7dec33c4a1578bcc842e6c30300051033a4e5975ed86cc2536/multipledispatch-1.0.0.tar.gz", hash = "sha256:5c839915465c68206c3e9c473357908216c28383b425361e5d144594bf85a7e0", size = 12385 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/c0/00c9809d8b9346eb238a6bbd5f83e846a4ce4503da94a4c08cb7284c325b/multipledispatch-1.0.0-py3-none-any.whl", hash = "sha256:0c53cd8b077546da4e48869f49b13164bebafd0c2a5afceb6bb6a316e7fb46e4", size = 12818 }, +] + +[[package]] +name = "mypy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8c/7b/08046ef9330735f536a09a2e31b00f42bccdb2795dcd979636ba43bb2d63/mypy-1.14.0.tar.gz", hash = "sha256:822dbd184d4a9804df5a7d5335a68cf7662930e70b8c1bc976645d1509f9a9d6", size = 3215684 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/97/f00ded038482230e0beaaa08f9c5483a54530b362ad1b0d752d5d2b2f211/mypy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e971c1c667007f9f2b397ffa80fa8e1e0adccff336e5e77e74cb5f22868bee87", size = 11207956 }, + { url = "https://files.pythonhosted.org/packages/68/67/8b4db0da19c9e3fa6264e948f1c135ab4dd45bede1809f4fdb613dc119f6/mypy-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e86aaeaa3221a278c66d3d673b297232947d873773d61ca3ee0e28b2ff027179", size = 10363681 }, + { url = "https://files.pythonhosted.org/packages/f5/00/56b1619ff1f3fcad2d411eccda60d74d20e73bda39c218d5ad2769980682/mypy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1628c5c3ce823d296e41e2984ff88c5861499041cb416a8809615d0c1f41740e", size = 12832976 }, + { url = "https://files.pythonhosted.org/packages/e7/8b/9247838774b0bd865f190cc221822212091317f16310305ef924d9772532/mypy-1.14.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7fadb29b77fc14a0dd81304ed73c828c3e5cde0016c7e668a86a3e0dfc9f3af3", size = 13013704 }, + { url = "https://files.pythonhosted.org/packages/b2/69/0c0868a6f3d9761d2f704d1fb6ef84d75998c27d342738a8b20f109a411f/mypy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:3fa76988dc760da377c1e5069200a50d9eaaccf34f4ea18428a3337034ab5a44", size = 9782230 }, + { url = "https://files.pythonhosted.org/packages/34/c1/b9dd3e955953aec1c728992545b7877c9f6fa742a623ce4c200da0f62540/mypy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6e73c8a154eed31db3445fe28f63ad2d97b674b911c00191416cf7f6459fd49a", size = 11121032 }, + { url = "https://files.pythonhosted.org/packages/ee/96/c52d5d516819ab95bf41f4a1ada828a3decc302f8c152ff4fc5feb0e4529/mypy-1.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:273e70fcb2e38c5405a188425aa60b984ffdcef65d6c746ea5813024b68c73dc", size = 10286294 }, + { url = "https://files.pythonhosted.org/packages/69/2c/3dbe51877a24daa467f8d8631f9ffd1aabbf0f6d9367a01c44a59df81fe0/mypy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1daca283d732943731a6a9f20fdbcaa927f160bc51602b1d4ef880a6fb252015", size = 12746528 }, + { url = "https://files.pythonhosted.org/packages/a1/a8/eb20cde4ba9c4c3e20d958918a7c5d92210f4d1a0200c27de9a641f70996/mypy-1.14.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7e68047bedb04c1c25bba9901ea46ff60d5eaac2d71b1f2161f33107e2b368eb", size = 12883489 }, + { url = "https://files.pythonhosted.org/packages/91/17/a1fc6c70f31d52c99299320cf81c3cb2c6b91ec7269414e0718a6d138e34/mypy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:7a52f26b9c9b1664a60d87675f3bae00b5c7f2806e0c2800545a32c325920bcc", size = 9780113 }, + { url = "https://files.pythonhosted.org/packages/fe/d8/0e72175ee0253217f5c44524f5e95251c02e95ba9749fb87b0e2074d203a/mypy-1.14.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d5326ab70a6db8e856d59ad4cb72741124950cbbf32e7b70e30166ba7bbf61dd", size = 11269011 }, + { url = "https://files.pythonhosted.org/packages/e9/6d/4ea13839dabe5db588dc6a1b766da16f420d33cf118a7b7172cdf6c7fcb2/mypy-1.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf4ec4980bec1e0e24e5075f449d014011527ae0055884c7e3abc6a99cd2c7f1", size = 10253076 }, + { url = "https://files.pythonhosted.org/packages/3e/38/7db2c5d0f4d290e998f7a52b2e2616c7bbad96b8e04278ab09d11978a29e/mypy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:390dfb898239c25289495500f12fa73aa7f24a4c6d90ccdc165762462b998d63", size = 12862786 }, + { url = "https://files.pythonhosted.org/packages/bf/4b/62d59c801b34141040989949c2b5c157d0408b45357335d3ec5b2845b0f6/mypy-1.14.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7e026d55ddcd76e29e87865c08cbe2d0104e2b3153a523c529de584759379d3d", size = 12971568 }, + { url = "https://files.pythonhosted.org/packages/f1/9c/e0f281b32d70c87b9e4d2939e302b1ff77ada4d7b0f2fb32890c144bc1d6/mypy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:585ed36031d0b3ee362e5107ef449a8b5dfd4e9c90ccbe36414ee405ee6b32ba", size = 9879477 }, + { url = "https://files.pythonhosted.org/packages/39/32/0214608af400cdf8f5102144bb8af10d880675c65ed0b58f7e0e77175d50/mypy-1.14.0-py3-none-any.whl", hash = "sha256:2238d7f93fc4027ed1efc944507683df3ba406445a2b6c96e79666a045aadfab", size = 2752803 }, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, +] + +[[package]] +name = "networkx" +version = "2.8.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/16/c44e8550012735b8f21b3df7f39e8ba5a987fb764ac017ad5f3589735889/networkx-2.8.8.tar.gz", hash = "sha256:230d388117af870fce5647a3c52401fcf753e94720e6ea6b4197a5355648885e", size = 1960828 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/31/d2f89f1ae42718f8c8a9e440ebe38d7d5fe1e0d9eb9178ce779e365b3ab0/networkx-2.8.8-py3-none-any.whl", hash = "sha256:e435dfa75b1d7195c7b8378c3859f0445cd88c6b0375c181ed66823a9ceb7524", size = 2025192 }, +] + +[[package]] +name = "neural-pipeline-search" +version = "0.12.2" +source = { editable = "." } +dependencies = [ + { name = "botorch" }, + { name = "configspace" }, + { name = "gpytorch" }, + { name = "grakel" }, + { name = "ifbo" }, + { name = "matplotlib" }, + { name = "more-itertools" }, + { name = "networkx" }, + { name = "nltk" }, + { name = "numpy" }, + { name = "pandas" }, + { name = "portalocker" }, + { name = "pyyaml" }, + { name = "scipy" }, + { name = "seaborn" }, + { name = "tensorboard" }, + { name = "torch" }, + { name = "torchvision" }, + { name = "typing-extensions" }, +] + +[package.optional-dependencies] +dev = [ + { name = "black" }, + { name = "mike" }, + { name = "mkdocs-autorefs" }, + { name = "mkdocs-gen-files" }, + { name = "mkdocs-literate-nav" }, + { name = "mkdocs-material" }, + { name = "mkdocstrings", extra = ["python"] }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-cases" }, + { name = "ruff" }, + { name = "types-pyyaml" }, +] + +[package.metadata] +requires-dist = [ + { name = "black", marker = "extra == 'dev'" }, + { name = "botorch", specifier = ">=0.12" }, + { name = "configspace", specifier = ">=0.7,<1.0" }, + { name = "gpytorch", specifier = "==1.13.0" }, + { name = "grakel", specifier = ">=0.1,<0.2" }, + { name = "ifbo", specifier = ">=0.3.10" }, + { name = "matplotlib", specifier = ">=3.0,<4.0" }, + { name = "mike", marker = "extra == 'dev'" }, + { name = "mkdocs-autorefs", marker = "extra == 'dev'" }, + { name = "mkdocs-gen-files", marker = "extra == 'dev'" }, + { name = "mkdocs-literate-nav", marker = "extra == 'dev'" }, + { name = "mkdocs-material", marker = "extra == 'dev'" }, + { name = "mkdocstrings", extras = ["python"], marker = "extra == 'dev'" }, + { name = "more-itertools" }, + { name = "mypy", marker = "extra == 'dev'", specifier = ">=1,<2" }, + { name = "networkx", specifier = ">=2.6.3,<3.0" }, + { name = "nltk", specifier = ">=3.6.4,<4.0" }, + { name = "numpy", specifier = ">=1.0,<2.0" }, + { name = "pandas", specifier = ">=2.0,<3.0" }, + { name = "portalocker", specifier = ">=2.0,<3.0" }, + { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=3,<4" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=7,<8" }, + { name = "pytest-cases", marker = "extra == 'dev'", specifier = ">=3,<4" }, + { name = "pyyaml", specifier = ">=6.0,<7.0" }, + { name = "ruff", marker = "extra == 'dev'" }, + { name = "scipy", specifier = ">=1.13.1" }, + { name = "seaborn", specifier = ">=0.13,<0.14" }, + { name = "tensorboard", specifier = ">=2.0,<3.0" }, + { name = "torch", specifier = ">=2.0.1" }, + { name = "torchvision", specifier = ">=0.8.0" }, + { name = "types-pyyaml", marker = "extra == 'dev'", specifier = ">=6,<7" }, + { name = "typing-extensions" }, +] + +[[package]] +name = "nltk" +version = "3.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "joblib" }, + { name = "regex" }, + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3c/87/db8be88ad32c2d042420b6fd9ffd4a149f9a0d7f0e86b3f543be2eeeedd2/nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868", size = 2904691 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/66/7d9e26593edda06e8cb531874633f7c2372279c3b0f46235539fe546df8b/nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1", size = 1505442 }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + +[[package]] +name = "numpy" +version = "1.26.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/94/ace0fdea5241a27d13543ee117cbc65868e82213fb31a8eb7fe9ff23f313/numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", size = 20631468 }, + { url = "https://files.pythonhosted.org/packages/20/f7/b24208eba89f9d1b58c1668bc6c8c4fd472b20c45573cb767f59d49fb0f6/numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", size = 13966411 }, + { url = "https://files.pythonhosted.org/packages/fc/a5/4beee6488160798683eed5bdb7eead455892c3b4e1f78d79d8d3f3b084ac/numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", size = 14219016 }, + { url = "https://files.pythonhosted.org/packages/4b/d7/ecf66c1cd12dc28b4040b15ab4d17b773b87fa9d29ca16125de01adb36cd/numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f", size = 18240889 }, + { url = "https://files.pythonhosted.org/packages/24/03/6f229fe3187546435c4f6f89f6d26c129d4f5bed40552899fcf1f0bf9e50/numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", size = 13876746 }, + { url = "https://files.pythonhosted.org/packages/39/fe/39ada9b094f01f5a35486577c848fe274e374bbf8d8f472e1423a0bbd26d/numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", size = 18078620 }, + { url = "https://files.pythonhosted.org/packages/d5/ef/6ad11d51197aad206a9ad2286dc1aac6a378059e06e8cf22cd08ed4f20dc/numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", size = 5972659 }, + { url = "https://files.pythonhosted.org/packages/19/77/538f202862b9183f54108557bfda67e17603fc560c384559e769321c9d92/numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", size = 15808905 }, + { url = "https://files.pythonhosted.org/packages/11/57/baae43d14fe163fa0e4c47f307b6b2511ab8d7d30177c491960504252053/numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", size = 20630554 }, + { url = "https://files.pythonhosted.org/packages/1a/2e/151484f49fd03944c4a3ad9c418ed193cfd02724e138ac8a9505d056c582/numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", size = 13997127 }, + { url = "https://files.pythonhosted.org/packages/79/ae/7e5b85136806f9dadf4878bf73cf223fe5c2636818ba3ab1c585d0403164/numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", size = 14222994 }, + { url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", size = 18252005 }, + { url = "https://files.pythonhosted.org/packages/09/bf/2b1aaf8f525f2923ff6cfcf134ae5e750e279ac65ebf386c75a0cf6da06a/numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", size = 13885297 }, + { url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", size = 18093567 }, + { url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", size = 5968812 }, + { url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", size = 15811913 }, + { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901 }, + { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868 }, + { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109 }, + { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613 }, + { url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172 }, + { url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643 }, + { url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803 }, + { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754 }, +] + +[[package]] +name = "nvidia-cublas-cu12" +version = "12.4.5.8" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/7f/7fbae15a3982dc9595e49ce0f19332423b260045d0a6afe93cdbe2f1f624/nvidia_cublas_cu12-12.4.5.8-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0f8aa1706812e00b9f19dfe0cdb3999b092ccb8ca168c0db5b8ea712456fd9b3", size = 363333771 }, + { url = "https://files.pythonhosted.org/packages/ae/71/1c91302526c45ab494c23f61c7a84aa568b8c1f9d196efa5993957faf906/nvidia_cublas_cu12-12.4.5.8-py3-none-manylinux2014_x86_64.whl", hash = "sha256:2fc8da60df463fdefa81e323eef2e36489e1c94335b5358bcb38360adf75ac9b", size = 363438805 }, +] + +[[package]] +name = "nvidia-cuda-cupti-cu12" +version = "12.4.127" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/b5/9fb3d00386d3361b03874246190dfec7b206fd74e6e287b26a8fcb359d95/nvidia_cuda_cupti_cu12-12.4.127-py3-none-manylinux2014_aarch64.whl", hash = "sha256:79279b35cf6f91da114182a5ce1864997fd52294a87a16179ce275773799458a", size = 12354556 }, + { url = "https://files.pythonhosted.org/packages/67/42/f4f60238e8194a3106d06a058d494b18e006c10bb2b915655bd9f6ea4cb1/nvidia_cuda_cupti_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:9dec60f5ac126f7bb551c055072b69d85392b13311fcc1bcda2202d172df30fb", size = 13813957 }, +] + +[[package]] +name = "nvidia-cuda-nvrtc-cu12" +version = "12.4.127" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/aa/083b01c427e963ad0b314040565ea396f914349914c298556484f799e61b/nvidia_cuda_nvrtc_cu12-12.4.127-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0eedf14185e04b76aa05b1fea04133e59f465b6f960c0cbf4e37c3cb6b0ea198", size = 24133372 }, + { url = "https://files.pythonhosted.org/packages/2c/14/91ae57cd4db3f9ef7aa99f4019cfa8d54cb4caa7e00975df6467e9725a9f/nvidia_cuda_nvrtc_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a178759ebb095827bd30ef56598ec182b85547f1508941a3d560eb7ea1fbf338", size = 24640306 }, +] + +[[package]] +name = "nvidia-cuda-runtime-cu12" +version = "12.4.127" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/aa/b656d755f474e2084971e9a297def515938d56b466ab39624012070cb773/nvidia_cuda_runtime_cu12-12.4.127-py3-none-manylinux2014_aarch64.whl", hash = "sha256:961fe0e2e716a2a1d967aab7caee97512f71767f852f67432d572e36cb3a11f3", size = 894177 }, + { url = "https://files.pythonhosted.org/packages/ea/27/1795d86fe88ef397885f2e580ac37628ed058a92ed2c39dc8eac3adf0619/nvidia_cuda_runtime_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:64403288fa2136ee8e467cdc9c9427e0434110899d07c779f25b5c068934faa5", size = 883737 }, +] + +[[package]] +name = "nvidia-cudnn-cu12" +version = "9.1.0.70" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/fd/713452cd72343f682b1c7b9321e23829f00b842ceaedcda96e742ea0b0b3/nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl", hash = "sha256:165764f44ef8c61fcdfdfdbe769d687e06374059fbb388b6c89ecb0e28793a6f", size = 664752741 }, +] + +[[package]] +name = "nvidia-cufft-cu12" +version = "11.2.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/8a/0e728f749baca3fbeffad762738276e5df60851958be7783af121a7221e7/nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:5dad8008fc7f92f5ddfa2101430917ce2ffacd86824914c82e28990ad7f00399", size = 211422548 }, + { url = "https://files.pythonhosted.org/packages/27/94/3266821f65b92b3138631e9c8e7fe1fb513804ac934485a8d05776e1dd43/nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f083fc24912aa410be21fa16d157fed2055dab1cc4b6934a0e03cba69eb242b9", size = 211459117 }, +] + +[[package]] +name = "nvidia-curand-cu12" +version = "10.3.5.147" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/9c/a79180e4d70995fdf030c6946991d0171555c6edf95c265c6b2bf7011112/nvidia_curand_cu12-10.3.5.147-py3-none-manylinux2014_aarch64.whl", hash = "sha256:1f173f09e3e3c76ab084aba0de819c49e56614feae5c12f69883f4ae9bb5fad9", size = 56314811 }, + { url = "https://files.pythonhosted.org/packages/8a/6d/44ad094874c6f1b9c654f8ed939590bdc408349f137f9b98a3a23ccec411/nvidia_curand_cu12-10.3.5.147-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a88f583d4e0bb643c49743469964103aa59f7f708d862c3ddb0fc07f851e3b8b", size = 56305206 }, +] + +[[package]] +name = "nvidia-cusolver-cu12" +version = "11.6.1.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12" }, + { name = "nvidia-cusparse-cu12" }, + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/6b/a5c33cf16af09166845345275c34ad2190944bcc6026797a39f8e0a282e0/nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_aarch64.whl", hash = "sha256:d338f155f174f90724bbde3758b7ac375a70ce8e706d70b018dd3375545fc84e", size = 127634111 }, + { url = "https://files.pythonhosted.org/packages/3a/e1/5b9089a4b2a4790dfdea8b3a006052cfecff58139d5a4e34cb1a51df8d6f/nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_x86_64.whl", hash = "sha256:19e33fa442bcfd085b3086c4ebf7e8debc07cfe01e11513cc6d332fd918ac260", size = 127936057 }, +] + +[[package]] +name = "nvidia-cusparse-cu12" +version = "12.3.1.170" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/96/a9/c0d2f83a53d40a4a41be14cea6a0bf9e668ffcf8b004bd65633f433050c0/nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_aarch64.whl", hash = "sha256:9d32f62896231ebe0480efd8a7f702e143c98cfaa0e8a76df3386c1ba2b54df3", size = 207381987 }, + { url = "https://files.pythonhosted.org/packages/db/f7/97a9ea26ed4bbbfc2d470994b8b4f338ef663be97b8f677519ac195e113d/nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ea4f11a2904e2a8dc4b1833cc1b5181cde564edd0d5cd33e3c168eff2d1863f1", size = 207454763 }, +] + +[[package]] +name = "nvidia-nccl-cu12" +version = "2.21.5" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/99/12cd266d6233f47d00daf3a72739872bdc10267d0383508b0b9c84a18bb6/nvidia_nccl_cu12-2.21.5-py3-none-manylinux2014_x86_64.whl", hash = "sha256:8579076d30a8c24988834445f8d633c697d42397e92ffc3f63fa26766d25e0a0", size = 188654414 }, +] + +[[package]] +name = "nvidia-nvjitlink-cu12" +version = "12.4.127" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/45/239d52c05074898a80a900f49b1615d81c07fceadd5ad6c4f86a987c0bc4/nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_aarch64.whl", hash = "sha256:4abe7fef64914ccfa909bc2ba39739670ecc9e820c83ccc7a6ed414122599b83", size = 20552510 }, + { url = "https://files.pythonhosted.org/packages/ff/ff/847841bacfbefc97a00036e0fce5a0f086b640756dc38caea5e1bb002655/nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:06b3b9b25bf3f8af351d664978ca26a16d2c5127dbd53c0497e28d1fb9611d57", size = 21066810 }, +] + +[[package]] +name = "nvidia-nvtx-cu12" +version = "12.4.127" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/39/471f581edbb7804b39e8063d92fc8305bdc7a80ae5c07dbe6ea5c50d14a5/nvidia_nvtx_cu12-12.4.127-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7959ad635db13edf4fc65c06a6e9f9e55fc2f92596db928d169c0bb031e88ef3", size = 100417 }, + { url = "https://files.pythonhosted.org/packages/87/20/199b8713428322a2f22b722c62b8cc278cc53dffa9705d744484b5035ee9/nvidia_nvtx_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:781e950d9b9f60d8241ccea575b32f5105a5baf4c2351cab5256a24869f12a1a", size = 99144 }, +] + +[[package]] +name = "opt-einsum" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/b9/2ac072041e899a52f20cf9510850ff58295003aa75525e58343591b0cbfb/opt_einsum-3.4.0.tar.gz", hash = "sha256:96ca72f1b886d148241348783498194c577fa30a8faac108586b14f1ba4473ac", size = 63004 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/cd/066e86230ae37ed0be70aae89aabf03ca8d9f39c8aea0dec8029455b5540/opt_einsum-3.4.0-py3-none-any.whl", hash = "sha256:69bb92469f86a1565195ece4ac0323943e83477171b91d24c35afe028a90d7cd", size = 71932 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "paginate" +version = "0.5.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746 }, +] + +[[package]] +name = "pandas" +version = "2.2.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9c/d6/9f8431bacc2e19dca897724cd097b1bb224a6ad5433784a44b587c7c13af/pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667", size = 4399213 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/70/c853aec59839bceed032d52010ff5f1b8d87dc3114b762e4ba2727661a3b/pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5", size = 12580827 }, + { url = "https://files.pythonhosted.org/packages/99/f2/c4527768739ffa4469b2b4fff05aa3768a478aed89a2f271a79a40eee984/pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348", size = 11303897 }, + { url = "https://files.pythonhosted.org/packages/ed/12/86c1747ea27989d7a4064f806ce2bae2c6d575b950be087837bdfcabacc9/pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed", size = 66480908 }, + { url = "https://files.pythonhosted.org/packages/44/50/7db2cd5e6373ae796f0ddad3675268c8d59fb6076e66f0c339d61cea886b/pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57", size = 13064210 }, + { url = "https://files.pythonhosted.org/packages/61/61/a89015a6d5536cb0d6c3ba02cebed51a95538cf83472975275e28ebf7d0c/pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42", size = 16754292 }, + { url = "https://files.pythonhosted.org/packages/ce/0d/4cc7b69ce37fac07645a94e1d4b0880b15999494372c1523508511b09e40/pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f", size = 14416379 }, + { url = "https://files.pythonhosted.org/packages/31/9e/6ebb433de864a6cd45716af52a4d7a8c3c9aaf3a98368e61db9e69e69a9c/pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645", size = 11598471 }, + { url = "https://files.pythonhosted.org/packages/a8/44/d9502bf0ed197ba9bf1103c9867d5904ddcaf869e52329787fc54ed70cc8/pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039", size = 12602222 }, + { url = "https://files.pythonhosted.org/packages/52/11/9eac327a38834f162b8250aab32a6781339c69afe7574368fffe46387edf/pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd", size = 11321274 }, + { url = "https://files.pythonhosted.org/packages/45/fb/c4beeb084718598ba19aa9f5abbc8aed8b42f90930da861fcb1acdb54c3a/pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698", size = 15579836 }, + { url = "https://files.pythonhosted.org/packages/cd/5f/4dba1d39bb9c38d574a9a22548c540177f78ea47b32f99c0ff2ec499fac5/pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc", size = 13058505 }, + { url = "https://files.pythonhosted.org/packages/b9/57/708135b90391995361636634df1f1130d03ba456e95bcf576fada459115a/pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3", size = 16744420 }, + { url = "https://files.pythonhosted.org/packages/86/4a/03ed6b7ee323cf30404265c284cee9c65c56a212e0a08d9ee06984ba2240/pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32", size = 14440457 }, + { url = "https://files.pythonhosted.org/packages/ed/8c/87ddf1fcb55d11f9f847e3c69bb1c6f8e46e2f40ab1a2d2abadb2401b007/pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5", size = 11617166 }, + { url = "https://files.pythonhosted.org/packages/17/a3/fb2734118db0af37ea7433f57f722c0a56687e14b14690edff0cdb4b7e58/pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9", size = 12529893 }, + { url = "https://files.pythonhosted.org/packages/e1/0c/ad295fd74bfac85358fd579e271cded3ac969de81f62dd0142c426b9da91/pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4", size = 11363475 }, + { url = "https://files.pythonhosted.org/packages/c6/2a/4bba3f03f7d07207481fed47f5b35f556c7441acddc368ec43d6643c5777/pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3", size = 15188645 }, + { url = "https://files.pythonhosted.org/packages/38/f8/d8fddee9ed0d0c0f4a2132c1dfcf0e3e53265055da8df952a53e7eaf178c/pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319", size = 12739445 }, + { url = "https://files.pythonhosted.org/packages/20/e8/45a05d9c39d2cea61ab175dbe6a2de1d05b679e8de2011da4ee190d7e748/pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8", size = 16359235 }, + { url = "https://files.pythonhosted.org/packages/1d/99/617d07a6a5e429ff90c90da64d428516605a1ec7d7bea494235e1c3882de/pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a", size = 14056756 }, + { url = "https://files.pythonhosted.org/packages/29/d4/1244ab8edf173a10fd601f7e13b9566c1b525c4f365d6bee918e68381889/pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", size = 11504248 }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, +] + +[[package]] +name = "pillow" +version = "11.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/26/0d95c04c868f6bdb0c447e3ee2de5564411845e36a858cfd63766bc7b563/pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739", size = 46737780 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/fb/a6ce6836bd7fd93fbf9144bf54789e02babc27403b50a9e1583ee877d6da/pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947", size = 3154708 }, + { url = "https://files.pythonhosted.org/packages/6a/1d/1f51e6e912d8ff316bb3935a8cda617c801783e0b998bf7a894e91d3bd4c/pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba", size = 2979223 }, + { url = "https://files.pythonhosted.org/packages/90/83/e2077b0192ca8a9ef794dbb74700c7e48384706467067976c2a95a0f40a1/pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086", size = 4183167 }, + { url = "https://files.pythonhosted.org/packages/0e/74/467af0146970a98349cdf39e9b79a6cc8a2e7558f2c01c28a7b6b85c5bda/pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9", size = 4283912 }, + { url = "https://files.pythonhosted.org/packages/85/b1/d95d4f7ca3a6c1ae120959605875a31a3c209c4e50f0029dc1a87566cf46/pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488", size = 4195815 }, + { url = "https://files.pythonhosted.org/packages/41/c3/94f33af0762ed76b5a237c5797e088aa57f2b7fa8ee7932d399087be66a8/pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f", size = 4366117 }, + { url = "https://files.pythonhosted.org/packages/ba/3c/443e7ef01f597497268899e1cca95c0de947c9bbf77a8f18b3c126681e5d/pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb", size = 4278607 }, + { url = "https://files.pythonhosted.org/packages/26/95/1495304448b0081e60c0c5d63f928ef48bb290acee7385804426fa395a21/pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97", size = 4410685 }, + { url = "https://files.pythonhosted.org/packages/45/da/861e1df971ef0de9870720cb309ca4d553b26a9483ec9be3a7bf1de4a095/pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50", size = 2249185 }, + { url = "https://files.pythonhosted.org/packages/d5/4e/78f7c5202ea2a772a5ab05069c1b82503e6353cd79c7e474d4945f4b82c3/pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c", size = 2566726 }, + { url = "https://files.pythonhosted.org/packages/77/e4/6e84eada35cbcc646fc1870f72ccfd4afacb0fae0c37ffbffe7f5dc24bf1/pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1", size = 2254585 }, + { url = "https://files.pythonhosted.org/packages/f0/eb/f7e21b113dd48a9c97d364e0915b3988c6a0b6207652f5a92372871b7aa4/pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc", size = 3154705 }, + { url = "https://files.pythonhosted.org/packages/25/b3/2b54a1d541accebe6bd8b1358b34ceb2c509f51cb7dcda8687362490da5b/pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a", size = 2979222 }, + { url = "https://files.pythonhosted.org/packages/20/12/1a41eddad8265c5c19dda8fb6c269ce15ee25e0b9f8f26286e6202df6693/pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3", size = 4190220 }, + { url = "https://files.pythonhosted.org/packages/a9/9b/8a8c4d07d77447b7457164b861d18f5a31ae6418ef5c07f6f878fa09039a/pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5", size = 4291399 }, + { url = "https://files.pythonhosted.org/packages/fc/e4/130c5fab4a54d3991129800dd2801feeb4b118d7630148cd67f0e6269d4c/pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b", size = 4202709 }, + { url = "https://files.pythonhosted.org/packages/39/63/b3fc299528d7df1f678b0666002b37affe6b8751225c3d9c12cf530e73ed/pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa", size = 4372556 }, + { url = "https://files.pythonhosted.org/packages/c6/a6/694122c55b855b586c26c694937d36bb8d3b09c735ff41b2f315c6e66a10/pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306", size = 4287187 }, + { url = "https://files.pythonhosted.org/packages/ba/a9/f9d763e2671a8acd53d29b1e284ca298bc10a595527f6be30233cdb9659d/pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9", size = 4418468 }, + { url = "https://files.pythonhosted.org/packages/6e/0e/b5cbad2621377f11313a94aeb44ca55a9639adabcaaa073597a1925f8c26/pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5", size = 2249249 }, + { url = "https://files.pythonhosted.org/packages/dc/83/1470c220a4ff06cd75fc609068f6605e567ea51df70557555c2ab6516b2c/pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291", size = 2566769 }, + { url = "https://files.pythonhosted.org/packages/52/98/def78c3a23acee2bcdb2e52005fb2810ed54305602ec1bfcfab2bda6f49f/pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9", size = 2254611 }, + { url = "https://files.pythonhosted.org/packages/1c/a3/26e606ff0b2daaf120543e537311fa3ae2eb6bf061490e4fea51771540be/pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923", size = 3147642 }, + { url = "https://files.pythonhosted.org/packages/4f/d5/1caabedd8863526a6cfa44ee7a833bd97f945dc1d56824d6d76e11731939/pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903", size = 2978999 }, + { url = "https://files.pythonhosted.org/packages/d9/ff/5a45000826a1aa1ac6874b3ec5a856474821a1b59d838c4f6ce2ee518fe9/pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4", size = 4196794 }, + { url = "https://files.pythonhosted.org/packages/9d/21/84c9f287d17180f26263b5f5c8fb201de0f88b1afddf8a2597a5c9fe787f/pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f", size = 4300762 }, + { url = "https://files.pythonhosted.org/packages/84/39/63fb87cd07cc541438b448b1fed467c4d687ad18aa786a7f8e67b255d1aa/pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9", size = 4210468 }, + { url = "https://files.pythonhosted.org/packages/7f/42/6e0f2c2d5c60f499aa29be14f860dd4539de322cd8fb84ee01553493fb4d/pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7", size = 4381824 }, + { url = "https://files.pythonhosted.org/packages/31/69/1ef0fb9d2f8d2d114db982b78ca4eeb9db9a29f7477821e160b8c1253f67/pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6", size = 4296436 }, + { url = "https://files.pythonhosted.org/packages/44/ea/dad2818c675c44f6012289a7c4f46068c548768bc6c7f4e8c4ae5bbbc811/pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc", size = 4429714 }, + { url = "https://files.pythonhosted.org/packages/af/3a/da80224a6eb15bba7a0dcb2346e2b686bb9bf98378c0b4353cd88e62b171/pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6", size = 2249631 }, + { url = "https://files.pythonhosted.org/packages/57/97/73f756c338c1d86bb802ee88c3cab015ad7ce4b838f8a24f16b676b1ac7c/pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47", size = 2567533 }, + { url = "https://files.pythonhosted.org/packages/0b/30/2b61876e2722374558b871dfbfcbe4e406626d63f4f6ed92e9c8e24cac37/pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25", size = 2254890 }, + { url = "https://files.pythonhosted.org/packages/36/57/42a4dd825eab762ba9e690d696d894ba366e06791936056e26e099398cda/pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2", size = 3119239 }, + { url = "https://files.pythonhosted.org/packages/98/f7/25f9f9e368226a1d6cf3507081a1a7944eddd3ca7821023377043f5a83c8/pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2", size = 2950803 }, + { url = "https://files.pythonhosted.org/packages/59/01/98ead48a6c2e31e6185d4c16c978a67fe3ccb5da5c2ff2ba8475379bb693/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b", size = 3281098 }, + { url = "https://files.pythonhosted.org/packages/51/c0/570255b2866a0e4d500a14f950803a2ec273bac7badc43320120b9262450/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2", size = 3323665 }, + { url = "https://files.pythonhosted.org/packages/0e/75/689b4ec0483c42bfc7d1aacd32ade7a226db4f4fac57c6fdcdf90c0731e3/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830", size = 3310533 }, + { url = "https://files.pythonhosted.org/packages/3d/30/38bd6149cf53da1db4bad304c543ade775d225961c4310f30425995cb9ec/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734", size = 3414886 }, + { url = "https://files.pythonhosted.org/packages/ec/3d/c32a51d848401bd94cabb8767a39621496491ee7cd5199856b77da9b18ad/pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316", size = 2567508 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "portalocker" +version = "2.10.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywin32", marker = "platform_system == 'Windows'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ed/d3/c6c64067759e87af98cc668c1cc75171347d0f1577fab7ca3749134e3cd4/portalocker-2.10.1.tar.gz", hash = "sha256:ef1bf844e878ab08aee7e40184156e1151f228f103aa5c6bd0724cc330960f8f", size = 40891 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/fb/a70a4214956182e0d7a9099ab17d50bfcba1056188e9b14f35b9e2b62a0d/portalocker-2.10.1-py3-none-any.whl", hash = "sha256:53a5984ebc86a025552264b459b46a2086e269b21823cb572f8f28ee759e45bf", size = 18423 }, +] + +[[package]] +name = "pre-commit" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/10/97ee2fa54dff1e9da9badbc5e35d0bbaef0776271ea5907eccf64140f72f/pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af", size = 177815 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/92/caae8c86e94681b42c246f0bca35c059a2f0529e5b92619f6aba4cf7e7b6/pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f", size = 204643 }, +] + +[[package]] +name = "protobuf" +version = "5.29.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/73/4e6295c1420a9d20c9c351db3a36109b4c9aa601916cb7c6871e3196a1ca/protobuf-5.29.2.tar.gz", hash = "sha256:b2cc8e8bb7c9326996f0e160137b0861f1a82162502658df2951209d0cb0309e", size = 424901 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/42/6db5387124708d619ffb990a846fb123bee546f52868039f8fa964c5bc54/protobuf-5.29.2-cp310-abi3-win32.whl", hash = "sha256:c12ba8249f5624300cf51c3d0bfe5be71a60c63e4dcf51ffe9a68771d958c851", size = 422697 }, + { url = "https://files.pythonhosted.org/packages/6c/38/2fcc968b377b531882d6ab2ac99b10ca6d00108394f6ff57c2395fb7baff/protobuf-5.29.2-cp310-abi3-win_amd64.whl", hash = "sha256:842de6d9241134a973aab719ab42b008a18a90f9f07f06ba480df268f86432f9", size = 434495 }, + { url = "https://files.pythonhosted.org/packages/cb/26/41debe0f6615fcb7e97672057524687ed86fcd85e3da3f031c30af8f0c51/protobuf-5.29.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a0c53d78383c851bfa97eb42e3703aefdc96d2036a41482ffd55dc5f529466eb", size = 417812 }, + { url = "https://files.pythonhosted.org/packages/e4/20/38fc33b60dcfb380507b99494aebe8c34b68b8ac7d32808c4cebda3f6f6b/protobuf-5.29.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:494229ecd8c9009dd71eda5fd57528395d1eacdf307dbece6c12ad0dd09e912e", size = 319562 }, + { url = "https://files.pythonhosted.org/packages/90/4d/c3d61e698e0e41d926dbff6aa4e57428ab1a6fc3b5e1deaa6c9ec0fd45cf/protobuf-5.29.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:b6b0d416bbbb9d4fbf9d0561dbfc4e324fd522f61f7af0fe0f282ab67b22477e", size = 319662 }, + { url = "https://files.pythonhosted.org/packages/f3/fd/c7924b4c2a1c61b8f4b64edd7a31ffacf63432135a2606f03a2f0d75a750/protobuf-5.29.2-py3-none-any.whl", hash = "sha256:fde4554c0e578a5a0bcc9a276339594848d1e89f9ea47b4427c80e5d72f90181", size = 172539 }, +] + +[[package]] +name = "pygments" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, +] + +[[package]] +name = "pymdown-extensions" +version = "10.13" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/49/87/4998d1aac5afea5b081238a609d9814f4c33cd5c7123503276d1105fb6a9/pymdown_extensions-10.13.tar.gz", hash = "sha256:e0b351494dc0d8d14a1f52b39b1499a00ef1566b4ba23dc74f1eba75c736f5dd", size = 843302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/7f/46c7122186759350cf523c71d29712be534f769f073a1d980ce8f095072c/pymdown_extensions-10.13-py3-none-any.whl", hash = "sha256:80bc33d715eec68e683e04298946d47d78c7739e79d808203df278ee8ef89428", size = 264108 }, +] + +[[package]] +name = "pyparsing" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/d5/e5aeee5387091148a19e1145f63606619cb5f20b83fccb63efae6474e7b2/pyparsing-3.2.0.tar.gz", hash = "sha256:cbf74e27246d595d9a74b186b810f6fbb86726dbf3b9532efb343f6d7294fe9c", size = 920984 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/ec/2eb3cd785efd67806c46c13a17339708ddc346cbb684eade7a6e6f79536a/pyparsing-3.2.0-py3-none-any.whl", hash = "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84", size = 106921 }, +] + +[[package]] +name = "pyro-api" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/d7/a0812f5c16b0d4464f80a64a44626c5fe200098070be0f32436dbb662775/pyro-api-0.1.2.tar.gz", hash = "sha256:a1b900d9580aa1c2fab3b123ab7ff33413744da7c5f440bd4aadc4d40d14d920", size = 7349 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/81/957ae78e6398460a7230b0eb9b8f1cb954c5e913e868e48d89324c68cec7/pyro_api-0.1.2-py3-none-any.whl", hash = "sha256:10e0e42e9e4401ce464dab79c870e50dfb4f413d326fa777f3582928ef9caf8f", size = 11981 }, +] + +[[package]] +name = "pyro-ppl" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "opt-einsum" }, + { name = "pyro-api" }, + { name = "torch" }, + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4c/2e/3bcba8688d58f8dc954cef6831c19d52b6017b035d783685d67cd99fa351/pyro_ppl-1.9.1.tar.gz", hash = "sha256:5e1596de276c038a3f77d2580a90d0a97126e0104900444a088eee620bb0d65e", size = 570861 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/37/def183a2a2c8619d92649d62fe0622c4c6c62f60e4151e8fbaa409e7d5ab/pyro_ppl-1.9.1-py3-none-any.whl", hash = "sha256:91fb2c8740d9d3bd548180ac5ecfa04552ed8c471a1ab66870180663b8f09852", size = 755956 }, +] + +[[package]] +name = "pytest" +version = "7.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/1f/9d8e98e4133ffb16c90f3b405c43e38d3abb715bb5d7a63a5a684f7e46a3/pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", size = 1357116 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8", size = 325287 }, +] + +[[package]] +name = "pytest-cases" +version = "3.8.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "decopatch" }, + { name = "makefun" }, + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/15/cb/d0d0810f9771b7daf35be7f283035c7a24c8c53b0272be458aebc2169ced/pytest_cases-3.8.6.tar.gz", hash = "sha256:5c24e0ab0cb6f8e802a469b7965906a333d3babb874586ebc56f7e2cbe1a7c44", size = 1092150 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/63/965396a32be6f2cd6d16650ef1e103caf5df92a530087bb0cf0b2509a04e/pytest_cases-3.8.6-py2.py3-none-any.whl", hash = "sha256:564c722492ea7e7ec3ac433fd14070180e65866f49fa35bfe938c0d5d9afba67", size = 107283 }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, +] + +[[package]] +name = "pytz" +version = "2024.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, +] + +[[package]] +name = "pywin32" +version = "308" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/a6/3e9f2c474895c1bb61b11fa9640be00067b5c5b363c501ee9c3fa53aec01/pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e", size = 5927028 }, + { url = "https://files.pythonhosted.org/packages/d9/b4/84e2463422f869b4b718f79eb7530a4c1693e96b8a4e5e968de38be4d2ba/pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e", size = 6558484 }, + { url = "https://files.pythonhosted.org/packages/9f/8f/fb84ab789713f7c6feacaa08dad3ec8105b88ade8d1c4f0f0dfcaaa017d6/pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c", size = 7971454 }, + { url = "https://files.pythonhosted.org/packages/eb/e2/02652007469263fe1466e98439831d65d4ca80ea1a2df29abecedf7e47b7/pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a", size = 5928156 }, + { url = "https://files.pythonhosted.org/packages/48/ef/f4fb45e2196bc7ffe09cad0542d9aff66b0e33f6c0954b43e49c33cad7bd/pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b", size = 6559559 }, + { url = "https://files.pythonhosted.org/packages/79/ef/68bb6aa865c5c9b11a35771329e95917b5559845bd75b65549407f9fc6b4/pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6", size = 7972495 }, + { url = "https://files.pythonhosted.org/packages/00/7c/d00d6bdd96de4344e06c4afbf218bc86b54436a94c01c71a8701f613aa56/pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897", size = 5939729 }, + { url = "https://files.pythonhosted.org/packages/21/27/0c8811fbc3ca188f93b5354e7c286eb91f80a53afa4e11007ef661afa746/pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47", size = 6543015 }, + { url = "https://files.pythonhosted.org/packages/9d/0f/d40f8373608caed2255781a3ad9a51d03a594a1248cd632d6a298daca693/pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091", size = 7976033 }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, +] + +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/8e/da1c6c58f751b70f8ceb1eb25bc25d524e8f14fe16edcce3f4e3ba08629c/pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb", size = 5631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/66/bbb1dd374f5c870f59c5bb1db0e18cbe7fa739415a24cbd95b2d1f5ae0c4/pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069", size = 3911 }, +] + +[[package]] +name = "regex" +version = "2024.11.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/3c/4651f6b130c6842a8f3df82461a8950f923925db8b6961063e82744bddcc/regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91", size = 482674 }, + { url = "https://files.pythonhosted.org/packages/15/51/9f35d12da8434b489c7b7bffc205c474a0a9432a889457026e9bc06a297a/regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0", size = 287684 }, + { url = "https://files.pythonhosted.org/packages/bd/18/b731f5510d1b8fb63c6b6d3484bfa9a59b84cc578ac8b5172970e05ae07c/regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e", size = 284589 }, + { url = "https://files.pythonhosted.org/packages/78/a2/6dd36e16341ab95e4c6073426561b9bfdeb1a9c9b63ab1b579c2e96cb105/regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde", size = 782511 }, + { url = "https://files.pythonhosted.org/packages/1b/2b/323e72d5d2fd8de0d9baa443e1ed70363ed7e7b2fb526f5950c5cb99c364/regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e", size = 821149 }, + { url = "https://files.pythonhosted.org/packages/90/30/63373b9ea468fbef8a907fd273e5c329b8c9535fee36fc8dba5fecac475d/regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2", size = 809707 }, + { url = "https://files.pythonhosted.org/packages/f2/98/26d3830875b53071f1f0ae6d547f1d98e964dd29ad35cbf94439120bb67a/regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf", size = 781702 }, + { url = "https://files.pythonhosted.org/packages/87/55/eb2a068334274db86208ab9d5599ffa63631b9f0f67ed70ea7c82a69bbc8/regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c", size = 771976 }, + { url = "https://files.pythonhosted.org/packages/74/c0/be707bcfe98254d8f9d2cff55d216e946f4ea48ad2fd8cf1428f8c5332ba/regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86", size = 697397 }, + { url = "https://files.pythonhosted.org/packages/49/dc/bb45572ceb49e0f6509f7596e4ba7031f6819ecb26bc7610979af5a77f45/regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67", size = 768726 }, + { url = "https://files.pythonhosted.org/packages/5a/db/f43fd75dc4c0c2d96d0881967897926942e935d700863666f3c844a72ce6/regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d", size = 775098 }, + { url = "https://files.pythonhosted.org/packages/99/d7/f94154db29ab5a89d69ff893159b19ada89e76b915c1293e98603d39838c/regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2", size = 839325 }, + { url = "https://files.pythonhosted.org/packages/f7/17/3cbfab1f23356fbbf07708220ab438a7efa1e0f34195bf857433f79f1788/regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008", size = 843277 }, + { url = "https://files.pythonhosted.org/packages/7e/f2/48b393b51900456155de3ad001900f94298965e1cad1c772b87f9cfea011/regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62", size = 773197 }, + { url = "https://files.pythonhosted.org/packages/45/3f/ef9589aba93e084cd3f8471fded352826dcae8489b650d0b9b27bc5bba8a/regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e", size = 261714 }, + { url = "https://files.pythonhosted.org/packages/42/7e/5f1b92c8468290c465fd50c5318da64319133231415a8aa6ea5ab995a815/regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519", size = 274042 }, + { url = "https://files.pythonhosted.org/packages/58/58/7e4d9493a66c88a7da6d205768119f51af0f684fe7be7bac8328e217a52c/regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638", size = 482669 }, + { url = "https://files.pythonhosted.org/packages/34/4c/8f8e631fcdc2ff978609eaeef1d6994bf2f028b59d9ac67640ed051f1218/regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7", size = 287684 }, + { url = "https://files.pythonhosted.org/packages/c5/1b/f0e4d13e6adf866ce9b069e191f303a30ab1277e037037a365c3aad5cc9c/regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20", size = 284589 }, + { url = "https://files.pythonhosted.org/packages/25/4d/ab21047f446693887f25510887e6820b93f791992994f6498b0318904d4a/regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114", size = 792121 }, + { url = "https://files.pythonhosted.org/packages/45/ee/c867e15cd894985cb32b731d89576c41a4642a57850c162490ea34b78c3b/regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3", size = 831275 }, + { url = "https://files.pythonhosted.org/packages/b3/12/b0f480726cf1c60f6536fa5e1c95275a77624f3ac8fdccf79e6727499e28/regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f", size = 818257 }, + { url = "https://files.pythonhosted.org/packages/bf/ce/0d0e61429f603bac433910d99ef1a02ce45a8967ffbe3cbee48599e62d88/regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0", size = 792727 }, + { url = "https://files.pythonhosted.org/packages/e4/c1/243c83c53d4a419c1556f43777ccb552bccdf79d08fda3980e4e77dd9137/regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55", size = 780667 }, + { url = "https://files.pythonhosted.org/packages/c5/f4/75eb0dd4ce4b37f04928987f1d22547ddaf6c4bae697623c1b05da67a8aa/regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89", size = 776963 }, + { url = "https://files.pythonhosted.org/packages/16/5d/95c568574e630e141a69ff8a254c2f188b4398e813c40d49228c9bbd9875/regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d", size = 784700 }, + { url = "https://files.pythonhosted.org/packages/8e/b5/f8495c7917f15cc6fee1e7f395e324ec3e00ab3c665a7dc9d27562fd5290/regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34", size = 848592 }, + { url = "https://files.pythonhosted.org/packages/1c/80/6dd7118e8cb212c3c60b191b932dc57db93fb2e36fb9e0e92f72a5909af9/regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d", size = 852929 }, + { url = "https://files.pythonhosted.org/packages/11/9b/5a05d2040297d2d254baf95eeeb6df83554e5e1df03bc1a6687fc4ba1f66/regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45", size = 781213 }, + { url = "https://files.pythonhosted.org/packages/26/b7/b14e2440156ab39e0177506c08c18accaf2b8932e39fb092074de733d868/regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9", size = 261734 }, + { url = "https://files.pythonhosted.org/packages/80/32/763a6cc01d21fb3819227a1cc3f60fd251c13c37c27a73b8ff4315433a8e/regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60", size = 274052 }, + { url = "https://files.pythonhosted.org/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", size = 483781 }, + { url = "https://files.pythonhosted.org/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", size = 288455 }, + { url = "https://files.pythonhosted.org/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", size = 284759 }, + { url = "https://files.pythonhosted.org/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", size = 794976 }, + { url = "https://files.pythonhosted.org/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", size = 833077 }, + { url = "https://files.pythonhosted.org/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", size = 823160 }, + { url = "https://files.pythonhosted.org/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", size = 796896 }, + { url = "https://files.pythonhosted.org/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", size = 783997 }, + { url = "https://files.pythonhosted.org/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", size = 781725 }, + { url = "https://files.pythonhosted.org/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", size = 789481 }, + { url = "https://files.pythonhosted.org/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", size = 852896 }, + { url = "https://files.pythonhosted.org/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", size = 860138 }, + { url = "https://files.pythonhosted.org/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", size = 787692 }, + { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135 }, + { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567 }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, +] + +[[package]] +name = "ruff" +version = "0.8.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/34/37/9c02181ef38d55b77d97c68b78e705fd14c0de0e5d085202bb2b52ce5be9/ruff-0.8.4.tar.gz", hash = "sha256:0d5f89f254836799af1615798caa5f80b7f935d7a670fad66c5007928e57ace8", size = 3402103 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/67/f480bf2f2723b2e49af38ed2be75ccdb2798fca7d56279b585c8f553aaab/ruff-0.8.4-py3-none-linux_armv6l.whl", hash = "sha256:58072f0c06080276804c6a4e21a9045a706584a958e644353603d36ca1eb8a60", size = 10546415 }, + { url = "https://files.pythonhosted.org/packages/eb/7a/5aba20312c73f1ce61814e520d1920edf68ca3b9c507bd84d8546a8ecaa8/ruff-0.8.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ffb60904651c00a1e0b8df594591770018a0f04587f7deeb3838344fe3adabac", size = 10346113 }, + { url = "https://files.pythonhosted.org/packages/76/f4/c41de22b3728486f0aa95383a44c42657b2db4062f3234ca36fc8cf52d8b/ruff-0.8.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6ddf5d654ac0d44389f6bf05cee4caeefc3132a64b58ea46738111d687352296", size = 9943564 }, + { url = "https://files.pythonhosted.org/packages/0e/f0/afa0d2191af495ac82d4cbbfd7a94e3df6f62a04ca412033e073b871fc6d/ruff-0.8.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e248b1f0fa2749edd3350a2a342b67b43a2627434c059a063418e3d375cfe643", size = 10805522 }, + { url = "https://files.pythonhosted.org/packages/12/57/5d1e9a0fd0c228e663894e8e3a8e7063e5ee90f8e8e60cf2085f362bfa1a/ruff-0.8.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf197b98ed86e417412ee3b6c893f44c8864f816451441483253d5ff22c0e81e", size = 10306763 }, + { url = "https://files.pythonhosted.org/packages/04/df/f069fdb02e408be8aac6853583572a2873f87f866fe8515de65873caf6b8/ruff-0.8.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c41319b85faa3aadd4d30cb1cffdd9ac6b89704ff79f7664b853785b48eccdf3", size = 11359574 }, + { url = "https://files.pythonhosted.org/packages/d3/04/37c27494cd02e4a8315680debfc6dfabcb97e597c07cce0044db1f9dfbe2/ruff-0.8.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9f8402b7c4f96463f135e936d9ab77b65711fcd5d72e5d67597b543bbb43cf3f", size = 12094851 }, + { url = "https://files.pythonhosted.org/packages/81/b1/c5d7fb68506cab9832d208d03ea4668da9a9887a4a392f4f328b1bf734ad/ruff-0.8.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4e56b3baa9c23d324ead112a4fdf20db9a3f8f29eeabff1355114dd96014604", size = 11655539 }, + { url = "https://files.pythonhosted.org/packages/ef/38/8f8f2c8898dc8a7a49bc340cf6f00226917f0f5cb489e37075bcb2ce3671/ruff-0.8.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:736272574e97157f7edbbb43b1d046125fce9e7d8d583d5d65d0c9bf2c15addf", size = 12912805 }, + { url = "https://files.pythonhosted.org/packages/06/dd/fa6660c279f4eb320788876d0cff4ea18d9af7d9ed7216d7bd66877468d0/ruff-0.8.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fe710ab6061592521f902fca7ebcb9fabd27bc7c57c764298b1c1f15fff720", size = 11205976 }, + { url = "https://files.pythonhosted.org/packages/a8/d7/de94cc89833b5de455750686c17c9e10f4e1ab7ccdc5521b8fe911d1477e/ruff-0.8.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:13e9ec6d6b55f6da412d59953d65d66e760d583dd3c1c72bf1f26435b5bfdbae", size = 10792039 }, + { url = "https://files.pythonhosted.org/packages/6d/15/3e4906559248bdbb74854af684314608297a05b996062c9d72e0ef7c7097/ruff-0.8.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:97d9aefef725348ad77d6db98b726cfdb075a40b936c7984088804dfd38268a7", size = 10400088 }, + { url = "https://files.pythonhosted.org/packages/a2/21/9ed4c0e8133cb4a87a18d470f534ad1a8a66d7bec493bcb8bda2d1a5d5be/ruff-0.8.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ab78e33325a6f5374e04c2ab924a3367d69a0da36f8c9cb6b894a62017506111", size = 10900814 }, + { url = "https://files.pythonhosted.org/packages/0d/5d/122a65a18955bd9da2616b69bc839351f8baf23b2805b543aa2f0aed72b5/ruff-0.8.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8ef06f66f4a05c3ddbc9121a8b0cecccd92c5bf3dd43b5472ffe40b8ca10f0f8", size = 11268828 }, + { url = "https://files.pythonhosted.org/packages/43/a9/1676ee9106995381e3d34bccac5bb28df70194167337ed4854c20f27c7ba/ruff-0.8.4-py3-none-win32.whl", hash = "sha256:552fb6d861320958ca5e15f28b20a3d071aa83b93caee33a87b471f99a6c0835", size = 8805621 }, + { url = "https://files.pythonhosted.org/packages/10/98/ed6b56a30ee76771c193ff7ceeaf1d2acc98d33a1a27b8479cbdb5c17a23/ruff-0.8.4-py3-none-win_amd64.whl", hash = "sha256:f21a1143776f8656d7f364bd264a9d60f01b7f52243fbe90e7670c0dfe0cf65d", size = 9660086 }, + { url = "https://files.pythonhosted.org/packages/13/9f/026e18ca7d7766783d779dae5e9c656746c6ede36ef73c6d934aaf4a6dec/ruff-0.8.4-py3-none-win_arm64.whl", hash = "sha256:9183dd615d8df50defa8b1d9a074053891ba39025cf5ae88e8bcb52edcc4bf08", size = 9074500 }, +] + +[[package]] +name = "scikit-learn" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "joblib" }, + { name = "numpy" }, + { name = "scipy" }, + { name = "threadpoolctl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/19/5aa2002044afc297ecaf1e3517ed07bba4aece3b5613b5160c1212995fc8/scikit_learn-1.6.0.tar.gz", hash = "sha256:9d58481f9f7499dff4196927aedd4285a0baec8caa3790efbe205f13de37dd6e", size = 7074944 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/97/55060f91a5e7c4df945e5a69b16148b5f2256e6e1ea3f17da8e27edf9953/scikit_learn-1.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:366fb3fa47dce90afed3d6106183f4978d6f24cfd595c2373424171b915ee718", size = 12060299 }, + { url = "https://files.pythonhosted.org/packages/36/7b/8c5dfc64a8344ebf2ae493d59af4b3650588051f654e164ff4f9952877b3/scikit_learn-1.6.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:59cd96a8d9f8dfd546f5d6e9787e1b989e981388d7803abbc9efdcde61e47460", size = 11105443 }, + { url = "https://files.pythonhosted.org/packages/25/9f/61544f2a5cae1bc27c97f0ec9ffcc9837e469f215817608840a4ccbb277a/scikit_learn-1.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efa7a579606c73a0b3d210e33ea410ea9e1af7933fe324cb7e6fbafae4ea5948", size = 12637137 }, + { url = "https://files.pythonhosted.org/packages/50/79/d21599fc44d2d497ced440480670b6314ebc00308e3bae0d0ebca44cd481/scikit_learn-1.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a46d3ca0f11a540b8eaddaf5e38172d8cd65a86cb3e3632161ec96c0cffb774c", size = 13490128 }, + { url = "https://files.pythonhosted.org/packages/ff/87/788da20cfefcd261123d4bb015b2de076e49cdd3b811b55e6811acd3cb21/scikit_learn-1.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:5be4577769c5dde6e1b53de8e6520f9b664ab5861dd57acee47ad119fd7405d6", size = 11118524 }, + { url = "https://files.pythonhosted.org/packages/07/95/070d6e70f735d13f1c10afebb65ba3526125b7d6c6fc7022651a4a061148/scikit_learn-1.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1f50b4f24cf12a81c3c09958ae3b864d7534934ca66ded3822de4996d25d7285", size = 12095168 }, + { url = "https://files.pythonhosted.org/packages/72/3d/0381e3a59ebd4154e6a61b0ceaf299c3c141035033dd3b868776cd9af02d/scikit_learn-1.6.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:eb9ae21f387826da14b0b9cb1034f5048ddb9182da429c689f5f4a87dc96930b", size = 11108880 }, + { url = "https://files.pythonhosted.org/packages/fe/2d/0999ae3eed2ac67b1b3cd7fc33370bd5ca59a7514ffe43ae2b6f3cd85b9b/scikit_learn-1.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0baa91eeb8c32632628874a5c91885eaedd23b71504d24227925080da075837a", size = 12585449 }, + { url = "https://files.pythonhosted.org/packages/0e/ec/1b15b59c6cc7a993320a52234369e787f50345a4753e50d5a015a91e1a20/scikit_learn-1.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c716d13ba0a2f8762d96ff78d3e0cde90bc9c9b5c13d6ab6bb9b2d6ca6705fd", size = 13489728 }, + { url = "https://files.pythonhosted.org/packages/96/a2/cbfb5743de748d574ffdfd557e9cb29ba4f8b8a3e07836c6c176f713de2f/scikit_learn-1.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:9aafd94bafc841b626681e626be27bf1233d5a0f20f0a6fdb4bee1a1963c6643", size = 11132946 }, + { url = "https://files.pythonhosted.org/packages/18/0c/a5de627aa57b028aea7026cb3bbeaf63be3158adc118212d6cc7843d939a/scikit_learn-1.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:04a5ba45c12a5ff81518aa4f1604e826a45d20e53da47b15871526cda4ff5174", size = 12096999 }, + { url = "https://files.pythonhosted.org/packages/a3/7d/02a96e6fb28ddb213e84b1b4a44148d26ec96fc9db9c74e050277e009892/scikit_learn-1.6.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:21fadfc2ad7a1ce8bd1d90f23d17875b84ec765eecbbfc924ff11fb73db582ce", size = 11160579 }, + { url = "https://files.pythonhosted.org/packages/70/28/77b071f541d75247e6c3403f19aaa634371e972691f6aa1838ca9fd4cc52/scikit_learn-1.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30f34bb5fde90e020653bb84dcb38b6c83f90c70680dbd8c38bd9becbad7a127", size = 12246543 }, + { url = "https://files.pythonhosted.org/packages/17/0e/e6bb84074f1081245a165c0ee775ecef24beae9d2f2e24bcac0c9f155f13/scikit_learn-1.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1dad624cffe3062276a0881d4e441bc9e3b19d02d17757cd6ae79a9d192a0027", size = 13140402 }, + { url = "https://files.pythonhosted.org/packages/21/1d/3df58df8bd425f425df9f90b316618ace62b7f1f838ac1580191025cc735/scikit_learn-1.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:2fce7950a3fad85e0a61dc403df0f9345b53432ac0e47c50da210d22c60b6d85", size = 11103596 }, +] + +[[package]] +name = "scipy" +version = "1.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/62/11/4d44a1f274e002784e4dbdb81e0ea96d2de2d1045b2132d5af62cc31fd28/scipy-1.14.1.tar.gz", hash = "sha256:5a275584e726026a5699459aa72f828a610821006228e841b94275c4a7c08417", size = 58620554 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/68/3bc0cfaf64ff507d82b1e5d5b64521df4c8bf7e22bc0b897827cbee9872c/scipy-1.14.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:b28d2ca4add7ac16ae8bb6632a3c86e4b9e4d52d3e34267f6e1b0c1f8d87e389", size = 39069598 }, + { url = "https://files.pythonhosted.org/packages/43/a5/8d02f9c372790326ad405d94f04d4339482ec082455b9e6e288f7100513b/scipy-1.14.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d0d2821003174de06b69e58cef2316a6622b60ee613121199cb2852a873f8cf3", size = 29879676 }, + { url = "https://files.pythonhosted.org/packages/07/42/0e0bea9666fcbf2cb6ea0205db42c81b1f34d7b729ba251010edf9c80ebd/scipy-1.14.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8bddf15838ba768bb5f5083c1ea012d64c9a444e16192762bd858f1e126196d0", size = 23088696 }, + { url = "https://files.pythonhosted.org/packages/15/47/298ab6fef5ebf31b426560e978b8b8548421d4ed0bf99263e1eb44532306/scipy-1.14.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:97c5dddd5932bd2a1a31c927ba5e1463a53b87ca96b5c9bdf5dfd6096e27efc3", size = 25470699 }, + { url = "https://files.pythonhosted.org/packages/d8/df/cdb6be5274bc694c4c22862ac3438cb04f360ed9df0aecee02ce0b798380/scipy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ff0a7e01e422c15739ecd64432743cf7aae2b03f3084288f399affcefe5222d", size = 35606631 }, + { url = "https://files.pythonhosted.org/packages/47/78/b0c2c23880dd1e99e938ad49ccfb011ae353758a2dc5ed7ee59baff684c3/scipy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e32dced201274bf96899e6491d9ba3e9a5f6b336708656466ad0522d8528f69", size = 41178528 }, + { url = "https://files.pythonhosted.org/packages/5d/aa/994b45c34b897637b853ec04334afa55a85650a0d11dacfa67232260fb0a/scipy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8426251ad1e4ad903a4514712d2fa8fdd5382c978010d1c6f5f37ef286a713ad", size = 42784535 }, + { url = "https://files.pythonhosted.org/packages/e7/1c/8daa6df17a945cb1a2a1e3bae3c49643f7b3b94017ff01a4787064f03f84/scipy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:a49f6ed96f83966f576b33a44257d869756df6cf1ef4934f59dd58b25e0327e5", size = 44772117 }, + { url = "https://files.pythonhosted.org/packages/b2/ab/070ccfabe870d9f105b04aee1e2860520460ef7ca0213172abfe871463b9/scipy-1.14.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:2da0469a4ef0ecd3693761acbdc20f2fdeafb69e6819cc081308cc978153c675", size = 39076999 }, + { url = "https://files.pythonhosted.org/packages/a7/c5/02ac82f9bb8f70818099df7e86c3ad28dae64e1347b421d8e3adf26acab6/scipy-1.14.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c0ee987efa6737242745f347835da2cc5bb9f1b42996a4d97d5c7ff7928cb6f2", size = 29894570 }, + { url = "https://files.pythonhosted.org/packages/ed/05/7f03e680cc5249c4f96c9e4e845acde08eb1aee5bc216eff8a089baa4ddb/scipy-1.14.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3a1b111fac6baec1c1d92f27e76511c9e7218f1695d61b59e05e0fe04dc59617", size = 23103567 }, + { url = "https://files.pythonhosted.org/packages/5e/fc/9f1413bef53171f379d786aabc104d4abeea48ee84c553a3e3d8c9f96a9c/scipy-1.14.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8475230e55549ab3f207bff11ebfc91c805dc3463ef62eda3ccf593254524ce8", size = 25499102 }, + { url = "https://files.pythonhosted.org/packages/c2/4b/b44bee3c2ddc316b0159b3d87a3d467ef8d7edfd525e6f7364a62cd87d90/scipy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:278266012eb69f4a720827bdd2dc54b2271c97d84255b2faaa8f161a158c3b37", size = 35586346 }, + { url = "https://files.pythonhosted.org/packages/93/6b/701776d4bd6bdd9b629c387b5140f006185bd8ddea16788a44434376b98f/scipy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fef8c87f8abfb884dac04e97824b61299880c43f4ce675dd2cbeadd3c9b466d2", size = 41165244 }, + { url = "https://files.pythonhosted.org/packages/06/57/e6aa6f55729a8f245d8a6984f2855696c5992113a5dc789065020f8be753/scipy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b05d43735bb2f07d689f56f7b474788a13ed8adc484a85aa65c0fd931cf9ccd2", size = 42817917 }, + { url = "https://files.pythonhosted.org/packages/ea/c2/5ecadc5fcccefaece775feadcd795060adf5c3b29a883bff0e678cfe89af/scipy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:716e389b694c4bb564b4fc0c51bc84d381735e0d39d3f26ec1af2556ec6aad94", size = 44781033 }, + { url = "https://files.pythonhosted.org/packages/c0/04/2bdacc8ac6387b15db6faa40295f8bd25eccf33f1f13e68a72dc3c60a99e/scipy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:631f07b3734d34aced009aaf6fedfd0eb3498a97e581c3b1e5f14a04164a456d", size = 39128781 }, + { url = "https://files.pythonhosted.org/packages/c8/53/35b4d41f5fd42f5781dbd0dd6c05d35ba8aa75c84ecddc7d44756cd8da2e/scipy-1.14.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:af29a935803cc707ab2ed7791c44288a682f9c8107bc00f0eccc4f92c08d6e07", size = 29939542 }, + { url = "https://files.pythonhosted.org/packages/66/67/6ef192e0e4d77b20cc33a01e743b00bc9e68fb83b88e06e636d2619a8767/scipy-1.14.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2843f2d527d9eebec9a43e6b406fb7266f3af25a751aa91d62ff416f54170bc5", size = 23148375 }, + { url = "https://files.pythonhosted.org/packages/f6/32/3a6dedd51d68eb7b8e7dc7947d5d841bcb699f1bf4463639554986f4d782/scipy-1.14.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:eb58ca0abd96911932f688528977858681a59d61a7ce908ffd355957f7025cfc", size = 25578573 }, + { url = "https://files.pythonhosted.org/packages/f0/5a/efa92a58dc3a2898705f1dc9dbaf390ca7d4fba26d6ab8cfffb0c72f656f/scipy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30ac8812c1d2aab7131a79ba62933a2a76f582d5dbbc695192453dae67ad6310", size = 35319299 }, + { url = "https://files.pythonhosted.org/packages/8e/ee/8a26858ca517e9c64f84b4c7734b89bda8e63bec85c3d2f432d225bb1886/scipy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f9ea80f2e65bdaa0b7627fb00cbeb2daf163caa015e59b7516395fe3bd1e066", size = 40849331 }, + { url = "https://files.pythonhosted.org/packages/a5/cd/06f72bc9187840f1c99e1a8750aad4216fc7dfdd7df46e6280add14b4822/scipy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:edaf02b82cd7639db00dbff629995ef185c8df4c3ffa71a5562a595765a06ce1", size = 42544049 }, + { url = "https://files.pythonhosted.org/packages/aa/7d/43ab67228ef98c6b5dd42ab386eae2d7877036970a0d7e3dd3eb47a0d530/scipy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2ff38e22128e6c03ff73b6bb0f85f897d2362f8c052e3b8ad00532198fbdae3f", size = 44521212 }, +] + +[[package]] +name = "seaborn" +version = "0.13.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "matplotlib" }, + { name = "numpy" }, + { name = "pandas" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/86/59/a451d7420a77ab0b98f7affa3a1d78a313d2f7281a57afb1a34bae8ab412/seaborn-0.13.2.tar.gz", hash = "sha256:93e60a40988f4d65e9f4885df477e2fdaff6b73a9ded434c1ab356dd57eefff7", size = 1457696 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/11/00d3c3dfc25ad54e731d91449895a79e4bf2384dc3ac01809010ba88f6d5/seaborn-0.13.2-py3-none-any.whl", hash = "sha256:636f8336facf092165e27924f223d3c62ca560b1f2bb5dff7ab7fad265361987", size = 294914 }, +] + +[[package]] +name = "setuptools" +version = "75.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/54/292f26c208734e9a7f067aea4a7e282c080750c4546559b58e2e45413ca0/setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6", size = 1337429 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/21/47d163f615df1d30c094f6c8bbb353619274edccf0327b185cc2493c2c33/setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d", size = 1224032 }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, +] + +[[package]] +name = "submitit" +version = "1.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cloudpickle" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/0a/854409283d533279b1b7523ebb65e1926ff611ee81bdf9c298bbed7b75ac/submitit-1.5.2.tar.gz", hash = "sha256:36a8a54ad4e10171111e7618eefe28fe819f931a89c9cd1f6d2770900c013f12", size = 80390 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/a4/90123871996bfb8a7148cd11d61e7a0ddc0118114c071730b3dc3a05c7bc/submitit-1.5.2-py3-none-any.whl", hash = "sha256:c6d5867fbcc78588d0ded3338436903f8db9fdb759f80e9639e6025a9ea32ade", size = 74917 }, +] + +[[package]] +name = "sympy" +version = "1.13.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ca/99/5a5b6f19ff9f083671ddf7b9632028436167cd3d33e11015754e41b249a4/sympy-1.13.1.tar.gz", hash = "sha256:9cebf7e04ff162015ce31c9c6c9144daa34a93bd082f54fd8f12deca4f47515f", size = 7533040 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/fe/81695a1aa331a842b582453b605175f419fe8540355886031328089d840a/sympy-1.13.1-py3-none-any.whl", hash = "sha256:db36cdc64bf61b9b24578b6f7bab1ecdd2452cf008f34faa33776680c26d66f8", size = 6189177 }, +] + +[[package]] +name = "tensorboard" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "absl-py" }, + { name = "grpcio" }, + { name = "markdown" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "protobuf" }, + { name = "setuptools" }, + { name = "six" }, + { name = "tensorboard-data-server" }, + { name = "werkzeug" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/de/021c1d407befb505791764ad2cbd56ceaaa53a746baed01d2e2143f05f18/tensorboard-2.18.0-py3-none-any.whl", hash = "sha256:107ca4821745f73e2aefa02c50ff70a9b694f39f790b11e6f682f7d326745eab", size = 5503036 }, +] + +[[package]] +name = "tensorboard-data-server" +version = "0.7.2" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/13/e503968fefabd4c6b2650af21e110aa8466fe21432cd7c43a84577a89438/tensorboard_data_server-0.7.2-py3-none-any.whl", hash = "sha256:7e0610d205889588983836ec05dc098e80f97b7e7bbff7e994ebb78f578d0ddb", size = 2356 }, + { url = "https://files.pythonhosted.org/packages/b7/85/dabeaf902892922777492e1d253bb7e1264cadce3cea932f7ff599e53fea/tensorboard_data_server-0.7.2-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:9fe5d24221b29625dbc7328b0436ca7fc1c23de4acf4d272f1180856e32f9f60", size = 4823598 }, + { url = "https://files.pythonhosted.org/packages/73/c6/825dab04195756cf8ff2e12698f22513b3db2f64925bdd41671bfb33aaa5/tensorboard_data_server-0.7.2-py3-none-manylinux_2_31_x86_64.whl", hash = "sha256:ef687163c24185ae9754ed5650eb5bc4d84ff257aabdc33f0cc6f74d8ba54530", size = 6590363 }, +] + +[[package]] +name = "threadpoolctl" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/55/b5148dcbf72f5cde221f8bfe3b6a540da7aa1842f6b491ad979a6c8b84af/threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107", size = 41936 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/2c/ffbf7a134b9ab11a67b0cf0726453cedd9c5043a4fe7a35d1cefa9a1bcfb/threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467", size = 18414 }, +] + +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +] + +[[package]] +name = "torch" +version = "2.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "setuptools", marker = "python_full_version >= '3.12'" }, + { name = "sympy" }, + { name = "triton", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/ef/834af4a885b31a0b32fff2d80e1e40f771e1566ea8ded55347502440786a/torch-2.5.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:71328e1bbe39d213b8721678f9dcac30dfc452a46d586f1d514a6aa0a99d4744", size = 906446312 }, + { url = "https://files.pythonhosted.org/packages/69/f0/46e74e0d145f43fa506cb336eaefb2d240547e4ce1f496e442711093ab25/torch-2.5.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:34bfa1a852e5714cbfa17f27c49d8ce35e1b7af5608c4bc6e81392c352dbc601", size = 91919522 }, + { url = "https://files.pythonhosted.org/packages/a5/13/1eb674c8efbd04d71e4a157ceba991904f633e009a584dd65dccbafbb648/torch-2.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:32a037bd98a241df6c93e4c789b683335da76a2ac142c0973675b715102dc5fa", size = 203088048 }, + { url = "https://files.pythonhosted.org/packages/a9/9d/e0860474ee0ff8f6ef2c50ec8f71a250f38d78a9b9df9fd241ad3397a65b/torch-2.5.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:23d062bf70776a3d04dbe74db950db2a5245e1ba4f27208a87f0d743b0d06e86", size = 63877046 }, + { url = "https://files.pythonhosted.org/packages/d1/35/e8b2daf02ce933e4518e6f5682c72fd0ed66c15910ea1fb4168f442b71c4/torch-2.5.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:de5b7d6740c4b636ef4db92be922f0edc425b65ed78c5076c43c42d362a45457", size = 906474467 }, + { url = "https://files.pythonhosted.org/packages/40/04/bd91593a4ca178ece93ca55f27e2783aa524aaccbfda66831d59a054c31e/torch-2.5.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:340ce0432cad0d37f5a31be666896e16788f1adf8ad7be481196b503dad675b9", size = 91919450 }, + { url = "https://files.pythonhosted.org/packages/0d/4a/e51420d46cfc90562e85af2fee912237c662ab31140ab179e49bd69401d6/torch-2.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:603c52d2fe06433c18b747d25f5c333f9c1d58615620578c326d66f258686f9a", size = 203098237 }, + { url = "https://files.pythonhosted.org/packages/d0/db/5d9cbfbc7968d79c5c09a0bc0bc3735da079f2fd07cc10498a62b320a480/torch-2.5.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:31f8c39660962f9ae4eeec995e3049b5492eb7360dd4f07377658ef4d728fa4c", size = 63884466 }, + { url = "https://files.pythonhosted.org/packages/8b/5c/36c114d120bfe10f9323ed35061bc5878cc74f3f594003854b0ea298942f/torch-2.5.1-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:ed231a4b3a5952177fafb661213d690a72caaad97d5824dd4fc17ab9e15cec03", size = 906389343 }, + { url = "https://files.pythonhosted.org/packages/6d/69/d8ada8b6e0a4257556d5b4ddeb4345ea8eeaaef3c98b60d1cca197c7ad8e/torch-2.5.1-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:3f4b7f10a247e0dcd7ea97dc2d3bfbfc90302ed36d7f3952b0008d0df264e697", size = 91811673 }, + { url = "https://files.pythonhosted.org/packages/5f/ba/607d013b55b9fd805db2a5c2662ec7551f1910b4eef39653eeaba182c5b2/torch-2.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:73e58e78f7d220917c5dbfad1a40e09df9929d3b95d25e57d9f8558f84c9a11c", size = 203046841 }, + { url = "https://files.pythonhosted.org/packages/57/6c/bf52ff061da33deb9f94f4121fde7ff3058812cb7d2036c97bc167793bd1/torch-2.5.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:8c712df61101964eb11910a846514011f0b6f5920c55dbf567bff8a34163d5b1", size = 63858109 }, +] + +[[package]] +name = "torchvision" +version = "0.20.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pillow" }, + { name = "torch" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/59/aea68d755da1451e1a0d894528a7edc9b58eb30d33e274bf21bef28dad1a/torchvision-0.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4878fefb96ef293d06c27210918adc83c399d9faaf34cda5a63e129f772328f1", size = 1787552 }, + { url = "https://files.pythonhosted.org/packages/a2/f6/7ff89a9f8703f623f5664afd66c8600e3f09fe188e1e0b7e6f9a8617f865/torchvision-0.20.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:8ffbdf8bf5b30eade22d459f5a313329eeadb20dc75efa142987b53c007098c3", size = 7238975 }, + { url = "https://files.pythonhosted.org/packages/f7/ce/4c31e9b96cc4f9fec746b258d2aa35f8d1247f4f58d63f9c505ea5eb254d/torchvision-0.20.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:75f8a4d51a593c4bab6c9bf7d75bdd88691b00a53b07656678bc55a3a753dd73", size = 14265343 }, + { url = "https://files.pythonhosted.org/packages/17/11/b5ce67715bbbec8798fb48c4a20ac28828aec1710ac01091a3eddcb8e075/torchvision-0.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:22c2fa44e20eb404b85e42b22b453863a14b0927d25e550fd4f84eea97fa5b39", size = 1562413 }, + { url = "https://files.pythonhosted.org/packages/28/57/4d7ad90be612f5ac6c4bdafcb0ff13e818e14a340a88c8ca00d9ed8c2dad/torchvision-0.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:344b339e15e6bbb59ee0700772616d0afefd209920c762b1604368d8c3458322", size = 1787548 }, + { url = "https://files.pythonhosted.org/packages/de/e9/e190ecec448d5a2abad8348cf085fcb39962a491e3f40dcb023721e04feb/torchvision-0.20.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:86f6523dee420000fe14c3527f6c8e0175139fda7d995b187f54a0b0ebec7eb6", size = 7241222 }, + { url = "https://files.pythonhosted.org/packages/b1/a3/cbb8177e5e379f0c040b00c6f80f14d323a97e30495d7115d169b101b2f7/torchvision-0.20.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:a40d766345927639da322c693934e5f91b1ba2218846c7104b868dea2314ce8e", size = 14267510 }, + { url = "https://files.pythonhosted.org/packages/69/55/ce836703ff77bb21582c3098d5311f8ddde7eadc7eab04be9561961f4725/torchvision-0.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:5b501d5c04b034d2ecda96a31ed050e383cf8201352e4c9276ca249cbecfded0", size = 1562402 }, + { url = "https://files.pythonhosted.org/packages/c5/eb/4ba19616378f2bc085999432fded2b7dfdbdccc6dd0fc293203452508100/torchvision-0.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1a31256ff945d64f006bb306813a7c95a531fe16bfb2535c837dd4c104533d7a", size = 1787553 }, + { url = "https://files.pythonhosted.org/packages/d4/75/00a852275ade58d3dc474530f7a7b6bc999a817148f0eb59d4fde12eb955/torchvision-0.20.1-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:17cd78adddf81dac57d7dccc9277a4d686425b1c55715f308769770cb26cad5c", size = 7240323 }, + { url = "https://files.pythonhosted.org/packages/af/f0/ca1445406eb12cbeb7a41fc833a1941ede78e7c55621198b83ecd7bcfd0f/torchvision-0.20.1-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:9f853ba4497ac4691815ad41b523ee23cf5ba4f87b1ce869d704052e233ca8b7", size = 14266936 }, + { url = "https://files.pythonhosted.org/packages/c3/18/00993d420b1d6e88582e51d4bc82c824c99a2e9c045d50eaf9b34fff729a/torchvision-0.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:4a330422c36dbfc946d3a6c1caec3489db07ecdf3675d83369adb2e5a0ca17c4", size = 1562392 }, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "platform_system == 'Windows'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 }, +] + +[[package]] +name = "triton" +version = "3.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/29/69aa56dc0b2eb2602b553881e34243475ea2afd9699be042316842788ff5/triton-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b0dd10a925263abbe9fa37dcde67a5e9b2383fc269fdf59f5657cac38c5d1d8", size = 209460013 }, + { url = "https://files.pythonhosted.org/packages/86/17/d9a5cf4fcf46291856d1e90762e36cbabd2a56c7265da0d1d9508c8e3943/triton-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f34f6e7885d1bf0eaaf7ba875a5f0ce6f3c13ba98f9503651c1e6dc6757ed5c", size = 209506424 }, + { url = "https://files.pythonhosted.org/packages/78/eb/65f5ba83c2a123f6498a3097746607e5b2f16add29e36765305e4ac7fdd8/triton-3.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8182f42fd8080a7d39d666814fa36c5e30cc00ea7eeeb1a2983dbb4c99a0fdc", size = 209551444 }, +] + +[[package]] +name = "typeguard" +version = "4.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/62/c3/400917dd37d7b8c07e9723f3046818530423e1e759a56a22133362adab00/typeguard-4.4.1.tar.gz", hash = "sha256:0d22a89d00b453b47c49875f42b6601b961757541a2e1e0ef517b6e24213c21b", size = 74959 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/53/9465dedf2d69fe26008e7732cf6e0a385e387c240869e7d54eed49782a3c/typeguard-4.4.1-py3-none-any.whl", hash = "sha256:9324ec07a27ec67fc54a9c063020ca4c0ae6abad5e9f0f9804ca59aee68c6e21", size = 35635 }, +] + +[[package]] +name = "types-pyyaml" +version = "6.0.12.20241230" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/f9/4d566925bcf9396136c0a2e5dc7e230ff08d86fa011a69888dd184469d80/types_pyyaml-6.0.12.20241230.tar.gz", hash = "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c", size = 17078 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/c1/48474fbead512b70ccdb4f81ba5eb4a58f69d100ba19f17c92c0c4f50ae6/types_PyYAML-6.0.12.20241230-py3-none-any.whl", hash = "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6", size = 20029 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] + +[[package]] +name = "tzdata" +version = "2024.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/34/943888654477a574a86a98e9896bae89c7aa15078ec29f490fef2f1e5384/tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc", size = 193282 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586 }, +] + +[[package]] +name = "urllib3" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, +] + +[[package]] +name = "verspec" +version = "0.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/44/8126f9f0c44319b2efc65feaad589cadef4d77ece200ae3c9133d58464d0/verspec-0.1.0.tar.gz", hash = "sha256:c4504ca697b2056cdb4bfa7121461f5a0e81809255b41c03dda4ba823637c01e", size = 27123 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl", hash = "sha256:741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31", size = 19640 }, +] + +[[package]] +name = "virtualenv" +version = "20.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bf/75/53316a5a8050069228a2f6d11f32046cfa94fbb6cc3f08703f59b873de2e/virtualenv-20.28.0.tar.gz", hash = "sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa", size = 7650368 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/f9/0919cf6f1432a8c4baa62511f8f8da8225432d22e83e3476f5be1a1edc6e/virtualenv-20.28.0-py3-none-any.whl", hash = "sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0", size = 4276702 }, +] + +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/56/90994d789c61df619bfc5ce2ecdabd5eeff564e1eb47512bd01b5e019569/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", size = 96390 }, + { url = "https://files.pythonhosted.org/packages/55/46/9a67ee697342ddf3c6daa97e3a587a56d6c4052f881ed926a849fcf7371c/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", size = 88389 }, + { url = "https://files.pythonhosted.org/packages/44/65/91b0985747c52064d8701e1075eb96f8c40a79df889e59a399453adfb882/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", size = 89020 }, + { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393 }, + { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392 }, + { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019 }, + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471 }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449 }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054 }, + { url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902 }, + { url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380 }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079 }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076 }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077 }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077 }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065 }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070 }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067 }, +] + +[[package]] +name = "werkzeug" +version = "3.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9f/69/83029f1f6300c5fb2471d621ab06f6ec6b3324685a2ce0f9777fd4a8b71e/werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746", size = 806925 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", size = 224498 }, +] + +[[package]] +name = "zipp" +version = "3.21.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630 }, +] From 715e84a237aa4138bb700c86368d84871ea96083 Mon Sep 17 00:00:00 2001 From: Meganton Date: Tue, 31 Dec 2024 01:49:01 +0100 Subject: [PATCH 16/24] renamed run_pipeline in yaml files + renamed run_pipline.py in yaml_tests --- docs/doc_yamls/customizing_neps_optimizer.yaml | 4 ++-- docs/doc_yamls/defining_hooks.yaml | 4 ++-- docs/doc_yamls/full_configuration_template.yaml | 4 ++-- docs/doc_yamls/loading_own_optimizer.yaml | 4 ++-- docs/doc_yamls/loading_pipeline_space_dict.yaml | 4 ++-- docs/doc_yamls/outsourcing_optimizer.yaml | 4 ++-- docs/doc_yamls/outsourcing_pipeline_space.yaml | 4 ++-- docs/doc_yamls/simple_example_including_run_pipeline.yaml | 6 +++--- tests/test_settings/overwrite_run_args.yaml | 4 ++-- tests/test_settings/run_args_optimizer_outside.yaml | 4 ++-- tests/test_settings/run_args_optimizer_settings.yaml | 4 ++-- tests/test_settings/run_args_required.yaml | 4 ++-- tests/test_yaml_run_args/run_args_full.yaml | 4 ++-- tests/test_yaml_run_args/run_args_full_same_level.yaml | 4 ++-- tests/test_yaml_run_args/run_args_invalid_key.yaml | 2 +- tests/test_yaml_run_args/run_args_key_missing.yaml | 2 +- .../run_args_optional_loading_format.yaml | 4 ++-- tests/test_yaml_run_args/run_args_wrong_name.yaml | 2 +- tests/test_yaml_run_args/run_args_wrong_path.yaml | 4 ++-- .../customizing_neps_optimizer.yaml | 4 ++-- .../test_declarative_usage_docs/defining_hooks.yaml | 4 ++-- .../{run_pipeline.py => evaluate_pipeline.py} | 0 .../full_configuration_template.yaml | 4 ++-- .../loading_own_optimizer.yaml | 6 +++--- .../loading_pipeline_space_dict.yaml | 4 ++-- .../outsourcing_optimizer.yaml | 6 +++--- .../outsourcing_pipeline_space.yaml | 4 ++-- .../simple_example_including_run_pipeline.yaml | 8 ++++---- .../test_run_args_by_neps_run/config.yaml | 4 ++-- .../config_hyperband_mixed_args.yaml | 4 ++-- .../config_priorband_with_args.yaml | 4 ++-- .../test_run_args_by_neps_run/config_select_bo.yaml | 4 ++-- .../test_run_args_by_neps_run/loading_optimizer.yaml | 4 ++-- .../test_run_args_by_neps_run/loading_pipeline_space.yaml | 4 ++-- 34 files changed, 68 insertions(+), 68 deletions(-) rename tests/test_yaml_run_args/test_declarative_usage_docs/{run_pipeline.py => evaluate_pipeline.py} (100%) diff --git a/docs/doc_yamls/customizing_neps_optimizer.yaml b/docs/doc_yamls/customizing_neps_optimizer.yaml index 93596fc8..5d98140f 100644 --- a/docs/doc_yamls/customizing_neps_optimizer.yaml +++ b/docs/doc_yamls/customizing_neps_optimizer.yaml @@ -1,6 +1,6 @@ # Customizing NePS Searcher -run_pipeline: - path: path/to/your/run_pipeline.py # Path to the function file +evaluate_pipeline: + path: path/to/your/evaluate_pipeline.py # Path to the function file name: example_pipeline # Function name within the file pipeline_space: diff --git a/docs/doc_yamls/defining_hooks.yaml b/docs/doc_yamls/defining_hooks.yaml index d63c3ce5..67032ab6 100644 --- a/docs/doc_yamls/defining_hooks.yaml +++ b/docs/doc_yamls/defining_hooks.yaml @@ -1,6 +1,6 @@ # Hooks -run_pipeline: - path: path/to/your/run_pipeline.py # Path to the function file +evaluate_pipeline: + path: path/to/your/evaluate_pipeline.py # Path to the function file name: example_pipeline # Function name within the file pipeline_space: diff --git a/docs/doc_yamls/full_configuration_template.yaml b/docs/doc_yamls/full_configuration_template.yaml index 6b28ccf4..aa1c6685 100644 --- a/docs/doc_yamls/full_configuration_template.yaml +++ b/docs/doc_yamls/full_configuration_template.yaml @@ -1,6 +1,6 @@ # Full Configuration Template for NePS -run_pipeline: - path: path/to/your/run_pipeline.py # Path to the function file +evaluate_pipeline: + path: path/to/your/evaluate_pipeline.py # Path to the function file name: example_pipeline # Function name within the file pipeline_space: diff --git a/docs/doc_yamls/loading_own_optimizer.yaml b/docs/doc_yamls/loading_own_optimizer.yaml index 7a26a123..5d656372 100644 --- a/docs/doc_yamls/loading_own_optimizer.yaml +++ b/docs/doc_yamls/loading_own_optimizer.yaml @@ -1,6 +1,6 @@ # Loading Optimizer Class -run_pipeline: - path: path/to/your/run_pipeline.py # Path to the function file +evaluate_pipeline: + path: path/to/your/evaluate_pipeline.py # Path to the function file name: example_pipeline # Function name within the file pipeline_space: diff --git a/docs/doc_yamls/loading_pipeline_space_dict.yaml b/docs/doc_yamls/loading_pipeline_space_dict.yaml index 96643865..53ff9ec6 100644 --- a/docs/doc_yamls/loading_pipeline_space_dict.yaml +++ b/docs/doc_yamls/loading_pipeline_space_dict.yaml @@ -1,6 +1,6 @@ # Loading pipeline space from a python dict -run_pipeline: - path: path/to/your/run_pipeline.py # Path to the function file +evaluate_pipeline: + path: path/to/your/evaluate_pipeline.py # Path to the function file name: example_pipeline # Function name within the file pipeline_space: diff --git a/docs/doc_yamls/outsourcing_optimizer.yaml b/docs/doc_yamls/outsourcing_optimizer.yaml index 6cdf3a2c..1ca3a764 100644 --- a/docs/doc_yamls/outsourcing_optimizer.yaml +++ b/docs/doc_yamls/outsourcing_optimizer.yaml @@ -1,6 +1,6 @@ # Optimizer settings from YAML configuration -run_pipeline: - path: path/to/your/run_pipeline.py # Path to the function file +evaluate_pipeline: + path: path/to/your/evaluate_pipeline.py # Path to the function file name: example_pipeline # Function name within the file pipeline_space: diff --git a/docs/doc_yamls/outsourcing_pipeline_space.yaml b/docs/doc_yamls/outsourcing_pipeline_space.yaml index c3d8eaed..d3f7a65f 100644 --- a/docs/doc_yamls/outsourcing_pipeline_space.yaml +++ b/docs/doc_yamls/outsourcing_pipeline_space.yaml @@ -1,6 +1,6 @@ # Pipeline space settings from separate YAML -run_pipeline: - path: path/to/your/run_pipeline.py # Path to the function file +evaluate_pipeline: + path: path/to/your/evaluate_pipeline.py # Path to the function file name: example_pipeline # Function name within the file pipeline_space: path/to/your/pipeline_space.yaml diff --git a/docs/doc_yamls/simple_example_including_run_pipeline.yaml b/docs/doc_yamls/simple_example_including_run_pipeline.yaml index afe8e9b8..ce9cc163 100644 --- a/docs/doc_yamls/simple_example_including_run_pipeline.yaml +++ b/docs/doc_yamls/simple_example_including_run_pipeline.yaml @@ -1,6 +1,6 @@ -# Simple NePS configuration including run_pipeline -run_pipeline: - path: path/to/your/run_pipeline.py # Path to the function file +# Simple NePS configuration including evaluate_pipeline +evaluate_pipeline: + path: path/to/your/evaluate_pipeline.py # Path to the function file name: example_pipeline # Function name within the file pipeline_space: diff --git a/tests/test_settings/overwrite_run_args.yaml b/tests/test_settings/overwrite_run_args.yaml index fb69b401..e7291fee 100644 --- a/tests/test_settings/overwrite_run_args.yaml +++ b/tests/test_settings/overwrite_run_args.yaml @@ -1,6 +1,6 @@ # Full Configuration Template for NePS -run_pipeline: - path: tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py +evaluate_pipeline: + path: tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py name: run_pipeline_constant pipeline_space: diff --git a/tests/test_settings/run_args_optimizer_outside.yaml b/tests/test_settings/run_args_optimizer_outside.yaml index 4380904e..1d87c32d 100644 --- a/tests/test_settings/run_args_optimizer_outside.yaml +++ b/tests/test_settings/run_args_optimizer_outside.yaml @@ -1,5 +1,5 @@ -run_pipeline: - name: run_pipeline +evaluate_pipeline: + name: evaluate_pipeline path: "tests/test_settings/test_settings.py" pipeline_space: name: pipeline_space diff --git a/tests/test_settings/run_args_optimizer_settings.yaml b/tests/test_settings/run_args_optimizer_settings.yaml index 00e34d18..065680da 100644 --- a/tests/test_settings/run_args_optimizer_settings.yaml +++ b/tests/test_settings/run_args_optimizer_settings.yaml @@ -1,6 +1,6 @@ # Full Configuration Template for NePS -run_pipeline: - path: tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py +evaluate_pipeline: + path: tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py name: run_pipeline_constant pipeline_space: diff --git a/tests/test_settings/run_args_required.yaml b/tests/test_settings/run_args_required.yaml index d3c6afdd..47aa6a52 100644 --- a/tests/test_settings/run_args_required.yaml +++ b/tests/test_settings/run_args_required.yaml @@ -1,5 +1,5 @@ -run_pipeline: - name: run_pipeline +evaluate_pipeline: + name: evaluate_pipeline path: "tests/test_settings/test_settings.py" pipeline_space: name: pipeline_space diff --git a/tests/test_yaml_run_args/run_args_full.yaml b/tests/test_yaml_run_args/run_args_full.yaml index 1ec96140..81433402 100644 --- a/tests/test_yaml_run_args/run_args_full.yaml +++ b/tests/test_yaml_run_args/run_args_full.yaml @@ -1,6 +1,6 @@ -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_yaml_run_args.py" - name: run_pipeline + name: evaluate_pipeline pipeline_space: "tests/test_yaml_run_args/pipeline_space.yaml" root_directory: "test_yaml" diff --git a/tests/test_yaml_run_args/run_args_full_same_level.yaml b/tests/test_yaml_run_args/run_args_full_same_level.yaml index b920533e..aad3d6c7 100644 --- a/tests/test_yaml_run_args/run_args_full_same_level.yaml +++ b/tests/test_yaml_run_args/run_args_full_same_level.yaml @@ -1,6 +1,6 @@ -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_yaml_run_args" # check if without .py also works - name: "run_pipeline" + name: "evaluate_pipeline" pipeline_space: "tests/test_yaml_run_args/pipeline_space.yaml" root_directory: "test_yaml" max_evaluations_total: 20 diff --git a/tests/test_yaml_run_args/run_args_invalid_key.yaml b/tests/test_yaml_run_args/run_args_invalid_key.yaml index b9c0ff2d..e440480b 100644 --- a/tests/test_yaml_run_args/run_args_invalid_key.yaml +++ b/tests/test_yaml_run_args/run_args_invalid_key.yaml @@ -1,6 +1,6 @@ run_pipelin: # typo in key path: "tests/test_yaml_run_args/test_yaml_run_args.py" - name: run_pipeline + name: evaluate_pipeline pipeline_space: "tests/test_yaml_run_args/pipeline_space.yaml" root_directory: "test_yaml" diff --git a/tests/test_yaml_run_args/run_args_key_missing.yaml b/tests/test_yaml_run_args/run_args_key_missing.yaml index ae27c608..e8cc72c1 100644 --- a/tests/test_yaml_run_args/run_args_key_missing.yaml +++ b/tests/test_yaml_run_args/run_args_key_missing.yaml @@ -1,4 +1,4 @@ -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_yaml_run_args.py" # key name is missing pipeline_space: "tests/test_yaml_run_args/pipeline_space.yaml" diff --git a/tests/test_yaml_run_args/run_args_optional_loading_format.yaml b/tests/test_yaml_run_args/run_args_optional_loading_format.yaml index aa96558f..e01a2cf3 100644 --- a/tests/test_yaml_run_args/run_args_optional_loading_format.yaml +++ b/tests/test_yaml_run_args/run_args_optional_loading_format.yaml @@ -1,6 +1,6 @@ -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_yaml_run_args.py" - name: "run_pipeline" + name: "evaluate_pipeline" pipeline_space: # Optional loading path: "tests/test_yaml_run_args/test_yaml_run_args.py" name: "pipeline_space" diff --git a/tests/test_yaml_run_args/run_args_wrong_name.yaml b/tests/test_yaml_run_args/run_args_wrong_name.yaml index ebfe640f..1a1d98b9 100644 --- a/tests/test_yaml_run_args/run_args_wrong_name.yaml +++ b/tests/test_yaml_run_args/run_args_wrong_name.yaml @@ -1,4 +1,4 @@ -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_yaml_run_args.py" name: run_pipelin # typo in name pipeline_space: "tests/test_yaml_run_args/pipeline_space.yaml" diff --git a/tests/test_yaml_run_args/run_args_wrong_path.yaml b/tests/test_yaml_run_args/run_args_wrong_path.yaml index bc8feed6..e9891465 100644 --- a/tests/test_yaml_run_args/run_args_wrong_path.yaml +++ b/tests/test_yaml_run_args/run_args_wrong_path.yaml @@ -1,6 +1,6 @@ -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_yaml_ru_args.py" # typo in path - name: run_pipeline + name: evaluate_pipeline pipeline_space: "tests/test_yaml_run_args/pipeline_space.yaml" root_directory: "test_yaml" diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/customizing_neps_optimizer.yaml b/tests/test_yaml_run_args/test_declarative_usage_docs/customizing_neps_optimizer.yaml index da0e7460..afae914e 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/customizing_neps_optimizer.yaml +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/customizing_neps_optimizer.yaml @@ -1,5 +1,5 @@ -run_pipeline: - path: tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py +evaluate_pipeline: + path: tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py name: run_pipeline_constant pipeline_space: diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/defining_hooks.yaml b/tests/test_yaml_run_args/test_declarative_usage_docs/defining_hooks.yaml index 83842f93..f37485f4 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/defining_hooks.yaml +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/defining_hooks.yaml @@ -1,6 +1,6 @@ # Basic NEPS Configuration Example -run_pipeline: - path: tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py +evaluate_pipeline: + path: tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py name: run_pipeline_constant pipeline_space: diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py b/tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py similarity index 100% rename from tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py rename to tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/full_configuration_template.yaml b/tests/test_yaml_run_args/test_declarative_usage_docs/full_configuration_template.yaml index 21851c88..70df0bdb 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/full_configuration_template.yaml +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/full_configuration_template.yaml @@ -1,6 +1,6 @@ # Full Configuration Template for NePS -run_pipeline: - path: tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py +evaluate_pipeline: + path: tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py name: run_pipeline_constant pipeline_space: diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/loading_own_optimizer.yaml b/tests/test_yaml_run_args/test_declarative_usage_docs/loading_own_optimizer.yaml index 9c0a4864..c178e8da 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/loading_own_optimizer.yaml +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/loading_own_optimizer.yaml @@ -1,6 +1,6 @@ -run_pipeline: - path: tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py - name: run_pipeline +evaluate_pipeline: + path: tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py + name: evaluate_pipeline pipeline_space: learning_rate: diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/loading_pipeline_space_dict.yaml b/tests/test_yaml_run_args/test_declarative_usage_docs/loading_pipeline_space_dict.yaml index 909e9559..0baad5c1 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/loading_pipeline_space_dict.yaml +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/loading_pipeline_space_dict.yaml @@ -1,6 +1,6 @@ # Loading pipeline space from a python dict -run_pipeline: - path: tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py +evaluate_pipeline: + path: tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py name: run_pipeline_constant pipeline_space: diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/outsourcing_optimizer.yaml b/tests/test_yaml_run_args/test_declarative_usage_docs/outsourcing_optimizer.yaml index e8e00aa3..82882247 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/outsourcing_optimizer.yaml +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/outsourcing_optimizer.yaml @@ -1,7 +1,7 @@ # Optimizer settings from YAML configuration -run_pipeline: - path: tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py - name: run_pipeline +evaluate_pipeline: + path: tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py + name: evaluate_pipeline pipeline_space: learning_rate: diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/outsourcing_pipeline_space.yaml b/tests/test_yaml_run_args/test_declarative_usage_docs/outsourcing_pipeline_space.yaml index 0810b62e..980b8b27 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/outsourcing_pipeline_space.yaml +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/outsourcing_pipeline_space.yaml @@ -1,6 +1,6 @@ # Pipeline space settings from YAML -run_pipeline: - path: tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py +evaluate_pipeline: + path: tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py name: run_pipeline_constant pipeline_space: tests/test_yaml_run_args/test_declarative_usage_docs/pipeline_space.yaml diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/simple_example_including_run_pipeline.yaml b/tests/test_yaml_run_args/test_declarative_usage_docs/simple_example_including_run_pipeline.yaml index fbf36873..a9abe6a7 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/simple_example_including_run_pipeline.yaml +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/simple_example_including_run_pipeline.yaml @@ -1,6 +1,6 @@ -# Simple NePS configuration including run_pipeline -run_pipeline: - path: tests/test_yaml_run_args/test_declarative_usage_docs/run_pipeline.py +# Simple NePS configuration including evaluate_pipeline +evaluate_pipeline: + path: tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py name: run_pipeline_constant pipeline_space: @@ -16,7 +16,7 @@ pipeline_space: choices: [adam, sgd, adamw] batch_size: 64 -root_directory: "tests_tmpdir/test_declarative_usage_docs/simple_example_including_run_pipeline" +root_directory: "tests_tmpdir/test_declarative_usage_docs/simple_example_including_evaluate_pipeline" max_evaluations_total: 20 # Budget overwrite_working_directory: True diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/config.yaml b/tests/test_yaml_run_args/test_run_args_by_neps_run/config.yaml index 967e2c9c..a87e3108 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/config.yaml +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/config.yaml @@ -1,6 +1,6 @@ -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py" - name: run_pipeline + name: evaluate_pipeline pipeline_space: "tests/test_yaml_run_args/test_run_args_by_neps_run/search_space.yaml" root_directory: "tests_tmpdir/test_run_args_by_neps_run/results2" diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/config_hyperband_mixed_args.yaml b/tests/test_yaml_run_args/test_run_args_by_neps_run/config_hyperband_mixed_args.yaml index 597cf20a..3ebfcb5d 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/config_hyperband_mixed_args.yaml +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/config_hyperband_mixed_args.yaml @@ -1,8 +1,8 @@ # args of optimizer from searcher kwargs (neps.run) and from run_args (yaml) -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py" - name: run_pipeline + name: evaluate_pipeline pipeline_space: "tests/test_yaml_run_args/test_run_args_by_neps_run/search_space_with_fidelity.yaml" root_directory: "tests_tmpdir/test_run_args_by_neps_run/optimizer_hyperband" diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/config_priorband_with_args.yaml b/tests/test_yaml_run_args/test_run_args_by_neps_run/config_priorband_with_args.yaml index a2c22067..b68ae9b7 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/config_priorband_with_args.yaml +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/config_priorband_with_args.yaml @@ -1,6 +1,6 @@ -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py" - name: run_pipeline + name: evaluate_pipeline pipeline_space: "tests/test_yaml_run_args/test_run_args_by_neps_run/search_space_with_priors.yaml" root_directory: "tests_tmpdir/test_run_args_by_neps_run/optimizer_priorband" diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/config_select_bo.yaml b/tests/test_yaml_run_args/test_run_args_by_neps_run/config_select_bo.yaml index 6d1ca26e..46913efa 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/config_select_bo.yaml +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/config_select_bo.yaml @@ -1,6 +1,6 @@ -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py" - name: run_pipeline + name: evaluate_pipeline pipeline_space: "tests/test_yaml_run_args/test_run_args_by_neps_run/search_space.yaml" root_directory: "tests_tmpdir/test_run_args_by_neps_run/optimizer_bo" diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/loading_optimizer.yaml b/tests/test_yaml_run_args/test_run_args_by_neps_run/loading_optimizer.yaml index b44fafe1..731dd20b 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/loading_optimizer.yaml +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/loading_optimizer.yaml @@ -1,6 +1,6 @@ -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py" - name: "run_pipeline" + name: "evaluate_pipeline" pipeline_space: "tests/test_yaml_run_args/test_run_args_by_neps_run/search_space.yaml" root_directory: "tests_tmpdir/test_run_args_by_neps_run/results1" diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/loading_pipeline_space.yaml b/tests/test_yaml_run_args/test_run_args_by_neps_run/loading_pipeline_space.yaml index fab9349a..eb298ad0 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/loading_pipeline_space.yaml +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/loading_pipeline_space.yaml @@ -1,6 +1,6 @@ -run_pipeline: +evaluate_pipeline: path: "tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py" - name: run_pipeline + name: evaluate_pipeline # Test Case pipeline_space: path: "tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py" From 18ba11acfaa3276da5904450c8ab6bc7929177df Mon Sep 17 00:00:00 2001 From: Meganton Date: Thu, 7 Nov 2024 19:31:19 +0100 Subject: [PATCH 17/24] renamed loss to objective_to_minimize --- docs/doc_yamls/run_pipeline.py | 6 +- docs/doc_yamls/run_pipeline_architecture.py | 6 +- .../run_pipeline_big_search_space.py | 6 +- docs/doc_yamls/run_pipeline_extended.py | 6 +- neps/api.py | 16 ++-- neps/optimizers/base_optimizer.py | 52 ++++++++----- .../bayesian_optimization/models/ftpfn.py | 6 +- .../bayesian_optimization/models/gp.py | 6 +- .../bayesian_optimization/optimizer.py | 2 +- neps/optimizers/multi_fidelity/hyperband.py | 24 +++--- neps/optimizers/multi_fidelity/ifbo.py | 5 +- .../multi_fidelity/successive_halving.py | 30 +++---- neps/optimizers/multi_fidelity/utils.py | 2 +- .../multi_fidelity_prior/async_priorband.py | 8 +- .../multi_fidelity_prior/priorband.py | 4 +- neps/plot/plot3D.py | 22 ++++-- neps/plot/read_results.py | 6 +- neps/plot/tensorboard_eval.py | 29 +++---- neps/runtime.py | 11 +-- neps/search_spaces/architecture/graph.py | 2 +- neps/state/_eval.py | 32 ++++---- neps/state/settings.py | 12 +-- neps/state/trial.py | 28 ++++--- neps/status/__main__.py | 19 +++-- neps/status/status.py | 44 +++++++---- neps/utils/cli.py | 78 ++++++++++++------- neps/utils/run_args.py | 8 +- neps/utils/types.py | 4 +- neps_examples/basic_usage/hyperparameters.py | 5 +- .../declarative_usage/hpo_example.py | 14 ++-- .../convenience/logging_additional_info.py | 4 +- .../convenience/neps_tblogger_tutorial.py | 26 +++---- neps_examples/convenience/neps_x_lightning.py | 24 +++--- .../working_directory_per_pipeline.py | 4 +- .../expert_priors_for_hyperparameters.py | 2 +- neps_examples/efficiency/multi_fidelity.py | 4 +- .../multi_fidelity_and_expert_priors.py | 4 +- ...rs_for_architecture_and_hyperparameters.py | 2 +- neps_examples/experimental/freeze_thaw.py | 18 ++--- tests/regression_objectives.py | 14 ++-- tests/regression_runner.py | 14 ++-- .../testing_scripts/baseoptimizer_neps.py | 8 +- .../testing_scripts/default_neps.py | 4 +- .../testing_scripts/user_yaml_neps.py | 4 +- .../test_default_report_values.py | 8 +- tests/test_runtime/test_stopping_criterion.py | 12 +-- tests/test_settings/test_settings.py | 26 +++---- tests/test_state/test_synced.py | 8 +- tests/test_state/test_trial.py | 18 ++--- .../evaluate_pipeline.py | 4 +- .../test_declarative_usage_docs/neps_run.py | 2 +- .../test_run_args_by_neps_run/neps_run.py | 2 +- .../test_yaml_run_args/test_yaml_run_args.py | 6 +- 53 files changed, 395 insertions(+), 316 deletions(-) diff --git a/docs/doc_yamls/run_pipeline.py b/docs/doc_yamls/run_pipeline.py index cfea0feb..29b33e72 100644 --- a/docs/doc_yamls/run_pipeline.py +++ b/docs/doc_yamls/run_pipeline.py @@ -2,6 +2,6 @@ def example_pipeline(learning_rate, optimizer, epochs): model = initialize_model() - training_loss = train_model(model, optimizer, learning_rate, epochs) - evaluation_loss = evaluate_model(model) - return {"loss": evaluation_loss, "training_loss": training_loss} + training_objective_to_minimize = train_model(model, optimizer, learning_rate, epochs) + evaluation_objective_to_minimize = evaluate_model(model) + return {"objective_to_minimize": evaluation_objective_to_minimize, "training_objective_to_minimize": training_objective_to_minimize} diff --git a/docs/doc_yamls/run_pipeline_architecture.py b/docs/doc_yamls/run_pipeline_architecture.py index f113f5f5..c3314489 100644 --- a/docs/doc_yamls/run_pipeline_architecture.py +++ b/docs/doc_yamls/run_pipeline_architecture.py @@ -19,6 +19,6 @@ def example_pipeline(architecture, optimizer, learning_rate): nn.Flatten(), nn.Linear(base_channels * out_channels_factor, n_classes), ) - training_loss = train_model(model, optimizer, learning_rate) - evaluation_loss = evaluate_model(model) - return {"loss": evaluation_loss, "training_loss": training_loss} + training_objective_to_minimize = train_model(model, optimizer, learning_rate) + evaluation_objective_to_minimize = evaluate_model(model) + return {"objective_to_minimize": evaluation_objective_to_minimize, "training_objective_to_minimize": training_objective_to_minimize} diff --git a/docs/doc_yamls/run_pipeline_big_search_space.py b/docs/doc_yamls/run_pipeline_big_search_space.py index 542283f0..346fe3bb 100644 --- a/docs/doc_yamls/run_pipeline_big_search_space.py +++ b/docs/doc_yamls/run_pipeline_big_search_space.py @@ -1,6 +1,6 @@ def example_pipeline(learning_rate, optimizer, epochs, batch_size, dropout_rate): model = initialize_model(dropout_rate) - training_loss = train_model(model, optimizer, learning_rate, epochs, batch_size) - evaluation_loss = evaluate_model(model) - return {"loss": evaluation_loss, "training_loss": training_loss} + training_objective_to_minimize = train_model(model, optimizer, learning_rate, epochs, batch_size) + evaluation_objective_to_minimize = evaluate_model(model) + return {"objective_to_minimize": evaluation_objective_to_minimize, "training_objective_to_minimize": training_objective_to_minimize} diff --git a/docs/doc_yamls/run_pipeline_extended.py b/docs/doc_yamls/run_pipeline_extended.py index c891f4d9..7a57f071 100644 --- a/docs/doc_yamls/run_pipeline_extended.py +++ b/docs/doc_yamls/run_pipeline_extended.py @@ -1,6 +1,6 @@ def example_pipeline(learning_rate, optimizer, epochs, batch_size): model = initialize_model() - training_loss = train_model(model, optimizer, learning_rate, epochs, batch_size) - evaluation_loss = evaluate_model(model) - return {"loss": evaluation_loss, "training_loss": training_loss} + training_objective_to_minimize = train_model(model, optimizer, learning_rate, epochs, batch_size) + evaluation_objective_to_minimize = evaluate_model(model) + return {"objective_to_minimize": evaluation_objective_to_minimize, "training_objective_to_minimize": training_objective_to_minimize} diff --git a/neps/api.py b/neps/api.py index d3991f7b..55d92a8a 100644 --- a/neps/api.py +++ b/neps/api.py @@ -41,7 +41,7 @@ def run( continue_until_max_evaluation_completed: bool = Default(False), max_cost_total: int | float | None = Default(None), ignore_errors: bool = Default(False), - loss_value_on_error: None | float = Default(None), + objective_to_minimize_value_on_error: None | float = Default(None), cost_value_on_error: None | float = Default(None), pre_load_hooks: Iterable | None = Default(None), searcher: ( @@ -93,9 +93,9 @@ def run( `return dict(loss=loss, cost=cost)`. ignore_errors: Ignore hyperparameter settings that threw an error and do not raise an error. Error configs still count towards max_evaluations_total. - loss_value_on_error: Setting this and cost_value_on_error to any float will - supress any error and will use given loss value instead. default: None - cost_value_on_error: Setting this and loss_value_on_error to any float will + objective_to_minimize_value_on_error: Setting this and cost_value_on_error to any float will + supress any error and will use given objective_to_minimize value instead. default: None + cost_value_on_error: Setting this and objective_to_minimize_value_on_error to any float will supress any error and will use given cost value instead. default: None pre_load_hooks: List of functions that will be called before load_results(). searcher: Which optimizer to use. Can be a string identifier, an @@ -193,7 +193,7 @@ def run( pipeline_space=settings.pipeline_space, max_cost_total=settings.max_cost_total, ignore_errors=settings.ignore_errors, - loss_value_on_error=settings.loss_value_on_error, + objective_to_minimize_value_on_error=settings.objective_to_minimize_value_on_error, cost_value_on_error=settings.cost_value_on_error, searcher=settings.searcher, **settings.searcher_kwargs, @@ -231,7 +231,7 @@ def run( max_evaluations_total=settings.max_evaluations_total, max_evaluations_for_worker=settings.max_evaluations_per_run, continue_until_max_evaluation_completed=settings.continue_until_max_evaluation_completed, - loss_value_on_error=settings.loss_value_on_error, + objective_to_minimize_value_on_error=settings.objective_to_minimize_value_on_error, cost_value_on_error=settings.cost_value_on_error, ignore_errors=settings.ignore_errors, overwrite_optimization_dir=settings.overwrite_working_directory, @@ -266,7 +266,7 @@ def _run_args( ) = None, max_cost_total: int | float | None = None, ignore_errors: bool = False, - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, searcher: ( Literal[ @@ -406,7 +406,7 @@ def _run_args( searcher_config.update( { - "loss_value_on_error": loss_value_on_error, + "objective_to_minimize_value_on_error": objective_to_minimize_value_on_error, "cost_value_on_error": cost_value_on_error, "ignore_errors": ignore_errors, } diff --git a/neps/optimizers/base_optimizer.py b/neps/optimizers/base_optimizer.py index 45d64167..69872584 100644 --- a/neps/optimizers/base_optimizer.py +++ b/neps/optimizers/base_optimizer.py @@ -14,9 +14,9 @@ from neps.utils.types import ERROR, ResultDict -def _get_loss( +def _get_objective_to_minimize( result: ERROR | ResultDict | float, - loss_value_on_error: float | None = None, + objective_to_minimize_value_on_error: float | None = None, *, ignore_errors: bool = False, ) -> ERROR | float: @@ -24,19 +24,20 @@ def _get_loss( if ignore_errors: return "error" - if loss_value_on_error is not None: - return loss_value_on_error + if objective_to_minimize_value_on_error is not None: + return objective_to_minimize_value_on_error raise ValueError( "An error happened during the execution of your evaluate_pipeline function." " You have three options: 1. If the error is expected and corresponds to" - " a loss value in your application (e.g., 0% accuracy), you can set" - " loss_value_on_error to some float. 2. If sometimes your pipeline" - " crashes randomly, you can set ignore_errors=True. 3. Fix your error." + " an objective_to_minimize value in your application (e.g., 0% accuracy)," + " you can set objective_to_minimize_value_on_error to some float. 2. If " + " sometimes your pipeline crashes randomly, you can set ignore_errors=True." + " 3. Fix your error." ) if isinstance(result, dict): - return float(result["loss"]) + return float(result["objective_to_minimize"]) assert isinstance(result, float) return float(result) @@ -89,7 +90,7 @@ def __init__( patience: int = 50, logger: logging.Logger | None = None, budget: int | float | None = None, - loss_value_on_error: float | None = None, + objective_to_minimize_value_on_error: float | None = None, cost_value_on_error: float | None = None, learning_curve_on_error: float | list[float] | None = None, ignore_errors: bool = False, @@ -101,7 +102,7 @@ def __init__( self.pipeline_space = pipeline_space self.patience = patience self.logger = logger or logging.getLogger("neps") - self.loss_value_on_error = loss_value_on_error + self.objective_to_minimize_value_on_error = objective_to_minimize_value_on_error self.cost_value_on_error = cost_value_on_error self.learning_curve_on_error = learning_curve_on_error self.ignore_errors = ignore_errors @@ -124,20 +125,27 @@ def ask( """ ... - def get_loss(self, result: ERROR | ResultDict | float | Report) -> float | ERROR: - """Calls result.utils.get_loss() and passes the error handling through. - Please use self.get_loss() instead of get_loss() in all optimizer classes. + def get_objective_to_minimize( + self, result: ERROR | ResultDict | float | Report + ) -> float | ERROR: + """Calls result.utils.get_objective_to_minimize() and passes the error handling + through. Please use self.get_objective_to_minimize() instead of + get_objective_to_minimize() in all optimizer classes. """ # TODO(eddiebergman): This is a forward change for whenever we can have optimizers # use `Trial` and `Report`, they already take care of this and save having to do - # this `_get_loss` at every call. We can also then just use `None` instead of - # the string `"error"` + # this `_get_objective_to_minimize` at every call. We can also then just use + # `None` instead of the string `"error"` if isinstance(result, Report): - return result.loss if result.loss is not None else "error" + return ( + result.objective_to_minimize + if result.objective_to_minimize is not None + else "error" + ) - return _get_loss( + return _get_objective_to_minimize( result, - loss_value_on_error=self.loss_value_on_error, + objective_to_minimize_value_on_error=self.objective_to_minimize_value_on_error, ignore_errors=self.ignore_errors, ) @@ -147,9 +155,13 @@ def get_cost(self, result: ERROR | ResultDict | float | Report) -> float | ERROR """ # TODO(eddiebergman): This is a forward change for whenever we can have optimizers # use `Trial` and `Report`, they already take care of this and save having to do - # this `_get_loss` at every call + # this `_get_objective_to_minimize` at every call if isinstance(result, Report): - return result.loss if result.loss is not None else "error" + return ( + result.objective_to_minimize + if result.objective_to_minimize is not None + else "error" + ) return _get_cost( result, diff --git a/neps/optimizers/bayesian_optimization/models/ftpfn.py b/neps/optimizers/bayesian_optimization/models/ftpfn.py index c5f206a5..da8c126f 100644 --- a/neps/optimizers/bayesian_optimization/models/ftpfn.py +++ b/neps/optimizers/bayesian_optimization/models/ftpfn.py @@ -174,7 +174,11 @@ def encode_ftpfn( [ pending_value if trial.report is None - else (error_value if trial.report.loss is None else trial.report.loss) + else ( + error_value + if trial.report.objective_to_minimize is None + else trial.report.objective_to_minimize + ) for trial in trials.values() ], device=device, diff --git a/neps/optimizers/bayesian_optimization/models/gp.py b/neps/optimizers/bayesian_optimization/models/gp.py index 681dbb71..bf01601a 100644 --- a/neps/optimizers/bayesian_optimization/models/gp.py +++ b/neps/optimizers/bayesian_optimization/models/gp.py @@ -243,8 +243,10 @@ def encode_trials_for_gp( train_configs.append(trial.config) - loss = trial.report.loss - train_losses.append(torch.nan if loss is None else loss) + objective_to_minimize = trial.report.objective_to_minimize + train_losses.append( + torch.nan if objective_to_minimize is None else objective_to_minimize + ) cost = trial.report.cost train_costs.append(torch.nan if cost is None else cost) diff --git a/neps/optimizers/bayesian_optimization/optimizer.py b/neps/optimizers/bayesian_optimization/optimizer.py index bf491e1c..3ed74fe3 100644 --- a/neps/optimizers/bayesian_optimization/optimizer.py +++ b/neps/optimizers/bayesian_optimization/optimizer.py @@ -71,7 +71,7 @@ def __init__( seed: int | None = None, budget: Any | None = None, # TODO: remove surrogate_model: Any | None = None, # TODO: remove - loss_value_on_error: Any | None = None, # TODO: remove + objective_to_minimize_value_on_error: Any | None = None, # TODO: remove cost_value_on_error: Any | None = None, # TODO: remove ignore_errors: Any | None = None, # TODO: remove ): diff --git a/neps/optimizers/multi_fidelity/hyperband.py b/neps/optimizers/multi_fidelity/hyperband.py index 10861b02..7d858528 100644 --- a/neps/optimizers/multi_fidelity/hyperband.py +++ b/neps/optimizers/multi_fidelity/hyperband.py @@ -53,7 +53,7 @@ def __init__( use_priors: bool = False, sampling_policy: Any = RandomUniformPolicy, promotion_policy: Any = SyncPromotionPolicy, - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] | None = None, @@ -70,7 +70,7 @@ def __init__( "use_priors": use_priors, "sampling_policy": sampling_policy, "promotion_policy": promotion_policy, - "loss_value_on_error": loss_value_on_error, + "objective_to_minimize_value_on_error": objective_to_minimize_value_on_error, "cost_value_on_error": cost_value_on_error, "ignore_errors": ignore_errors, "prior_confidence": prior_confidence, @@ -278,7 +278,7 @@ def __init__( initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = FixedPriorPolicy, promotion_policy: Any = SyncPromotionPolicy, - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", @@ -294,7 +294,7 @@ def __init__( use_priors=self.use_priors, # key change to the base HB class sampling_policy=sampling_policy, promotion_policy=promotion_policy, - loss_value_on_error=loss_value_on_error, + objective_to_minimize_value_on_error=objective_to_minimize_value_on_error, cost_value_on_error=cost_value_on_error, ignore_errors=ignore_errors, prior_confidence=prior_confidence, @@ -316,7 +316,7 @@ def __init__( initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = EnsemblePolicy, promotion_policy: Any = SyncPromotionPolicy, - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", @@ -331,7 +331,7 @@ def __init__( initial_design_type=initial_design_type, sampling_policy=sampling_policy, promotion_policy=promotion_policy, - loss_value_on_error=loss_value_on_error, + objective_to_minimize_value_on_error=objective_to_minimize_value_on_error, cost_value_on_error=cost_value_on_error, ignore_errors=ignore_errors, prior_confidence=prior_confidence, @@ -367,7 +367,7 @@ def __init__( use_priors: bool = False, sampling_policy: Any = RandomUniformPolicy, promotion_policy: Any = AsyncPromotionPolicy, - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] | None = None, @@ -383,7 +383,7 @@ def __init__( "use_priors": use_priors, "sampling_policy": sampling_policy, "promotion_policy": promotion_policy, - "loss_value_on_error": loss_value_on_error, + "objective_to_minimize_value_on_error": objective_to_minimize_value_on_error, "cost_value_on_error": cost_value_on_error, "ignore_errors": ignore_errors, "prior_confidence": prior_confidence, @@ -461,7 +461,7 @@ def __init__( initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = FixedPriorPolicy, promotion_policy: Any = AsyncPromotionPolicy, - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", @@ -477,7 +477,7 @@ def __init__( use_priors=self.use_priors, # key change to the base Async HB class sampling_policy=sampling_policy, promotion_policy=promotion_policy, - loss_value_on_error=loss_value_on_error, + objective_to_minimize_value_on_error=objective_to_minimize_value_on_error, cost_value_on_error=cost_value_on_error, ignore_errors=ignore_errors, prior_confidence=prior_confidence, @@ -501,7 +501,7 @@ def __init__( use_priors: bool = False, sampling_policy: Any = RandomUniformPolicy, promotion_policy: Any = AsyncPromotionPolicy, - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] | None = None, @@ -526,7 +526,7 @@ def __init__( "use_priors": use_priors, "sampling_policy": sampling_policy, "promotion_policy": promotion_policy, - "loss_value_on_error": loss_value_on_error, + "objective_to_minimize_value_on_error": objective_to_minimize_value_on_error, "cost_value_on_error": cost_value_on_error, "ignore_errors": ignore_errors, "prior_confidence": prior_confidence, diff --git a/neps/optimizers/multi_fidelity/ifbo.py b/neps/optimizers/multi_fidelity/ifbo.py index 8f873b2c..10403916 100755 --- a/neps/optimizers/multi_fidelity/ifbo.py +++ b/neps/optimizers/multi_fidelity/ifbo.py @@ -99,7 +99,7 @@ def __init__( n_acquisition_new_configs: int = 1_000, device: torch.device | None = None, budget: int | float | None = None, # TODO: Remove - loss_value_on_error: float | None = None, # TODO: Remove + objective_to_minimize_value_on_error: float | None = None, # TODO: Remove cost_value_on_error: float | None = None, # TODO: Remove ignore_errors: bool = False, # TODO: Remove ): @@ -222,7 +222,8 @@ def ask( not_pending_X = X # NOTE: Can't really abstract this, requires knowledge that: - # 1. The encoding is such that the loss is 1 - loss + # 1. The encoding is such that the objective_to_minimize is 1 - + # objective_to_minimize # 2. The budget is the second column # 3. The budget is encoded between 1/max_fid and 1 rng = np.random.RandomState(len(trials)) diff --git a/neps/optimizers/multi_fidelity/successive_halving.py b/neps/optimizers/multi_fidelity/successive_halving.py index 08a8cbc2..b070f517 100644 --- a/neps/optimizers/multi_fidelity/successive_halving.py +++ b/neps/optimizers/multi_fidelity/successive_halving.py @@ -56,7 +56,7 @@ def __init__( use_priors: bool = False, sampling_policy: Any = RandomUniformPolicy, promotion_policy: Any = SyncPromotionPolicy, - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] | None = None, @@ -78,12 +78,12 @@ def __init__( Samples generated from a Gaussian centered around the default value sampling_policy: The type of sampling procedure to use promotion_policy: The type of promotion procedure to use - loss_value_on_error: Setting this and cost_value_on_error to any float will - supress any error during bayesian optimization and will use given loss - value instead. default: None - cost_value_on_error: Setting this and loss_value_on_error to any float will - supress any error during bayesian optimization and will use given cost - value instead. default: None + objective_to_minimize_value_on_error: Setting this and cost_value_on_error to + any float will supress any error during bayesian optimization and will + use given objective_to_minimize value instead. default: None + cost_value_on_error: Setting this and objective_to_minimize_value_on_error to + any float will supress any error during bayesian optimization and will + use given cost value instead. default: None prior_confidence: The range of confidence to have on the prior The higher the confidence, the smaller is the standard deviation of the prior distribution centered around the default @@ -95,7 +95,7 @@ def __init__( super().__init__( pipeline_space=pipeline_space, budget=budget, - loss_value_on_error=loss_value_on_error, + objective_to_minimize_value_on_error=objective_to_minimize_value_on_error, cost_value_on_error=cost_value_on_error, ignore_errors=ignore_errors, ) @@ -224,7 +224,7 @@ def _load_previous_observations( ) -> None: for config_id, config_val in previous_results.items(): _config, _rung = self._get_config_id_split(config_id) - perf = self.get_loss(config_val.result) + perf = self.get_objective_to_minimize(config_val.result) if int(_config) in self.observed_configs.index: # config already recorded in dataframe rung_recorded = self.observed_configs.at[int(_config), "rung"] @@ -565,7 +565,7 @@ def __init__( initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = FixedPriorPolicy, promotion_policy: Any = SyncPromotionPolicy, - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", # medium = 0.25 @@ -582,7 +582,7 @@ def __init__( use_priors=self.use_priors, sampling_policy=sampling_policy, promotion_policy=promotion_policy, - loss_value_on_error=loss_value_on_error, + objective_to_minimize_value_on_error=objective_to_minimize_value_on_error, cost_value_on_error=cost_value_on_error, ignore_errors=ignore_errors, prior_confidence=prior_confidence, @@ -606,7 +606,7 @@ def __init__( use_priors: bool = False, sampling_policy: Any = RandomUniformPolicy, promotion_policy: Any = AsyncPromotionPolicy, # key difference from SH - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] | None = None, @@ -623,7 +623,7 @@ def __init__( use_priors=use_priors, sampling_policy=sampling_policy, promotion_policy=promotion_policy, - loss_value_on_error=loss_value_on_error, + objective_to_minimize_value_on_error=objective_to_minimize_value_on_error, cost_value_on_error=cost_value_on_error, ignore_errors=ignore_errors, prior_confidence=prior_confidence, @@ -648,7 +648,7 @@ def __init__( initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = FixedPriorPolicy, promotion_policy: Any = AsyncPromotionPolicy, # key difference from SH - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", @@ -665,7 +665,7 @@ def __init__( use_priors=self.use_priors, sampling_policy=sampling_policy, promotion_policy=promotion_policy, - loss_value_on_error=loss_value_on_error, + objective_to_minimize_value_on_error=objective_to_minimize_value_on_error, cost_value_on_error=cost_value_on_error, ignore_errors=ignore_errors, prior_confidence=prior_confidence, diff --git a/neps/optimizers/multi_fidelity/utils.py b/neps/optimizers/multi_fidelity/utils.py index 059e2ca9..bbc6557f 100644 --- a/neps/optimizers/multi_fidelity/utils.py +++ b/neps/optimizers/multi_fidelity/utils.py @@ -188,7 +188,7 @@ def extract_learning_curve( # For the first epoch we have no learning curve available if budget_id == 0: return [] - # reduce budget_id to discount the current validation loss + # reduce budget_id to discount the current validation objective_to_minimize # both during training and prediction phase budget_id = max(0, budget_id - 1) if self.lc_col_name in self.df.columns: diff --git a/neps/optimizers/multi_fidelity_prior/async_priorband.py b/neps/optimizers/multi_fidelity_prior/async_priorband.py index 7adcdd9a..1290e145 100644 --- a/neps/optimizers/multi_fidelity_prior/async_priorband.py +++ b/neps/optimizers/multi_fidelity_prior/async_priorband.py @@ -40,7 +40,7 @@ def __init__( initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = EnsemblePolicy, # key difference to ASHA promotion_policy: Any = AsyncPromotionPolicy, # key difference from SH - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", @@ -76,7 +76,7 @@ def __init__( initial_design_type=initial_design_type, sampling_policy=sampling_policy, promotion_policy=promotion_policy, - loss_value_on_error=loss_value_on_error, + objective_to_minimize_value_on_error=objective_to_minimize_value_on_error, cost_value_on_error=cost_value_on_error, ignore_errors=ignore_errors, prior_confidence=prior_confidence, @@ -148,7 +148,7 @@ def __init__( initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = EnsemblePolicy, # key difference to ASHA promotion_policy: Any = AsyncPromotionPolicy, # key difference from PB - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", @@ -185,7 +185,7 @@ def __init__( "initial_design_type": initial_design_type, "sampling_policy": sampling_policy, "promotion_policy": promotion_policy, - "loss_value_on_error": loss_value_on_error, + "objective_to_minimize_value_on_error": objective_to_minimize_value_on_error, "cost_value_on_error": cost_value_on_error, "ignore_errors": ignore_errors, "prior_confidence": prior_confidence, diff --git a/neps/optimizers/multi_fidelity_prior/priorband.py b/neps/optimizers/multi_fidelity_prior/priorband.py index ef9c6002..a689aaf4 100644 --- a/neps/optimizers/multi_fidelity_prior/priorband.py +++ b/neps/optimizers/multi_fidelity_prior/priorband.py @@ -309,7 +309,7 @@ def __init__( initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = EnsemblePolicy, promotion_policy: Any = SyncPromotionPolicy, - loss_value_on_error: None | float = None, + objective_to_minimize_value_on_error: None | float = None, cost_value_on_error: None | float = None, ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", @@ -342,7 +342,7 @@ def __init__( initial_design_type=initial_design_type, sampling_policy=sampling_policy, promotion_policy=promotion_policy, - loss_value_on_error=loss_value_on_error, + objective_to_minimize_value_on_error=objective_to_minimize_value_on_error, cost_value_on_error=cost_value_on_error, ignore_errors=ignore_errors, prior_confidence=prior_confidence, diff --git a/neps/plot/plot3D.py b/neps/plot/plot3D.py index 37618a48..e0d83598 100644 --- a/neps/plot/plot3D.py +++ b/neps/plot/plot3D.py @@ -23,7 +23,7 @@ class Plotter3D: """Plot a 3d landscape of learning curves for a given run.""" - loss_key: str = "Loss" + objective_to_minimize_key: str = "Objective to minimize" fidelity_key: str = "epochs" run_path: str | Path | None = None scatter: bool = True @@ -49,7 +49,7 @@ def __post_init__(self) -> None: ) # Assigned at prep_df stage - self.loss_range: tuple[float, float] | None = None + self.objective_to_minimize_range: tuple[float, float] | None = None self.epochs_range: tuple[float, float] | None = None @staticmethod @@ -66,7 +66,7 @@ def get_y(df: pd.DataFrame) -> np.ndarray: @staticmethod def get_z(df: pd.DataFrame) -> np.ndarray: """Get the z-axis values for the plot.""" - return df["result.loss"].to_numpy() + return df["result.objective_to_minimize"].to_numpy() @staticmethod def get_color(df: pd.DataFrame) -> np.ndarray: @@ -78,7 +78,10 @@ def prep_df(self, df: pd.DataFrame | None = None) -> pd.DataFrame: df = self.df if df is None else df _fid_key = f"config.{self.fidelity_key}" - self.loss_range = (df["result.loss"].min(), df["result.loss"].max()) # type: ignore + self.objective_to_minimize_range = ( + df["result.objective_to_minimize"].min(), + df["result.objective_to_minimize"].max(), + ) # type: ignore self.epochs_range = (df[_fid_key].min(), df[_fid_key].max()) # type: ignore split_values = np.array([[*index.split("_")] for index in df.index]) @@ -189,23 +192,26 @@ def plot3D( # noqa: N802, PLR0915 # Draw lines ax.add_collection(lc) - assert self.loss_range is not None + assert self.objective_to_minimize_range is not None assert self.epochs_range is not None ax3D.axes.set_xlim3d(left=self.epochs_range[0], right=self.epochs_range[1]) # type: ignore ax3D.axes.set_ylim3d(bottom=0, top=data_groups.ngroups) # type: ignore - ax3D.axes.set_zlim3d(bottom=self.loss_range[0], top=self.loss_range[1]) # type: ignore + ax3D.axes.set_zlim3d( + bottom=self.objective_to_minimize_range[0], + top=self.objective_to_minimize_range[1], + ) # type: ignore ax3D.set_xlabel("Epochs") ax3D.set_ylabel("Iteration sampled") - ax3D.set_zlabel(f"{self.loss_key}") # type: ignore + ax3D.set_zlabel(f"{self.objective_to_minimize_key}") # type: ignore # set view angle ax3D.view_init(elev=self.view_angle[0], azim=self.view_angle[1]) # type: ignore ax.autoscale_view() ax.set_xlabel(self.fidelity_key) - ax.set_ylabel(f"{self.loss_key}") + ax.set_ylabel(f"{self.objective_to_minimize_key}") ax.set_facecolor(self.bck_color_2d) fig.suptitle("ifBO run") diff --git a/neps/plot/read_results.py b/neps/plot/read_results.py index 06ff3f1c..24b8a288 100644 --- a/neps/plot/read_results.py +++ b/neps/plot/read_results.py @@ -62,9 +62,9 @@ def get_cost(idx: str) -> float: else: config_cost = config_result.metadata["time_end"] - global_start - # TODO(eddiebergman): Assumes it never crashed and there's a loss available, - # not fixing now but it should be addressed - losses.append(config_result.result["loss"]) # type: ignore + # TODO(eddiebergman): Assumes it never crashed and there's a + # objective_to_minimize available,not fixing now but it should be addressed + losses.append(config_result.result["objective_to_minimize"]) # type: ignore costs.append(config_cost) return list(np.minimum.accumulate(losses)), costs, max_cost diff --git a/neps/plot/tensorboard_eval.py b/neps/plot/tensorboard_eval.py index 380ad6b4..9022a825 100644 --- a/neps/plot/tensorboard_eval.py +++ b/neps/plot/tensorboard_eval.py @@ -35,7 +35,7 @@ class SummaryWriter_(SummaryWriter): # noqa: N801 - Ensures all logs are stored in the same 'tfevent' directory for better organization. - Updates metric keys to have a consistent 'Summary/' prefix for clarity. - - Improves the display of 'Loss' or 'Accuracy' on the Summary file. + - Improves the display of 'objective_to_minimize' or 'Accuracy' on the Summary file. Methods: - add_hparams: Overrides the base method to log hyperparameters and @@ -74,7 +74,7 @@ class tblogger: # noqa: N801 disable_logging: ClassVar[bool] = False - loss: ClassVar[float | None] = None + objective_to_minimize: ClassVar[float | None] = None current_epoch: ClassVar[int | None] = None write_incumbent: ClassVar[bool | None] = None @@ -377,20 +377,20 @@ def _write_hparam_config() -> None: TensorBoard writer is initialized at the correct directory. It also depends on the following global variables: - - tblogger.loss (float) + - tblogger.objective_to_minimize (float) - tblogger.config_writer (SummaryWriter_) - tblogger.config (dict) - tblogger.current_epoch (int) The function will log hyperparameter configurations along - with a metric value (either accuracy or loss) to TensorBoard + with a metric value (either accuracy or objective_to_minimize) to TensorBoard based on the given configurations. """ if not tblogger._is_initialized(): tblogger._initialize_writers() - str_name = "Loss" - str_value = tblogger.loss + str_name = "Objective to minimize" + str_value = tblogger.objective_to_minimize values = {str_name: str_value} # Just an extra safety measure @@ -411,7 +411,8 @@ def _write_hparam_config() -> None: @staticmethod def _tracking_incumbent_api() -> None: - """Track the incumbent (best) loss and log it in the TensorBoard summary. + """Track the incumbent (best) objective_to_minimize and log it in the TensorBoard + summary. Note: The function relies on the following global variables: @@ -424,7 +425,7 @@ def _tracking_incumbent_api() -> None: summary_dict = get_summary_dict(tblogger.optimizer_dir, add_details=True) incum_tracker = summary_dict["num_evaluated_configs"] - incum_val = summary_dict["best_loss"] + incum_val = summary_dict["best_objective_to_minimize"] if tblogger.summary_writer is None and tblogger.optimizer_dir is not None: tblogger.summary_writer = SummaryWriter_(tblogger.optimizer_dir / "summary") @@ -478,7 +479,7 @@ def get_status() -> bool: @staticmethod def log( - loss: float, + objective_to_minimize: float, current_epoch: int, *, writer_config_scalar: bool = True, @@ -490,9 +491,9 @@ def log( hyperparameters, and images. Args: - loss: Current loss value. + objective_to_minimize: Current objective_to_minimize value. current_epoch: Current epoch of the experiment (used as the global step). - writer_config_scalar: Displaying the loss or accuracy + writer_config_scalar: Displaying the objective_to_minimize or accuracy curve on tensorboard (default: True) writer_config_hparam: Write hyperparameters logging of the configs. write_summary_incumbent: Set to `True` for a live incumbent trajectory. @@ -502,13 +503,15 @@ def log( return tblogger.current_epoch = current_epoch - tblogger.loss = loss + tblogger.objective_to_minimize = objective_to_minimize tblogger.write_incumbent = write_summary_incumbent tblogger._initiate_internal_configurations() if writer_config_scalar: - tblogger._write_scalar_config(tag="Loss", value=loss) + tblogger._write_scalar_config( + tag="objective_to_minimize", value=objective_to_minimize + ) if writer_config_hparam: tblogger._write_hparam_config() diff --git a/neps/runtime.py b/neps/runtime.py index edb6c661..4f326535 100644 --- a/neps/runtime.py +++ b/neps/runtime.py @@ -481,8 +481,8 @@ def run(self) -> None: # noqa: C901, PLR0915 ) logger.debug("Config %s: %s", evaluated_trial.id, evaluated_trial.config) - logger.debug("Loss %s: %s", evaluated_trial.id, report.loss) - logger.debug("Cost %s: %s", evaluated_trial.id, report.loss) + logger.debug("Loss %s: %s", evaluated_trial.id, report.objective_to_minimize) + logger.debug("Cost %s: %s", evaluated_trial.id, report.objective_to_minimize) logger.debug( "Learning Curve %s: %s", evaluated_trial.id, report.learning_curve ) @@ -498,7 +498,7 @@ def _launch_runtime( # noqa: PLR0913 optimization_dir: Path, max_cost_total: float | None, ignore_errors: bool = False, - loss_value_on_error: float | None, + objective_to_minimize_value_on_error: float | None, cost_value_on_error: float | None, continue_until_max_evaluation_completed: bool, overwrite_optimization_dir: bool, @@ -536,11 +536,12 @@ def _launch_runtime( # noqa: PLR0913 else OnErrorPossibilities.RAISE_ANY_ERROR ), default_report_values=DefaultReportValues( - loss_value_on_error=loss_value_on_error, + objective_to_minimize_value_on_error=objective_to_minimize_value_on_error, cost_value_on_error=cost_value_on_error, cost_if_not_provided=None, # TODO: User can't specify yet learning_curve_on_error=None, # TODO: User can't specify yet - learning_curve_if_not_provided="loss", # report the loss as single value LC + learning_curve_if_not_provided="objective_to_minimize", # report the + # objective_to_minimize as single value LC ), max_evaluations_total=max_evaluations_total, include_in_progress_evaluations_towards_maximum=( diff --git a/neps/search_spaces/architecture/graph.py b/neps/search_spaces/architecture/graph.py index 34d01195..b7dd5b5e 100644 --- a/neps/search_spaces/architecture/graph.py +++ b/neps/search_spaces/architecture/graph.py @@ -53,7 +53,7 @@ class Graph(torch.nn.Module, nx.DiGraph): >>> graph = getFancySearchSpace() >>> graph.parse() >>> logits = graph(data) - >>> optimizer.min(loss(logits, target)) + >>> optimizer.min(objective_to_minimize(logits, target)) To update the pytorch module representation (e.g. after removing or adding some new edges), you have to unparse. Beware that this is not fast, so it should diff --git a/neps/state/_eval.py b/neps/state/_eval.py index f3153a64..915e3823 100644 --- a/neps/state/_eval.py +++ b/neps/state/_eval.py @@ -32,15 +32,17 @@ def parse_user_result( user_result: float | dict[str, Any], *, default_cost_value: float | None = None, - default_learning_curve: Literal["loss"] | list[float] | None = None, + default_learning_curve: Literal["objective_to_minimize"] | list[float] | None = None, ) -> tuple[float, float | None, list[float] | None, dict[str, Any]]: """Check if the trial has succeeded.""" if isinstance(user_result, Mapping): - extracted_loss = user_result.pop("loss", _notset) - if extracted_loss is _notset: + extracted_objective_to_minimize = user_result.pop( + "objective_to_minimize", _notset + ) + if extracted_objective_to_minimize is _notset: raise KeyError( - "The 'loss' should be provided in the evaluation result if providing" - " a dictionary." + "The 'objective_to_minimize' should be provided in the evaluation result" + " if providing a dictionary." ) extracted_cost = user_result.pop("cost", default_cost_value) @@ -56,30 +58,32 @@ def parse_user_result( else: extracted_learning_curve = default_learning_curve - if extracted_learning_curve == "loss": - extracted_learning_curve = [extracted_loss] + if extracted_learning_curve == "objective_to_minimize": + extracted_learning_curve = [extracted_objective_to_minimize] extra = user_result else: - extracted_loss = user_result + extracted_objective_to_minimize = user_result extracted_learning_curve = ( None if default_learning_curve is None else [user_result] - if default_learning_curve == "loss" + if default_learning_curve == "objective_to_minimize" else default_learning_curve ) extracted_cost = default_cost_value extra = {} - loss = _check_float(extracted_loss, "loss") + objective_to_minimize = _check_float( + extracted_objective_to_minimize, "objective_to_minimize" + ) cost = _check_float(extracted_cost, "cost") if extracted_cost is not None else None learning_curve = ( [float(v) for v in extracted_learning_curve] if extracted_learning_curve is not None else None ) - return loss, cost, learning_curve, extra + return objective_to_minimize, cost, learning_curve, extra def _eval_trial( @@ -100,7 +104,7 @@ def _eval_trial( logger.exception(e) report = trial.set_complete( report_as="crashed", - loss=default_report_values.loss_value_on_error, + objective_to_minimize=default_report_values.objective_to_minimize_value_on_error, cost=default_report_values.cost_value_on_error, learning_curve=default_report_values.learning_curve_on_error, extra=None, @@ -114,14 +118,14 @@ def _eval_trial( time_end = time.time() logger.info(f"Successful evaluation of '{trial.id}': {user_result}.") - loss, cost, learning_curve, extra = parse_user_result( + objective_to_minimize, cost, learning_curve, extra = parse_user_result( dict(user_result) if isinstance(user_result, Mapping) else user_result, default_cost_value=default_report_values.cost_if_not_provided, default_learning_curve=default_report_values.learning_curve_if_not_provided, ) report = trial.set_complete( report_as="success", - loss=loss, + objective_to_minimize=objective_to_minimize, cost=cost, learning_curve=learning_curve, err=None, diff --git a/neps/state/settings.py b/neps/state/settings.py index f34a9435..def6a230 100644 --- a/neps/state/settings.py +++ b/neps/state/settings.py @@ -11,8 +11,8 @@ class DefaultReportValues: """Values to use when an error occurs.""" - loss_value_on_error: float | None = None - """The value to use for the loss when an error occurs.""" + objective_to_minimize_value_on_error: float | None = None + """The value to use for the objective_to_minimize when an error occurs.""" cost_value_on_error: float | None = None """The value to use for the cost when an error occurs.""" @@ -23,11 +23,13 @@ class DefaultReportValues: learning_curve_on_error: list[float] | None = None """The value to use for the learning curve when an error occurs. - If `'loss'`, the learning curve will be set to the loss value but as - a list with a single value. + If `'objective_to_minimize'`, the learning curve will be set to the + objective_to_minimize value but as a list with a single value. """ - learning_curve_if_not_provided: Literal["loss"] | list[float] | None = None + learning_curve_if_not_provided: ( + Literal["objective_to_minimize"] | list[float] | None + ) = None """The value to use for the learning curve when the evaluation function does not provide one.""" diff --git a/neps/state/trial.py b/neps/state/trial.py index 75ad0664..d80c3fbc 100644 --- a/neps/state/trial.py +++ b/neps/state/trial.py @@ -65,7 +65,7 @@ class Report: """A failed report of the evaluation of a configuration.""" trial_id: str - loss: float | None + objective_to_minimize: float | None cost: float | None learning_curve: list[float] | None # TODO: Serializing a large list into yaml sucks! extra: Mapping[str, Any] @@ -81,12 +81,16 @@ def __post_init__(self) -> None: def to_deprecate_result_dict(self) -> dict[str, Any] | ERROR: """Return the report as a dictionary.""" if self.reported_as == "success": - d = {"loss": self.loss, "cost": self.cost, **self.extra} + d = { + "objective_to_minimize": self.objective_to_minimize, + "cost": self.cost, + **self.extra, + } # HACK: Backwards compatibility. Not sure how much this is needed # but it should be removed once optimizers stop calling the - # `get_loss`, `get_cost`, `get_learning_curve` methods of `BaseOptimizer` - # and just use the `Report` directly. + # `get_objective_to_minimize`, `get_cost`, `get_learning_curve` methods of + # `BaseOptimizer` and just use the `Report` directly. if "info_dict" not in d or "learning_curve" not in d["info_dict"]: d.setdefault("info_dict", {})["learning_curve"] = self.learning_curve return d @@ -94,8 +98,8 @@ def to_deprecate_result_dict(self) -> dict[str, Any] | ERROR: return "error" def __eq__(self, value: Any, /) -> bool: - # HACK : Since it could be probably that one of loss or cost is nan, - # we need a custom comparator for this object + # HACK : Since it could be probably that one of objective_to_minimize or cost is + # nan, we need a custom comparator for this object # HACK : We also have to skip over the `Err` object since when it's deserialized, # we can not recover the original object/type. if not isinstance(value, Report): @@ -110,7 +114,7 @@ def __eq__(self, value: Any, /) -> bool: if k == "err": if str(v) != str(other_v): return False - elif k in ("loss", "cost"): + elif k in ("objective_to_minimize", "cost"): if v is not None and np.isnan(v): if other_v is None or not np.isnan(other_v): return False @@ -182,7 +186,7 @@ def into_config_result( if self.report.reported_as == "success": result = { **self.report.extra, - "loss": self.report.loss, + "objective_to_minimize": self.report.objective_to_minimize, "cost": self.report.cost, } else: @@ -211,7 +215,7 @@ def set_complete( *, report_as: Literal["success", "failed", "crashed"], time_end: float, - loss: float | None, + objective_to_minimize: float | None, cost: float | None, learning_curve: list[float] | None, err: Exception | None, @@ -234,7 +238,9 @@ def set_complete( extra = {} if extra is None else extra - loss = float(loss) if loss is not None else None + objective_to_minimize = ( + float(objective_to_minimize) if objective_to_minimize is not None else None + ) cost = float(cost) if cost is not None else None if learning_curve is not None: learning_curve = [float(v) for v in learning_curve] @@ -243,7 +249,7 @@ def set_complete( trial_id=self.metadata.id, reported_as=report_as, evaluation_duration=evaluation_duration, - loss=loss, + objective_to_minimize=objective_to_minimize, cost=cost, learning_curve=learning_curve, extra=extra, diff --git a/neps/status/__main__.py b/neps/status/__main__.py index 744a3417..b1266937 100644 --- a/neps/status/__main__.py +++ b/neps/status/__main__.py @@ -1,18 +1,20 @@ """Displays status information about a working directory of a neps.run. Usage: - python -m neps.status [-h] [--best_losses] [--best_configs] [--all_configs] - working_directory + python -m neps.status [-h] [--best_objective_to_minimizees] [--best_configs] + [--all_configs] working_directory Positional arguments: working_directory The working directory given to neps.run Optional arguments: -h, --help show this help message and exit - --best_losses Show the trajectory of the best loss across evaluations - --best_configs Show the trajectory of the best configs and their losses + --best_objective_to_minimizees Show the trajectory of the best + objective_to_minimize across evaluations + --best_configs Show the trajectory of the best configs and their + objective_to_minimizees across evaluations - --all_configs Show all configs and their losses + --all_configs Show all configs and their objective_to_minimizees Note: We have to use the __main__.py construct due to the issues explained in @@ -36,14 +38,15 @@ parser.add_argument("root_directory", type=Path, help="The working directory given to neps.run") parser.add_argument( - "--best_losses", + "--best_objective_to_minimizees", action="store_true", - help="Show the trajectory of the best loss across evaluations", + help="Show the trajectory of the best objective_to_minimize across evaluations", ) parser.add_argument( "--best_configs", action="store_true", - help="Show the trajectory of the best configs and their losses across evaluations", + help="Show the trajectory of the best configs and their losses " + "across evaluations", ) parser.add_argument( "--all_configs", diff --git a/neps/status/status.py b/neps/status/status.py index 660c53f3..5f6656a5 100644 --- a/neps/status/status.py +++ b/neps/status/status.py @@ -77,7 +77,7 @@ def get_summary_dict( summary["num_pending_configs"] = len(in_progress) + len(pending) summary["num_pending_configs_with_worker"] = len(in_progress) - summary["best_loss"] = float("inf") + summary["best_objective_to_minimize"] = float("inf") summary["best_config_id"] = None summary["best_config_metadata"] = None summary["best_config"] = None @@ -85,9 +85,12 @@ def get_summary_dict( for evaluation in evaluated.values(): if evaluation.result == "error": summary["num_error"] += 1 - loss = evaluation.loss - if isinstance(loss, float) and loss < summary["best_loss"]: - summary["best_loss"] = loss + objective_to_minimize = evaluation.objective_to_minimize + if ( + isinstance(objective_to_minimize, float) + and objective_to_minimize < summary["best_objective_to_minimize"] + ): + summary["best_objective_to_minimize"] = objective_to_minimize summary["best_config"] = evaluation.config summary["best_config_id"] = evaluation.id summary["best_config_metadata"] = evaluation.metadata @@ -107,7 +110,8 @@ def status( Args: root_directory: The root directory given to neps.run. - best_losses: If true, show the trajectory of the best loss across evaluations + best_losses: If true, show the trajectory of the best objective_to_minimize + across evaluations best_configs: If true, show the trajectory of the best configs and their losses across evaluations all_configs: If true, show all configs and their losses @@ -133,29 +137,35 @@ def status( return summary["previous_results"], summary["pending_configs"] print() - print(f"Best loss: {summary['best_loss']}") + print(f"Best objective_to_minimize: {summary['best_objective_to_minimize']}") print(f"Best config id: {summary['best_config_id']}") print(f"Best config: {summary['best_config']}") if best_losses: print() - print("Best loss across evaluations:") - best_loss_trajectory = root_directory / "best_loss_trajectory.txt" - print(best_loss_trajectory.read_text(encoding="utf-8")) + print("Best objective_to_minimize across evaluations:") + best_objective_to_minimize_trajectory = ( + root_directory / "best_objective_to_minimize_trajectory.txt" + ) + print(best_objective_to_minimize_trajectory.read_text(encoding="utf-8")) if best_configs: print() print("Best configs and their losses across evaluations:") print(79 * "-") - best_loss_config = root_directory / "best_loss_with_config_trajectory.txt" - print(best_loss_config.read_text(encoding="utf-8")) + best_objective_to_minimize_config = ( + root_directory / "best_objective_to_minimize_with_config_trajectory.txt" + ) + print(best_objective_to_minimize_config.read_text(encoding="utf-8")) if all_configs: print() print("All evaluated configs and their losses:") print(79 * "-") - all_loss_config = root_directory / "all_losses_and_configs.txt" - print(all_loss_config.read_text(encoding="utf-8")) + all_objective_to_minimize_config = ( + root_directory / "all_losses_and_configs.txt" + ) + print(all_objective_to_minimize_config.read_text(encoding="utf-8")) return summary["previous_results"], summary["pending_configs"] @@ -264,7 +274,7 @@ def _get_dataframes_from_summary( "num_evaluated_configs": summary["num_evaluated_configs"], "num_pending_configs": summary["num_pending_configs"], "num_pending_configs_with_worker": summary["num_pending_configs_with_worker"], - "best_loss": summary["best_loss"], + "best_objective_to_minimize": summary["best_objective_to_minimize"], "best_config_id": summary["best_config_id"], "num_error": summary["num_error"], } @@ -309,7 +319,7 @@ def _save_data_to_csv( # Represents the last worker if int(pending_configs) == 0 and int(pending_configs_with_worker) == 0: config_data_df = config_data_df.sort_values( - by="result.loss", + by="result.objective_to_minimize", ascending=True, ) config_data_df.to_csv(config_data_file_path, index=False, mode="w") @@ -330,7 +340,7 @@ def _save_data_to_csv( # check if the current worker has more evaluated configs than the previous if int(num_evaluated_configs_csv) < num_evaluated_configs_run.iloc[0]: config_data_df = config_data_df.sort_values( - by="result.loss", + by="result.objective_to_minimize", ascending=True, ) config_data_df.to_csv(config_data_file_path, index=False, mode="w") @@ -338,7 +348,7 @@ def _save_data_to_csv( # Represents the first worker to be evaluated else: config_data_df = config_data_df.sort_values( - by="result.loss", + by="result.objective_to_minimize", ascending=True, ) config_data_df.to_csv(config_data_file_path, index=False, mode="w") diff --git a/neps/utils/cli.py b/neps/utils/cli.py index 99adc282..b475519b 100644 --- a/neps/utils/cli.py +++ b/neps/utils/cli.py @@ -32,7 +32,7 @@ SEARCHER, SEARCHER_KWARGS, IGNORE_ERROR, - LOSS_VALUE_ON_ERROR, + OBJECTIVE_TO_MINIMIZE_VALUE_ON_ERROR, COST_VALUE_ON_ERROR, CONTINUE_UNTIL_MAX_EVALUATION_COMPLETED, OVERWRITE_WORKING_DIRECTORY, @@ -231,7 +231,7 @@ def init_config(args: argparse.Namespace) -> None: continue_until_max_evaluation_completed: true # Error Handling -loss_value_on_error: +objective_to_minimize_value_on_error: cost_value_on_error: ignore_errors: @@ -316,7 +316,7 @@ def run_optimization(args: argparse.Namespace) -> None: ), MAX_COST_TOTAL: args.max_cost_total, IGNORE_ERROR: args.ignore_errors, - LOSS_VALUE_ON_ERROR: args.loss_value_on_error, + OBJECTIVE_TO_MINIMIZE_VALUE_ON_ERROR: args.objective_to_minimize_value_on_error, COST_VALUE_ON_ERROR: args.cost_value_on_error, SEARCHER: args.searcher, **kwargs, @@ -361,7 +361,7 @@ def info_config(args: argparse.Namespace) -> None: if trial.report is not None: print("\nReport:") - print(f" Loss: {trial.report.loss}") + print(f" Objective_to_minimize: {trial.report.objective_to_minimize}") print(f" Cost: {trial.report.cost}") print(f" Reported As: {trial.report.reported_as}") error = trial.report.err @@ -510,7 +510,7 @@ def status(args: argparse.Namespace) -> None: print(f"Failed Trials (Errors): {failed_trials_count}") print(f"Active Trials: {evaluating_trials_count}") print(f"Pending Trials: {pending_trials_count}") - print(f"Best Loss Achieved: {summary['best_loss']}") + print(f"Best Objective_to_minimize Achieved: {summary['best_objective_to_minimize']}") print("\nLatest Trials:") print("-----------------------------") @@ -544,7 +544,12 @@ def status(args: argparse.Namespace) -> None: # Print the header print( header_format.format( - "Sampled Time", "Duration", "Trial ID", "Worker ID", "State", "Loss" + "Sampled Time", + "Duration", + "Trial ID", + "Worker ID", + "State", + "Objective_to_minimize", ) ) @@ -562,13 +567,17 @@ def status(args: argparse.Namespace) -> None: trial_id = trial.id worker_id = trial.metadata.sampling_worker_id state = trial.state.name - loss = ( - f"{trial.report.loss:.6f}" - if (trial.report and trial.report.loss is not None) + objective_to_minimize = ( + f"{trial.report.objective_to_minimize:.6f}" + if (trial.report and trial.report.objective_to_minimize is not None) else "N/A" ) - print(row_format.format(time_sampled, duration, trial_id, worker_id, state, loss)) + print( + row_format.format( + time_sampled, duration, trial_id, worker_id, state, objective_to_minimize + ) + ) # If no specific filter is applied, print the best trial and optimizer info if not args.pending and not args.evaluating and not args.succeeded: @@ -576,7 +585,7 @@ def status(args: argparse.Namespace) -> None: print("\nBest Trial:") print("-----------------------------") print(f"ID: {summary['best_config_id']}") - print(f"Loss: {summary['best_loss']}") + print(f"Loss: {summary['best_objective_to_minimize']}") print("Config:") for key, value in summary["best_config"].items(): print(f" {key}: {value}") @@ -677,12 +686,15 @@ def load_neps_state(directory_path: Path) -> Optional[NePSState[Path]]: def compute_incumbents(sorted_trials: List[Trial]) -> List[Trial]: - """Compute the list of incumbent trials based on the best loss.""" - best_loss = float("inf") + """Compute the list of incumbent trials based on the best objective_to_minimize.""" + best_objective_to_minimize = float("inf") incumbents = [] for trial in sorted_trials: - if trial.report and trial.report.loss < best_loss: - best_loss = trial.report.loss + if ( + trial.report + and trial.report.objective_to_minimize < best_objective_to_minimize + ): + best_objective_to_minimize = trial.report.objective_to_minimize incumbents.append(trial) return incumbents[::-1] # Reverse for most recent first @@ -786,11 +798,16 @@ def display_results(directory_path: Path, incumbents: List[Trial]) -> None: print("-" * len(header)) if incumbents: for trial in incumbents: - if trial.report is not None and trial.report.loss is not None: + if ( + trial.report is not None + and trial.report.objective_to_minimize is not None + ): config = ", ".join(f"{k}: {v}" for k, v in trial.config.items()) - print(f"{trial.id:<6} {trial.report.loss:<12.6f} {config:<60}") + print( + f"{trial.id:<6} {trial.report.objective_to_minimize:<12.6f} {config:<60}" + ) else: - print(f"Trial {trial.id} has no valid loss.") + print(f"Trial {trial.id} has no valid objective_to_minimize.") else: print("No Incumbent Trials found.") @@ -804,9 +821,10 @@ def plot_incumbents( # Collect data for plotting x_values = [id_to_index[incumbent.id] for incumbent in incumbents] y_values = [ - incumbent.report.loss + incumbent.report.objective_to_minimize for incumbent in incumbents - if incumbent.report is not None and incumbent.report.loss is not None + if incumbent.report is not None + and incumbent.report.objective_to_minimize is not None ] plt.figure(figsize=(12, 6)) @@ -881,7 +899,7 @@ def print_help(args: Optional[argparse.Namespace] = None) -> None: --continue-until-max-evaluation-completed (Continue until max evaluations are completed.) --max-cost-total (Max cost before halting new evaluations.) --ignore-errors (Ignore errors during optimization.) - --loss-value-on-error (Assumed loss value on error.) + --objective_to_minimize-value-on-error (Assumed objective_to_minimize value on error.) --cost-value-on-error (Assumed cost value on error.) --searcher (Searcher algorithm key for optimization.) --searcher-kwargs ... (Additional kwargs for the searcher.) @@ -1045,7 +1063,7 @@ def handle_report_config(args: argparse.Namespace) -> None: report = trial.set_complete( report_as=args.reported_as, time_end=args.time_end, - loss=args.loss, + objective_to_minimize=args.objective_to_minimize, cost=args.cost, learning_curve=args.learning_curve, err=Exception(args.err) if args.err else None, @@ -1069,7 +1087,9 @@ def handle_report_config(args: argparse.Namespace) -> None: print(f"Trial ID: {trial.metadata.id}") print(f"Reported As: {report.reported_as}") print(f"Time Ended: {convert_timestamp(trial.metadata.time_end)}") - print(f"Loss: {report.loss if report.loss is not None else 'N/A'}") + print( + f"Loss: {report.objective_to_minimize if report.objective_to_minimize is not None else 'N/A'}" + ) print(f"Cost: {report.cost if report.cost is not None else 'N/A'}") print(f"Evaluation Duration: {format_duration(report.evaluation_duration)}") @@ -1106,7 +1126,9 @@ def load_optimizer(run_args: dict) -> Tuple[Optional[BaseOptimizer], Optional[di pipeline_space=run_args.get(PIPELINE_SPACE), max_cost_total=run_args.get(MAX_COST_TOTAL, None), ignore_errors=run_args.get(IGNORE_ERROR, False), - loss_value_on_error=run_args.get(LOSS_VALUE_ON_ERROR, None), + objective_to_minimize_value_on_error=run_args.get( + OBJECTIVE_TO_MINIMIZE_VALUE_ON_ERROR, None + ), cost_value_on_error=run_args.get(COST_VALUE_ON_ERROR, None), searcher=run_args.get(SEARCHER, "default"), **run_args.get(SEARCHER_KWARGS, {}), @@ -1269,7 +1291,7 @@ def main() -> None: default=Default(None), help="No new evaluations will start when this cost is exceeded. Requires " "returning a cost in the evaluate_pipeline function, e.g., `return dict(" - "loss=loss, cost=cost)`. (default: %(default)s)", + "objective_to_minimize=objective_to_minimize, cost=cost)`. (default: %(default)s)", ) parser_run.add_argument( "--ignore-errors", @@ -1279,7 +1301,7 @@ def main() -> None: "default)s)", ) parser_run.add_argument( - "--loss-value-on-error", + "--objective_to_minimize-value-on-error", type=float, default=Default(None), help="Loss value to assume on error. (default: %(default)s)", @@ -1373,7 +1395,9 @@ def main() -> None: default="cli", help="The worker ID for which the configuration is being sampled.", ) - report_parser.add_argument("--loss", type=float, help="Loss value of the trial") + report_parser.add_argument( + "--objective_to_minimize", type=float, help="Loss value of the trial" + ) report_parser.add_argument( "--run-args", type=str, help="Path to the YAML file containing run configurations" ) diff --git a/neps/utils/run_args.py b/neps/utils/run_args.py index 572cd6ff..c1d09dbc 100644 --- a/neps/utils/run_args.py +++ b/neps/utils/run_args.py @@ -30,7 +30,7 @@ DEVELOPMENT_STAGE_ID = "development_stage_id" TASK_ID = "task_id" CONTINUE_UNTIL_MAX_EVALUATION_COMPLETED = "continue_until_max_evaluation_completed" -LOSS_VALUE_ON_ERROR = "loss_value_on_error" +OBJECTIVE_TO_MINIMIZE_VALUE_ON_ERROR = "objective_to_minimize_value_on_error" COST_VALUE_ON_ERROR = "cost_value_on_error" IGNORE_ERROR = "ignore_errors" SEARCHER = "searcher" @@ -79,7 +79,7 @@ def get_run_args_from_yaml(path: str | Path) -> dict: TASK_ID, MAX_EVALUATIONS_PER_RUN, CONTINUE_UNTIL_MAX_EVALUATION_COMPLETED, - LOSS_VALUE_ON_ERROR, + OBJECTIVE_TO_MINIMIZE_VALUE_ON_ERROR, COST_VALUE_ON_ERROR, IGNORE_ERROR, ] @@ -415,7 +415,7 @@ def check_run_args(settings: dict) -> None: MAX_COST_TOTAL: (int, float), MAX_EVALUATIONS_PER_RUN: int, CONTINUE_UNTIL_MAX_EVALUATION_COMPLETED: bool, - LOSS_VALUE_ON_ERROR: float, + OBJECTIVE_TO_MINIMIZE_VALUE_ON_ERROR: float, COST_VALUE_ON_ERROR: float, IGNORE_ERROR: bool, SEARCHER_KWARGS: dict, @@ -527,7 +527,7 @@ def __init__(self, func_args: dict, yaml_args: Path | str | Default | None = Non self.continue_until_max_evaluation_completed = UNSET self.max_cost_total = UNSET self.ignore_errors = UNSET - self.loss_value_on_error = UNSET + self.objective_to_minimize_value_on_error = UNSET self.cost_value_on_error = UNSET self.pre_load_hooks = UNSET self.searcher = UNSET diff --git a/neps/utils/types.py b/neps/utils/types.py index f57762a5..e5fd343a 100644 --- a/neps/utils/types.py +++ b/neps/utils/types.py @@ -68,7 +68,7 @@ class _ConfigResultForStats: metadata: dict @property - def loss(self) -> float | ERROR: + def objective_to_minimize(self) -> float | ERROR: if isinstance(self.result, dict): - return float(self.result["loss"]) + return float(self.result["objective_to_minimize"]) return "error" diff --git a/neps_examples/basic_usage/hyperparameters.py b/neps_examples/basic_usage/hyperparameters.py index 04590fa1..f86a5ae4 100644 --- a/neps_examples/basic_usage/hyperparameters.py +++ b/neps_examples/basic_usage/hyperparameters.py @@ -11,8 +11,9 @@ def evaluate_pipeline(float1, float2, categorical, integer1, integer2): return evaluate_pipeline(float1, float2, categorical, integer1, integer2) def evaluate_pipeline(float1, float2, categorical, integer1, integer2): - loss = -float(np.sum([float1, float2, int(categorical), integer1, integer2])) - return loss + objective_to_minimize = -float(np.sum([float1, float2, int(categorical), integer1, integer2])) + # time.sleep(0.7) # For demonstration purposes + return objective_to_minimize pipeline_space = dict( diff --git a/neps_examples/convenience/declarative_usage/hpo_example.py b/neps_examples/convenience/declarative_usage/hpo_example.py index 8af8af2e..0e599440 100644 --- a/neps_examples/convenience/declarative_usage/hpo_example.py +++ b/neps_examples/convenience/declarative_usage/hpo_example.py @@ -60,7 +60,7 @@ def training_pipeline(num_layers, num_neurons, epochs, learning_rate, optimizer) optimizer (str): Name of the optimizer to use ('adam' or 'sgd'). Returns: - float: The average loss over the validation set after training. + float: The average objective_to_minimize over the validation set after training. Raises: KeyError: If the specified optimizer is not supported. @@ -101,20 +101,20 @@ def training_pipeline(num_layers, num_neurons, epochs, learning_rate, optimizer) for batch_idx, (data, target) in enumerate(train_loader): optimizer.zero_grad() output = model(data) - loss = criterion(output, target) - loss.backward() + objective_to_minimize = criterion(output, target) + objective_to_minimize.backward() optimizer.step() # Validation loop model.eval() - val_loss = 0 + val_objective_to_minimize = 0 with torch.no_grad(): for data, target in val_loader: output = model(data) - val_loss += criterion(output, target).item() + val_objective_to_minimize += criterion(output, target).item() - val_loss /= len(val_loader.dataset) - return val_loss + val_objective_to_minimize /= len(val_loader.dataset) + return val_objective_to_minimize if __name__ == "__main__": diff --git a/neps_examples/convenience/logging_additional_info.py b/neps_examples/convenience/logging_additional_info.py index 0b2d4c81..70b2681c 100644 --- a/neps_examples/convenience/logging_additional_info.py +++ b/neps_examples/convenience/logging_additional_info.py @@ -12,10 +12,10 @@ def run_pipeline(float1, float2, categorical, integer1, integer2): def evaluate_pipeline(float1, float2, categorical, integer1, integer2): start = time.time() - loss = -float(np.sum([float1, float2, int(categorical), integer1, integer2])) + objective_to_minimize = -float(np.sum([float1, float2, int(categorical), integer1, integer2])) end = time.time() return { - "loss": loss, + "objective_to_minimize": objective_to_minimize, "info_dict": { # Optionally include additional information as an info_dict "train_time": end - start, }, diff --git a/neps_examples/convenience/neps_tblogger_tutorial.py b/neps_examples/convenience/neps_tblogger_tutorial.py index 6044112c..f3fd8322 100644 --- a/neps_examples/convenience/neps_tblogger_tutorial.py +++ b/neps_examples/convenience/neps_tblogger_tutorial.py @@ -156,7 +156,7 @@ def forward(self, x: torch.Tensor): # misclassified images. -def loss_ev(model: nn.Module, data_loader: DataLoader) -> float: +def objective_to_minimize_ev(model: nn.Module, data_loader: DataLoader) -> float: # Set the model in evaluation mode (no gradient computation). model.eval() @@ -209,22 +209,22 @@ def training( for x, y in train_loader: optimizer.zero_grad() output = model(x) - loss = criterion(output, y) - loss.backward() + objective_to_minimize = criterion(output, y) + objective_to_minimize.backward() optimizer.step() predicted_labels = torch.argmax(output, dim=1) incorrect_mask = predicted_labels != y incorrect_images.append(x[incorrect_mask]) - # Calculate validation loss using the loss_ev function. - validation_loss = loss_ev(model, validation_loader) + # Calculate validation objective_to_minimize using the objective_to_minimize_ev function. + validation_objective_to_minimize = objective_to_minimize_ev(model, validation_loader) # Return the misclassified image by during model training. if len(incorrect_images) > 0: incorrect_images = torch.cat(incorrect_images, dim=0) - return (validation_loss, incorrect_images) + return (validation_objective_to_minimize, incorrect_images) ############################################################# @@ -274,7 +274,7 @@ def evaluate_pipeline(lr, optim, weight_decay): criterion = nn.CrossEntropyLoss() for i in range(max_epochs): - loss, miss_img = training( + objective_to_minimize, miss_img = training( optimizer=optimizer, model=model, criterion=criterion, @@ -301,10 +301,10 @@ def evaluate_pipeline(lr, optim, weight_decay): # 4. First two layer gradients passed as scalar configs. tblogger.log( - loss=loss, + objective_to_minimize=objective_to_minimize, current_epoch=i, write_summary_incumbent=False, # Set to `True` for a live incumbent trajectory. - writer_config_scalar=True, # Set to `True` for a live loss trajectory for each config. + writer_config_scalar=True, # Set to `True` for a live objective_to_minimize trajectory for each config. writer_config_hparam=True, # Set to `True` for live parallel coordinate, scatter plot matrix, and table view. # Appending extra data extra_data={ @@ -319,15 +319,15 @@ def evaluate_pipeline(lr, optim, weight_decay): scheduler.step() - print(f" Epoch {i + 1} / {max_epochs} Val Error: {loss} ") + print(f" Epoch {i + 1} / {max_epochs} Val Error: {objective_to_minimize} ") # Calculate training and test accuracy. - train_accuracy = loss_ev(model, train_loader) - test_accuracy = loss_ev(model, test_loader) + train_accuracy = objective_to_minimize_ev(model, train_loader) + test_accuracy = objective_to_minimize_ev(model, test_loader) # Return a dictionary with relevant metrics and information. return { - "loss": loss, + "objective_to_minimize": objective_to_minimize, "info_dict": { "train_accuracy": train_accuracy, "test_accuracy": test_accuracy, diff --git a/neps_examples/convenience/neps_x_lightning.py b/neps_examples/convenience/neps_x_lightning.py index f7949dfa..c3b06944 100644 --- a/neps_examples/convenience/neps_x_lightning.py +++ b/neps_examples/convenience/neps_x_lightning.py @@ -91,7 +91,7 @@ def __init__( self.n_train = n_train self.n_valid = n_valid - # Define data transformation and loss function + # Define data transformation and objective_to_minimize function self.transform = transforms.ToTensor() self.criterion = nn.NLLLoss() @@ -119,39 +119,39 @@ def common_step( self, batch: Tuple[torch.Tensor, torch.Tensor], batch_idx: int ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: """ - Perform a forward pass and compute loss, predictions, and get the ground + Perform a forward pass and compute objective_to_minimize, predictions, and get the ground truth labels for a batch of data. """ x, y = batch logits = self.forward(x) - loss = self.criterion(logits, y) + objective_to_minimize = self.criterion(logits, y) preds = torch.argmax(logits, dim=1) - return loss, preds, y + return objective_to_minimize, preds, y def training_step( self, batch: Tuple[torch.Tensor, torch.Tensor], batch_idx: int ) -> float: - loss, preds, y = self.common_step(batch, batch_idx) + objective_to_minimize, preds, y = self.common_step(batch, batch_idx) self.train_accuracy.update(preds, y) self.log_dict( - {"train_loss": loss, "train_acc": self.val_accuracy.compute()}, + {"train_objective_to_minimize": objective_to_minimize, "train_acc": self.val_accuracy.compute()}, on_epoch=True, on_step=False, prog_bar=True, ) - return loss + return objective_to_minimize def validation_step( self, batch: Tuple[torch.Tensor, torch.Tensor], batch_idx: int ) -> None: - loss, preds, y = self.common_step(batch, batch_idx) + objective_to_minimize, preds, y = self.common_step(batch, batch_idx) self.val_accuracy.update(preds, y) self.log_dict( - {"val_loss": loss, "val_acc": self.val_accuracy.compute()}, + {"val_objective_to_minimize": objective_to_minimize, "val_acc": self.val_accuracy.compute()}, on_epoch=True, on_step=False, prog_bar=True, @@ -291,7 +291,7 @@ def evaluate_pipeline(pipeline_directory, previous_pipeline_directory, **config) # Add checkpoints at the end of training checkpoint_callback = ModelCheckpoint( dirpath=checkpoint_dir, - filename="{epoch}-{val_loss:.2f}", + filename="{epoch}-{val_objective_to_minimize:.2f}", ) # Use this function to load the previous checkpoint if it exists @@ -321,7 +321,7 @@ def evaluate_pipeline(pipeline_directory, previous_pipeline_directory, **config) trainer.fit(model) train_accuracy = trainer.logged_metrics.get("train_acc", None) - val_loss = trainer.logged_metrics.get("val_loss", None) + val_objective_to_minimize = trainer.logged_metrics.get("val_objective_to_minimize", None) val_accuracy = trainer.logged_metrics.get("val_acc", None) # Test the model and retrieve test metrics @@ -330,7 +330,7 @@ def evaluate_pipeline(pipeline_directory, previous_pipeline_directory, **config) test_accuracy = trainer.logged_metrics.get("test_acc", None) return { - "loss": val_loss, + "objective_to_minimize": val_objective_to_minimize, "cost": epochs - previously_spent_epochs, "info_dict": { "train_accuracy": train_accuracy, diff --git a/neps_examples/convenience/working_directory_per_pipeline.py b/neps_examples/convenience/working_directory_per_pipeline.py index 4cce4633..ce36e929 100644 --- a/neps_examples/convenience/working_directory_per_pipeline.py +++ b/neps_examples/convenience/working_directory_per_pipeline.py @@ -18,8 +18,8 @@ def evaluate_pipeline(pipeline_directory: Path, float1, categorical, integer1): weight_file = pipeline_directory / "weight_file.txt" weight_file.write_text("0") - loss = -float(np.sum([float1, int(categorical), integer1])) - return loss + objective_to_minimize = -float(np.sum([float1, int(categorical), integer1])) + return objective_to_minimize pipeline_space = dict( diff --git a/neps_examples/efficiency/expert_priors_for_hyperparameters.py b/neps_examples/efficiency/expert_priors_for_hyperparameters.py index 352d94dc..3c85895f 100644 --- a/neps_examples/efficiency/expert_priors_for_hyperparameters.py +++ b/neps_examples/efficiency/expert_priors_for_hyperparameters.py @@ -16,7 +16,7 @@ def evaluate_pipeline(some_float, some_integer, some_cat): y = -some_float - some_integer end = time.time() return { - "loss": y, + "objective_to_minimize": y, "info_dict": { "test_score": y, "train_time": end - start, diff --git a/neps_examples/efficiency/multi_fidelity.py b/neps_examples/efficiency/multi_fidelity.py index b9848c3a..8f0eedc6 100644 --- a/neps_examples/efficiency/multi_fidelity.py +++ b/neps_examples/efficiency/multi_fidelity.py @@ -72,9 +72,9 @@ def evaluate_pipeline(pipeline_directory, previous_pipeline_directory, learning_ pipeline_directory / checkpoint_name, ) - loss = np.log(learning_rate / epoch) # Replace with actual error + objective_to_minimize = np.log(learning_rate / epoch) # Replace with actual error epochs_spent_in_this_call = epoch - epochs_previously_spent # Optional for stopping - return dict(loss=loss, cost=epochs_spent_in_this_call) + return dict(objective_to_minimize=objective_to_minimize, cost=epochs_spent_in_this_call) pipeline_space = dict( diff --git a/neps_examples/efficiency/multi_fidelity_and_expert_priors.py b/neps_examples/efficiency/multi_fidelity_and_expert_priors.py index 6ea2d8b8..c5d3c11c 100644 --- a/neps_examples/efficiency/multi_fidelity_and_expert_priors.py +++ b/neps_examples/efficiency/multi_fidelity_and_expert_priors.py @@ -11,8 +11,8 @@ def run_pipeline(float1, float2, integer1, fidelity): return evaluate_pipeline(float1, float2, integer1, fidelity) def evaluate_pipeline(float1, float2, integer1, fidelity): - loss = -float(np.sum([float1, float2, integer1])) / fidelity - return loss + objective_to_minimize = -float(np.sum([float1, float2, integer1])) / fidelity + return objective_to_minimize pipeline_space = dict( diff --git a/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py b/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py index dc4b7084..2505f431 100644 --- a/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py +++ b/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py @@ -102,7 +102,7 @@ def evaluate_pipeline(some_architecture, some_float, some_integer, some_cat): end = time.time() return { - "loss": y, + "objective_to_minimize": y, "info_dict": { "test_score": y, "train_time": end - start, diff --git a/neps_examples/experimental/freeze_thaw.py b/neps_examples/experimental/freeze_thaw.py index b4af7b40..9c63d109 100644 --- a/neps_examples/experimental/freeze_thaw.py +++ b/neps_examples/experimental/freeze_thaw.py @@ -48,7 +48,7 @@ def training_pipeline( optimizer (str): Name of the optimizer to use ('adam' or 'sgd'). Returns: - float: The average loss over the validation set after training. + float: The average objective_to_minimize over the validation set after training. Raises: KeyError: If the specified optimizer is not supported. @@ -92,19 +92,19 @@ def training_pipeline( for batch_idx, (data, target) in enumerate(train_loader): optimizer.zero_grad() output = model(data) - loss = criterion(output, target) - loss.backward() + objective_to_minimize = criterion(output, target) + objective_to_minimize.backward() optimizer.step() # Validation loop model.eval() - val_loss = 0 + val_objective_to_minimize = 0 val_correct = 0 val_total = 0 with torch.no_grad(): for data, target in val_loader: output = model(data) - val_loss += criterion(output, target).item() + val_objective_to_minimize += criterion(output, target).item() # Get the predicted class _, predicted = torch.max(output.data, 1) @@ -113,7 +113,7 @@ def training_pipeline( val_total += target.size(0) val_correct += (predicted == target).sum().item() - val_loss /= len(val_loader.dataset) + val_objective_to_minimize /= len(val_loader.dataset) val_err = 1 - val_correct / val_total # Saving checkpoint @@ -126,17 +126,17 @@ def training_pipeline( # Logging tblogger.log( - loss=val_loss, + objective_to_minimize=val_objective_to_minimize, current_epoch=epochs, # Set to `True` for a live incumbent trajectory. write_summary_incumbent=True, - # Set to `True` for a live loss trajectory for each config. + # Set to `True` for a live objective_to_minimize trajectory for each config. writer_config_scalar=True, # Set to `True` for live parallel coordinate, scatter plot matrix, and table view. writer_config_hparam=True, # Appending extra data extra_data={ - "train_loss": tblogger.scalar_logging(loss.item()), + "train_objective_to_minimize": tblogger.scalar_logging(objective_to_minimize.item()), "val_err": tblogger.scalar_logging(val_err), }, ) diff --git a/tests/regression_objectives.py b/tests/regression_objectives.py index 90adb892..eb261674 100644 --- a/tests/regression_objectives.py +++ b/tests/regression_objectives.py @@ -90,11 +90,11 @@ def cost_evaluation(**joint_configuration): results = self.benchmark(joint_configuration, nepochs=epoch) return { - "loss": 100 - results[epoch]["valid-acc"], + "objective_to_minimize": 100 - results[epoch]["valid-acc"], "cost": results[epoch]["runtime"], } - def loss_evaluation(**joint_configuration): + def objective_to_minimize_evaluation(**joint_configuration): epoch = joint_configuration.pop("epoch") joint_configuration.update({"N": 5, "W": 16, "Resolution": 1.0}) @@ -104,7 +104,7 @@ def loss_evaluation(**joint_configuration): if "cost" in self.optimizer: return cost_evaluation else: - return loss_evaluation + return objective_to_minimize_evaluation def __init__( self, @@ -188,10 +188,10 @@ def hartmann3(**z_nX): noise = np.abs(rng.normal(size=H.size)) * self.noise * (1 - log_z_scaled) - loss = float((H + noise)[0]) + objective_to_minimize = float((H + noise)[0]) cost = 0.05 + (1 - 0.05) * (z / self.z_max) ** 2 - result = {"loss": loss} + result = {"objective_to_minimize": objective_to_minimize} if "cost" in self.optimizer: result.update({"cost": cost}) @@ -247,10 +247,10 @@ def hartmann6(**z_nX): noise = np.abs(rng.normal(size=H.size)) * self.noise * (1 - log_z_scaled) - loss = float((H + noise)[0]) + objective_to_minimize = float((H + noise)[0]) cost = 0.05 + (1 - 0.05) * (z / self.z_max) ** 2 - result = {"loss": loss} + result = {"objective_to_minimize": objective_to_minimize} if "cost" in self.optimizer: result.update({"cost": cost}) diff --git a/tests/regression_runner.py b/tests/regression_runner.py index eead3639..612c74f3 100644 --- a/tests/regression_runner.py +++ b/tests/regression_runner.py @@ -112,17 +112,17 @@ def root_directory(self): @property def final_losses_path(self): - return Path(self.root_directory, self.loss_file_name) + return Path(self.root_directory, self.objective_to_minimize_file_name) @property - def loss_file_name(self): + def objective_to_minimize_file_name(self): return f"final_losses_{self.max_evaluations}_.txt" def save_losses(self): if not self.final_losses_path.parent.exists(): Path(self.root_directory).mkdir() with self.final_losses_path.open(mode="w+", encoding="utf-8") as f: - f.writelines([str(loss) + "\n" for loss in self.final_losses]) + f.writelines([str(objective_to_minimize) + "\n" for objective_to_minimize in self.final_losses]) logging.info( f"Saved the results of {len(self.final_losses)} " f"runs of {self.max_evaluations} " @@ -171,8 +171,8 @@ def read_results(self): elif self.final_losses_path.exists(): # Read from final_losses_path for each regression run self.final_losses = [ - float(loss) - for loss in self.final_losses_path.read_text( + float(objective_to_minimize) + for objective_to_minimize in self.final_losses_path.read_text( encoding="utf-8" ).splitlines()[: self.iterations] ] @@ -189,8 +189,8 @@ def read_results(self): # Try reading from the LOSS_FILE in the worst case if LOSS_FILE.exists(): with LOSS_FILE.open(mode="r", encoding="utf-8") as f: - loss_dict = json.load(f) - self.final_losses = loss_dict[self.optimizer][self.task] + objective_to_minimize_dict = json.load(f) + self.final_losses = objective_to_minimize_dict[self.optimizer][self.task] else: raise FileNotFoundError( f"Results from the previous runs are not " diff --git a/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py b/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py index 16e714f3..007a14dc 100644 --- a/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py +++ b/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py @@ -22,8 +22,8 @@ def run_pipeline(val1, val2): return evaluate_pipeline(val1, val2) def evaluate_pipeline(val1, val2): - loss = val1 * val2 - return loss + objective_to_minimize = val1 * val2 + return objective_to_minimize def run_pipeline_fidelity(val1, val2): @@ -31,8 +31,8 @@ def run_pipeline_fidelity(val1, val2): return evaluate_pipeline_fidelity(val1, val2) def evaluate_pipeline_fidelity(val1, val2): - loss = val1 * val2 - return {"loss": loss, "cost": 1} + objective_to_minimize = val1 * val2 + return {"objective_to_minimize": objective_to_minimize, "cost": 1} logging.basicConfig(level=logging.INFO) diff --git a/tests/test_neps_api/testing_scripts/default_neps.py b/tests/test_neps_api/testing_scripts/default_neps.py index 03adda4c..2d669fcf 100644 --- a/tests/test_neps_api/testing_scripts/default_neps.py +++ b/tests/test_neps_api/testing_scripts/default_neps.py @@ -29,8 +29,8 @@ def run_pipeline(val1, val2): return evaluate_pipeline(val1, val2) def evaluate_pipeline(val1, val2): - loss = val1 * val2 - return loss + objective_to_minimize = val1 * val2 + return objective_to_minimize logging.basicConfig(level=logging.INFO) diff --git a/tests/test_neps_api/testing_scripts/user_yaml_neps.py b/tests/test_neps_api/testing_scripts/user_yaml_neps.py index 448e941a..e32d84d4 100644 --- a/tests/test_neps_api/testing_scripts/user_yaml_neps.py +++ b/tests/test_neps_api/testing_scripts/user_yaml_neps.py @@ -12,8 +12,8 @@ def run_pipeline(val1, val2): warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) - loss = val1 * val2 - return loss + objective_to_minimize = val1 * val2 + return objective_to_minimize logging.basicConfig(level=logging.INFO) diff --git a/tests/test_runtime/test_default_report_values.py b/tests/test_runtime/test_default_report_values.py index 265d4c08..24ee3659 100644 --- a/tests/test_runtime/test_default_report_values.py +++ b/tests/test_runtime/test_default_report_values.py @@ -28,7 +28,7 @@ def test_default_values_on_error( settings = WorkerSettings( on_error=OnErrorPossibilities.IGNORE, default_report_values=DefaultReportValues( - loss_value_on_error=2.4, # <- Highlight + objective_to_minimize_value_on_error=2.4, # <- Highlight cost_value_on_error=2.4, # <- Highlight learning_curve_on_error=[2.4, 2.5], # <- Highlight ), @@ -67,7 +67,7 @@ def eval_function(*args, **kwargs) -> float: trial = trials.popitem()[1] assert trial.state == Trial.State.CRASHED assert trial.report is not None - assert trial.report.loss == 2.4 + assert trial.report.objective_to_minimize == 2.4 assert trial.report.cost == 2.4 assert trial.report.learning_curve == [2.4, 2.5] @@ -121,13 +121,13 @@ def eval_function(*args, **kwargs) -> float: assert trial.report.learning_curve == [2.4, 2.5] -def test_default_value_loss_curve_take_loss_value( +def test_default_value_objective_to_minimize_curve_take_objective_to_minimize_value( neps_state: NePSState, ) -> None: optimizer = RandomSearch(pipeline_space=SearchSpace(a=Float(0, 1))) settings = WorkerSettings( on_error=OnErrorPossibilities.IGNORE, - default_report_values=DefaultReportValues(learning_curve_if_not_provided="loss"), + default_report_values=DefaultReportValues(learning_curve_if_not_provided="objective_to_minimize"), max_evaluations_total=None, include_in_progress_evaluations_towards_maximum=False, max_cost_total=None, diff --git a/tests/test_runtime/test_stopping_criterion.py b/tests/test_runtime/test_stopping_criterion.py index c73051a9..cdc9313b 100644 --- a/tests/test_runtime/test_stopping_criterion.py +++ b/tests/test_runtime/test_stopping_criterion.py @@ -59,7 +59,7 @@ def eval_function(*args, **kwargs) -> float: for _, trial in trials.items(): assert trial.state == Trial.State.SUCCESS assert trial.report is not None - assert trial.report.loss == 1.0 + assert trial.report.objective_to_minimize == 1.0 # New worker has the same total number of evaluations so it should not run anything. new_worker = DefaultWorker.new( @@ -113,7 +113,7 @@ def eval_function(*args, **kwargs) -> float: for _, trial in trials.items(): assert trial.state == Trial.State.SUCCESS assert trial.report is not None - assert trial.report.loss == 1.0 + assert trial.report.objective_to_minimize == 1.0 # New worker should run 2 more evaluations new_worker = DefaultWorker.new( @@ -134,7 +134,7 @@ def eval_function(*args, **kwargs) -> float: for _, trial in trials.items(): assert trial.state == Trial.State.SUCCESS assert trial.report is not None - assert trial.report.loss == 1.0 + assert trial.report.objective_to_minimize == 1.0 def test_include_in_progress_evaluations_towards_maximum_with_work_eval_count( @@ -190,7 +190,7 @@ def eval_function(*args, **kwargs) -> float: assert the_completed_trial.state == Trial.State.SUCCESS assert the_completed_trial.report is not None - assert the_completed_trial.report.loss == 1.0 + assert the_completed_trial.report.objective_to_minimize == 1.0 def test_max_cost_total( @@ -211,7 +211,7 @@ def test_max_cost_total( ) def eval_function(*args, **kwargs) -> dict: - return {"loss": 1.0, "cost": 1.0} + return {"objective_to_minimize": 1.0, "cost": 1.0} worker = DefaultWorker.new( state=neps_state, @@ -262,7 +262,7 @@ def test_worker_cost_total( ) def eval_function(*args, **kwargs) -> dict: - return {"loss": 1.0, "cost": 1.0} + return {"objective_to_minimize": 1.0, "cost": 1.0} worker = DefaultWorker.new( state=neps_state, diff --git a/tests/test_settings/test_settings.py b/tests/test_settings/test_settings.py index cd9b5663..e943e721 100644 --- a/tests/test_settings/test_settings.py +++ b/tests/test_settings/test_settings.py @@ -38,7 +38,7 @@ "continue_until_max_evaluation_completed": Default(False), "max_cost_total": Default(None), "ignore_errors": Default(False), - "loss_value_on_error": Default(None), + "objective_to_minimize_value_on_error": Default(None), "cost_value_on_error": Default(None), "pre_load_hooks": Default(None), "searcher": Default("default"), @@ -58,7 +58,7 @@ "continue_until_max_evaluation_completed": False, "max_cost_total": None, "ignore_errors": False, - "loss_value_on_error": None, + "objective_to_minimize_value_on_error": None, "cost_value_on_error": None, "pre_load_hooks": None, "searcher": "default", @@ -80,7 +80,7 @@ "continue_until_max_evaluation_completed": Default(False), "max_cost_total": Default(None), "ignore_errors": Default(False), - "loss_value_on_error": Default(None), + "objective_to_minimize_value_on_error": Default(None), "cost_value_on_error": Default(None), "pre_load_hooks": Default(None), "searcher": Default("default"), @@ -100,7 +100,7 @@ "continue_until_max_evaluation_completed": False, "max_cost_total": None, "ignore_errors": False, - "loss_value_on_error": None, + "objective_to_minimize_value_on_error": None, "cost_value_on_error": None, "pre_load_hooks": None, "searcher": "default", @@ -122,7 +122,7 @@ "continue_until_max_evaluation_completed": Default(False), "max_cost_total": Default(None), "ignore_errors": Default(False), - "loss_value_on_error": Default(None), + "objective_to_minimize_value_on_error": Default(None), "cost_value_on_error": Default(None), "pre_load_hooks": Default(None), "searcher": Default("default"), @@ -142,7 +142,7 @@ "continue_until_max_evaluation_completed": False, "max_cost_total": None, "ignore_errors": False, - "loss_value_on_error": None, + "objective_to_minimize_value_on_error": None, "cost_value_on_error": None, "pre_load_hooks": None, "searcher": "hyperband", @@ -164,7 +164,7 @@ "continue_until_max_evaluation_completed": False, "max_cost_total": None, "ignore_errors": False, - "loss_value_on_error": None, + "objective_to_minimize_value_on_error": None, "cost_value_on_error": None, "pre_load_hooks": None, "searcher": "default", @@ -184,7 +184,7 @@ "continue_until_max_evaluation_completed": False, "max_cost_total": None, "ignore_errors": False, - "loss_value_on_error": None, + "objective_to_minimize_value_on_error": None, "cost_value_on_error": None, "pre_load_hooks": None, "searcher": "default", @@ -206,7 +206,7 @@ "continue_until_max_evaluation_completed": False, "max_cost_total": None, "ignore_errors": False, - "loss_value_on_error": None, + "objective_to_minimize_value_on_error": None, "cost_value_on_error": None, "pre_load_hooks": None, "searcher": Default("default"), @@ -232,7 +232,7 @@ "continue_until_max_evaluation_completed": False, "max_cost_total": None, "ignore_errors": False, - "loss_value_on_error": None, + "objective_to_minimize_value_on_error": None, "cost_value_on_error": None, "pre_load_hooks": None, "searcher": { @@ -268,7 +268,7 @@ "continue_until_max_evaluation_completed": Default(False), "max_cost_total": Default(None), "ignore_errors": Default(False), - "loss_value_on_error": Default(None), + "objective_to_minimize_value_on_error": Default(None), "cost_value_on_error": Default(None), "pre_load_hooks": Default(None), "searcher": Default("default"), @@ -290,7 +290,7 @@ "continue_until_max_evaluation_completed": False, "max_cost_total": None, "ignore_errors": False, - "loss_value_on_error": None, + "objective_to_minimize_value_on_error": None, "cost_value_on_error": None, "pre_load_hooks": None, "searcher": my_bayesian, @@ -331,7 +331,7 @@ def test_check_settings(func_args: dict, yaml_args: str, expected_output: dict) "continue_until_max_evaluation_completed": Default(False), "max_cost_total": Default(None), "ignore_errors": Default(False), - "loss_value_on_error": Default(None), + "objective_to_minimize_value_on_error": Default(None), "cost_value_on_error": Default(None), "pre_load_hooks": Default(None), "searcher": Default("default"), diff --git a/tests/test_state/test_synced.py b/tests/test_state/test_synced.py index 6294db37..1d002b3f 100644 --- a/tests/test_state/test_synced.py +++ b/tests/test_state/test_synced.py @@ -91,7 +91,7 @@ def case_trial_3(tmp_path: Path) -> tuple[Synced[Trial, Path], Callable[[Trial], def _update(trial: Trial) -> None: trial.set_complete( time_end=3, - loss=1, + objective_to_minimize=1, cost=1, extra={"hi": [1, 2, 3]}, learning_curve=[1], @@ -129,7 +129,7 @@ def case_trial_4(tmp_path: Path) -> tuple[Synced[Trial, Path], Callable[[Trial], def _update(trial: Trial) -> None: trial.set_complete( time_end=3, - loss=np.nan, + objective_to_minimize=np.nan, cost=np.inf, extra={"hi": [1, 2, 3]}, report_as="failed", @@ -167,7 +167,7 @@ def case_trial_5(tmp_path: Path) -> tuple[Synced[Trial, Path], Callable[[Trial], def _update(trial: Trial) -> None: trial.set_complete( time_end=3, - loss=np.nan, + objective_to_minimize=np.nan, cost=np.inf, extra={"hi": [1, 2, 3]}, learning_curve=None, @@ -231,7 +231,7 @@ def case_trial_7(tmp_path: Path) -> tuple[Synced[Trial, Path], Callable[[Trial], trial.set_evaluating(time_started=2, worker_id=1) trial.set_complete( time_end=3, - loss=np.nan, + objective_to_minimize=np.nan, cost=np.inf, extra={"hi": [1, 2, 3]}, learning_curve=[1, 2, 3], diff --git a/tests/test_state/test_trial.py b/tests/test_state/test_trial.py index a433a917..562bf2b3 100644 --- a/tests/test_state/test_trial.py +++ b/tests/test_state/test_trial.py @@ -117,7 +117,7 @@ def test_trial_as_success_after_being_progress() -> None: previous_trial = "0" sampling_worker_id = "42" evaluating_worker_id = "43" - loss = 427 + objective_to_minimize = 427 cost = -123.6 extra = {"picnic": "basket", "counts": [1, 2, 3]} @@ -134,7 +134,7 @@ def test_trial_as_success_after_being_progress() -> None: trial.set_evaluating(time_started=time_started, worker_id=evaluating_worker_id) report = trial.set_complete( report_as="success", - loss=loss, + objective_to_minimize=objective_to_minimize, cost=cost, err=None, tb=None, @@ -162,7 +162,7 @@ def test_trial_as_success_after_being_progress() -> None: ) assert report == Trial.Report( trial_id=trial_id, - loss=loss, + objective_to_minimize=objective_to_minimize, cost=cost, learning_curve=None, evaluation_duration=1, @@ -173,7 +173,7 @@ def test_trial_as_success_after_being_progress() -> None: ) -def test_trial_as_failed_with_nan_loss_and_in_cost() -> None: +def test_trial_as_failed_with_nan_objective_to_minimize_and_in_cost() -> None: trial_id = "1" time_sampled = 0 time_submitted = 1 @@ -182,7 +182,7 @@ def test_trial_as_failed_with_nan_loss_and_in_cost() -> None: previous_trial = "0" sampling_worker_id = "42" evaluating_worker_id = "43" - loss = np.nan + objective_to_minimize = np.nan cost = np.inf extra = {"picnic": "basket", "counts": [1, 2, 3]} @@ -199,7 +199,7 @@ def test_trial_as_failed_with_nan_loss_and_in_cost() -> None: trial.set_evaluating(time_started=time_started, worker_id=evaluating_worker_id) report = trial.set_complete( report_as="failed", - loss=loss, + objective_to_minimize=objective_to_minimize, cost=cost, learning_curve=None, evaluation_duration=time_end - time_started, @@ -226,7 +226,7 @@ def test_trial_as_failed_with_nan_loss_and_in_cost() -> None: ) assert report == Trial.Report( trial_id=trial_id, - loss=loss, + objective_to_minimize=objective_to_minimize, cost=cost, learning_curve=None, evaluation_duration=time_end - time_started, @@ -263,7 +263,7 @@ def test_trial_as_crashed_with_err_and_tb() -> None: trial.set_evaluating(time_started=time_started, worker_id=evaluating_worker_id) report = trial.set_complete( report_as="crashed", - loss=None, + objective_to_minimize=None, cost=None, learning_curve=None, evaluation_duration=time_end - time_started, @@ -291,7 +291,7 @@ def test_trial_as_crashed_with_err_and_tb() -> None: ) assert report == Trial.Report( trial_id=trial_id, - loss=None, + objective_to_minimize=None, cost=None, learning_curve=None, evaluation_duration=time_end - time_started, diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py b/tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py index cd89b1ca..a59f7739 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/evaluate_pipeline.py @@ -13,7 +13,7 @@ def evaluate_pipeline(learning_rate, optimizer, epochs): eval_score = np.random.choice([learning_rate, epochs], 1) else: eval_score = 5.0 - return {"loss": eval_score} + return {"objective_to_minimize": eval_score} def run_pipeline_constant(learning_rate, optimizer, epochs, batch_size): @@ -28,5 +28,5 @@ def evaluate_pipeline_constant(learning_rate, optimizer, epochs, batch_size): else: eval_score = 5.0 eval_score += batch_size - return {"loss": eval_score} + return {"objective_to_minimize": eval_score} diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py b/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py index 77fa841e..b1d18fc3 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/neps_run.py @@ -15,7 +15,7 @@ def evaluate_pipeline_constant(learning_rate, optimizer, epochs, batch_size): else: eval_score = 5.0 eval_score += batch_size - return {"loss": eval_score} + return {"objective_to_minimize": eval_score} if __name__ == "__main__": diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py b/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py index 14778024..e470580c 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py @@ -16,7 +16,7 @@ def evaluate_pipeline(learning_rate, epochs, optimizer, batch_size): else: eval_score = 5.0 eval_score += batch_size - return {"loss": eval_score} + return {"objective_to_minimize": eval_score} # For testing the functionality of loading a dictionary from a YAML configuration. diff --git a/tests/test_yaml_run_args/test_yaml_run_args.py b/tests/test_yaml_run_args/test_yaml_run_args.py index bec40d1b..7995d953 100644 --- a/tests/test_yaml_run_args/test_yaml_run_args.py +++ b/tests/test_yaml_run_args/test_yaml_run_args.py @@ -116,7 +116,7 @@ def are_functions_equivalent( "task_id": 4, "max_evaluations_per_run": 5, "continue_until_max_evaluation_completed": True, - "loss_value_on_error": 4.2, + "objective_to_minimize_value_on_error": 4.2, "cost_value_on_error": 3.7, "ignore_errors": True, "searcher": { @@ -140,7 +140,7 @@ def are_functions_equivalent( "task_id": 2.0, "max_evaluations_per_run": 5, "continue_until_max_evaluation_completed": True, - "loss_value_on_error": 2.4, + "objective_to_minimize_value_on_error": 2.4, "cost_value_on_error": 2.1, "ignore_errors": False, "searcher": { @@ -191,7 +191,7 @@ def are_functions_equivalent( "development_stage_id": 9, "max_evaluations_per_run": 5, "continue_until_max_evaluation_completed": True, - "loss_value_on_error": 2.4, + "objective_to_minimize_value_on_error": 2.4, "cost_value_on_error": 2.1, "ignore_errors": False, "searcher": BayesianOptimization, From cd08eb4756516b68bc88e6d7f1a15ea9ab136f2d Mon Sep 17 00:00:00 2001 From: Meganton Date: Tue, 31 Dec 2024 01:57:26 +0100 Subject: [PATCH 18/24] rename loss_value_on_error to objective_to_minimize_value_on_error in YAML configuration files --- docs/doc_yamls/full_configuration_template.yaml | 2 +- tests/test_settings/overwrite_run_args.yaml | 2 +- tests/test_settings/run_args_optimizer_settings.yaml | 2 +- tests/test_settings/run_args_optional.yaml | 2 +- tests/test_yaml_run_args/run_args_full.yaml | 2 +- tests/test_yaml_run_args/run_args_full_same_level.yaml | 2 +- tests/test_yaml_run_args/run_args_invalid_key.yaml | 2 +- tests/test_yaml_run_args/run_args_invalid_type.yaml | 2 +- tests/test_yaml_run_args/run_args_key_missing.yaml | 2 +- tests/test_yaml_run_args/run_args_optional_loading_format.yaml | 2 +- tests/test_yaml_run_args/run_args_partial_same_level.yaml | 2 +- tests/test_yaml_run_args/run_args_wrong_name.yaml | 2 +- tests/test_yaml_run_args/run_args_wrong_path.yaml | 2 +- .../full_configuration_template.yaml | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/doc_yamls/full_configuration_template.yaml b/docs/doc_yamls/full_configuration_template.yaml index aa1c6685..6f90e77b 100644 --- a/docs/doc_yamls/full_configuration_template.yaml +++ b/docs/doc_yamls/full_configuration_template.yaml @@ -31,7 +31,7 @@ max_evaluations_per_run: continue_until_max_evaluation_completed: false # Error Handling -loss_value_on_error: +objective_to_minimize_value_on_error: cost_value_on_error: ignore_errors: diff --git a/tests/test_settings/overwrite_run_args.yaml b/tests/test_settings/overwrite_run_args.yaml index e7291fee..e4dd91b4 100644 --- a/tests/test_settings/overwrite_run_args.yaml +++ b/tests/test_settings/overwrite_run_args.yaml @@ -31,7 +31,7 @@ max_evaluations_per_run: 6 continue_until_max_evaluation_completed: False # Error Handling -loss_value_on_error: 1.0 +objective_to_minimize_value_on_error: 1.0 cost_value_on_error: 1.0 ignore_errors: True diff --git a/tests/test_settings/run_args_optimizer_settings.yaml b/tests/test_settings/run_args_optimizer_settings.yaml index 065680da..d2daa042 100644 --- a/tests/test_settings/run_args_optimizer_settings.yaml +++ b/tests/test_settings/run_args_optimizer_settings.yaml @@ -31,7 +31,7 @@ max_evaluations_per_run: 6 continue_until_max_evaluation_completed: False # Error Handling -loss_value_on_error: 1.0 +objective_to_minimize_value_on_error: 1.0 cost_value_on_error: 1.0 ignore_errors: True diff --git a/tests/test_settings/run_args_optional.yaml b/tests/test_settings/run_args_optional.yaml index 5e46ff99..db0ef575 100644 --- a/tests/test_settings/run_args_optional.yaml +++ b/tests/test_settings/run_args_optional.yaml @@ -7,7 +7,7 @@ max_evaluations_per_run: continue_until_max_evaluation_completed: False max_evaluations_total: 11 # get ignored root_directory: "get/ignored" -loss_value_on_error: +objective_to_minimize_value_on_error: cost_value_on_error: ignore_errors: searcher: hyperband diff --git a/tests/test_yaml_run_args/run_args_full.yaml b/tests/test_yaml_run_args/run_args_full.yaml index 81433402..2bf1671f 100644 --- a/tests/test_yaml_run_args/run_args_full.yaml +++ b/tests/test_yaml_run_args/run_args_full.yaml @@ -19,7 +19,7 @@ parallelization_setup: continue_until_max_evaluation_completed: true error_handling: - loss_value_on_error: 4.2 + objective_to_minimize_value_on_error: 4.2 cost_value_on_error: 3.7 ignore_errors: true diff --git a/tests/test_yaml_run_args/run_args_full_same_level.yaml b/tests/test_yaml_run_args/run_args_full_same_level.yaml index aad3d6c7..a7b9948f 100644 --- a/tests/test_yaml_run_args/run_args_full_same_level.yaml +++ b/tests/test_yaml_run_args/run_args_full_same_level.yaml @@ -11,7 +11,7 @@ development_stage_id: 9 task_id: 2.0 max_evaluations_per_run: 5 continue_until_max_evaluation_completed: true -loss_value_on_error: 2.4 +objective_to_minimize_value_on_error: 2.4 cost_value_on_error: 2.1 ignore_errors: false searcher: diff --git a/tests/test_yaml_run_args/run_args_invalid_key.yaml b/tests/test_yaml_run_args/run_args_invalid_key.yaml index e440480b..8047f74a 100644 --- a/tests/test_yaml_run_args/run_args_invalid_key.yaml +++ b/tests/test_yaml_run_args/run_args_invalid_key.yaml @@ -19,7 +19,7 @@ parallelization_setup: continue_until_max_evaluation_completed: true error_handling: - loss_value_on_error: 4.2 + objective_to_minimize_value_on_error: 4.2 cost_value_on_error: 3.7 ignore_errors: true diff --git a/tests/test_yaml_run_args/run_args_invalid_type.yaml b/tests/test_yaml_run_args/run_args_invalid_type.yaml index 1c85b8cb..8e1f1d2d 100644 --- a/tests/test_yaml_run_args/run_args_invalid_type.yaml +++ b/tests/test_yaml_run_args/run_args_invalid_type.yaml @@ -16,7 +16,7 @@ parallelization_setup: continue_until_max_evaluation_completed: false error_handling: - loss_value_on_error: None + objective_to_minimize_value_on_error: None cost_value_on_error: None ignore_errors: None diff --git a/tests/test_yaml_run_args/run_args_key_missing.yaml b/tests/test_yaml_run_args/run_args_key_missing.yaml index e8cc72c1..660349c9 100644 --- a/tests/test_yaml_run_args/run_args_key_missing.yaml +++ b/tests/test_yaml_run_args/run_args_key_missing.yaml @@ -11,7 +11,7 @@ development_stage_id: 9 task_id: 2.0 max_evaluations_per_run: 5 continue_until_max_evaluation_completed: true -loss_value_on_error: 2.4 +objective_to_minimize_value_on_error: 2.4 cost_value_on_error: 2.1 ignore_errors: false searcher: diff --git a/tests/test_yaml_run_args/run_args_optional_loading_format.yaml b/tests/test_yaml_run_args/run_args_optional_loading_format.yaml index e01a2cf3..640c7d9d 100644 --- a/tests/test_yaml_run_args/run_args_optional_loading_format.yaml +++ b/tests/test_yaml_run_args/run_args_optional_loading_format.yaml @@ -13,7 +13,7 @@ development_stage_id: 9 task_id: max_evaluations_per_run: 5 continue_until_max_evaluation_completed: true -loss_value_on_error: 2.4 +objective_to_minimize_value_on_error: 2.4 cost_value_on_error: 2.1 ignore_errors: false searcher: # Optional Loading diff --git a/tests/test_yaml_run_args/run_args_partial_same_level.yaml b/tests/test_yaml_run_args/run_args_partial_same_level.yaml index 85cc1cbe..93198651 100644 --- a/tests/test_yaml_run_args/run_args_partial_same_level.yaml +++ b/tests/test_yaml_run_args/run_args_partial_same_level.yaml @@ -8,7 +8,7 @@ development_stage_id: None task_id: 4 max_evaluations_per_run: None continue_until_max_evaluation_completed: True -loss_value_on_error: None +objective_to_minimize_value_on_error: None ignore_errors: True searcher: pre_load_hooks: None diff --git a/tests/test_yaml_run_args/run_args_wrong_name.yaml b/tests/test_yaml_run_args/run_args_wrong_name.yaml index 1a1d98b9..c2eb7002 100644 --- a/tests/test_yaml_run_args/run_args_wrong_name.yaml +++ b/tests/test_yaml_run_args/run_args_wrong_name.yaml @@ -19,7 +19,7 @@ parallelization_setup: continue_until_max_evaluation_completed: True error_handling: - loss_value_on_error: 4.2 + objective_to_minimize_value_on_error: 4.2 cost_value_on_error: 3.7 ignore_errors: True diff --git a/tests/test_yaml_run_args/run_args_wrong_path.yaml b/tests/test_yaml_run_args/run_args_wrong_path.yaml index e9891465..b09808cc 100644 --- a/tests/test_yaml_run_args/run_args_wrong_path.yaml +++ b/tests/test_yaml_run_args/run_args_wrong_path.yaml @@ -19,7 +19,7 @@ parallelization_setup: continue_until_max_evaluation_completed: True error_handling: - loss_value_on_error: 4.2 + objective_to_minimize_value_on_error: 4.2 cost_value_on_error: 3.7 ignore_errors: True diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/full_configuration_template.yaml b/tests/test_yaml_run_args/test_declarative_usage_docs/full_configuration_template.yaml index 70df0bdb..e207a6df 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/full_configuration_template.yaml +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/full_configuration_template.yaml @@ -31,7 +31,7 @@ max_evaluations_per_run: continue_until_max_evaluation_completed: False # Error Handling -loss_value_on_error: +objective_to_minimize_value_on_error: cost_value_on_error: ignore_errors: From 5a93ec34e26d43f2c6433e6ad22d86b3b70dd163 Mon Sep 17 00:00:00 2001 From: Meganton Date: Tue, 31 Dec 2024 02:04:12 +0100 Subject: [PATCH 19/24] renamed run_pipeline in user_yaml_neps.py --- tests/test_neps_api/testing_scripts/user_yaml_neps.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_neps_api/testing_scripts/user_yaml_neps.py b/tests/test_neps_api/testing_scripts/user_yaml_neps.py index e32d84d4..135c4b35 100644 --- a/tests/test_neps_api/testing_scripts/user_yaml_neps.py +++ b/tests/test_neps_api/testing_scripts/user_yaml_neps.py @@ -12,6 +12,10 @@ def run_pipeline(val1, val2): warn("run_pipeline is deprecated, use evaluate_pipeline instead", DeprecationWarning) + return evaluate_pipeline(val1, val2) + + +def evaluate_pipeline(val1, val2): objective_to_minimize = val1 * val2 return objective_to_minimize From 34729165e2fc74477f00be5d1d18b85fea31e1bf Mon Sep 17 00:00:00 2001 From: Meganton Date: Thu, 7 Nov 2024 22:08:51 +0100 Subject: [PATCH 20/24] rename default,default_confidence to prior,prior_confidence --- neps/optimizers/initial_design.py | 2 +- neps/optimizers/multi_fidelity/ifbo.py | 4 +- .../multi_fidelity/sampling_policy.py | 2 +- .../multi_fidelity/successive_halving.py | 8 +- .../multi_fidelity_prior/priorband.py | 4 +- neps/sampling/priors.py | 6 +- .../architecture/graph_grammar.py | 4 +- .../hyperparameters/categorical.py | 56 ++++++------- .../search_spaces/hyperparameters/constant.py | 10 +-- neps/search_spaces/hyperparameters/float.py | 36 ++++----- neps/search_spaces/hyperparameters/integer.py | 34 ++++---- .../hyperparameters/numerical.py | 78 +++++++++---------- neps/search_spaces/parameter.py | 22 +++--- neps/search_spaces/search_space.py | 24 +++--- neps_examples/convenience/neps_x_lightning.py | 6 +- .../expert_priors_for_hyperparameters.py | 6 +- .../multi_fidelity_and_expert_priors.py | 6 +- ...rs_for_architecture_and_hyperparameters.py | 6 +- .../testing_scripts/default_neps.py | 6 +- tests/test_state/test_neps_state.py | 14 ++-- .../test_search_space.py | 4 +- 21 files changed, 167 insertions(+), 171 deletions(-) diff --git a/neps/optimizers/initial_design.py b/neps/optimizers/initial_design.py index ee64fd2a..139ff82d 100644 --- a/neps/optimizers/initial_design.py +++ b/neps/optimizers/initial_design.py @@ -102,7 +102,7 @@ def make_initial_design( # noqa: PLR0912, C901 if sample_default_first: # TODO: No way to pass a seed to the sampler default = { - name: hp.default if hp.default is not None else hp.sample_value() + name: hp.prior if hp.prior is not None else hp.sample_value() for name, hp in space.hyperparameters.items() } configs.append({**default, **fids()}) diff --git a/neps/optimizers/multi_fidelity/ifbo.py b/neps/optimizers/multi_fidelity/ifbo.py index 10403916..b4e90d1d 100755 --- a/neps/optimizers/multi_fidelity/ifbo.py +++ b/neps/optimizers/multi_fidelity/ifbo.py @@ -73,9 +73,9 @@ def _adjust_pipeline_space_to_match_stepsize( lower=new_lower, upper=fidelity.upper, log=fidelity.log, - default=fidelity.default, + prior=fidelity.prior, is_fidelity=True, - default_confidence=fidelity.default_confidence_choice, + prior_confidence=fidelity.prior_confidence_choice, ) return ( SearchSpace(**{**pipeline_space.hyperparameters, fidelity_name: new_fid}), diff --git a/neps/optimizers/multi_fidelity/sampling_policy.py b/neps/optimizers/multi_fidelity/sampling_policy.py index 7e883e69..dd510c1c 100644 --- a/neps/optimizers/multi_fidelity/sampling_policy.py +++ b/neps/optimizers/multi_fidelity/sampling_policy.py @@ -214,7 +214,7 @@ def sample( # noqa: PLR0912, C901, PLR0915 user_priors = False if inc is None: - inc = self.pipeline_space.from_dict(self.pipeline_space.default_config) + inc = self.pipeline_space.from_dict(self.pipeline_space.prior_config) logger.warning( "No incumbent config found, using default as the incumbent." ) diff --git a/neps/optimizers/multi_fidelity/successive_halving.py b/neps/optimizers/multi_fidelity/successive_halving.py index b070f517..f580ed3d 100644 --- a/neps/optimizers/multi_fidelity/successive_halving.py +++ b/neps/optimizers/multi_fidelity/successive_halving.py @@ -38,7 +38,7 @@ CUSTOM_FLOAT_CONFIDENCE_SCORES = dict(Float.DEFAULT_CONFIDENCE_SCORES) CUSTOM_FLOAT_CONFIDENCE_SCORES.update({"ultra": 0.05}) -CUSTOM_CATEGORICAL_CONFIDENCE_SCORES = dict(Categorical.DEFAULT_CONFIDENCE_SCORES) +CUSTOM_CATEGORICAL_CONFIDENCE_SCORES = dict(Categorical.PRIOR_CONFIDENCE_SCORES) CUSTOM_CATEGORICAL_CONFIDENCE_SCORES.update({"ultra": 8}) @@ -437,7 +437,7 @@ def get_config_and_ids(self) -> tuple[RawConfig, str, str | None]: rung_id = self.max_rung logger.info("Next config will be evaluated at target fidelity.") logger.info("Sampling the default configuration...") - config = self.pipeline_space.from_dict(self.pipeline_space.default_config) + config = self.pipeline_space.from_dict(self.pipeline_space.prior_config) elif rng.random() < self.random_interleave_prob: config = sample_one_old( self.pipeline_space, @@ -476,7 +476,7 @@ def _enhance_priors(self, confidence_score: dict[str, float] | None = None) -> N confidence = CUSTOM_FLOAT_CONFIDENCE_SCORES[self.prior_confidence] else: confidence = confidence_score["numeric"] - self.pipeline_space[k].default_confidence_score = confidence + self.pipeline_space[k].prior_confidence_score = confidence elif isinstance(v, Categorical): if confidence_score is None: confidence = CUSTOM_CATEGORICAL_CONFIDENCE_SCORES[ @@ -484,7 +484,7 @@ def _enhance_priors(self, confidence_score: dict[str, float] | None = None) -> N ] else: confidence = confidence_score["categorical"] - self.pipeline_space[k].default_confidence_score = confidence + self.pipeline_space[k].prior_confidence_score = confidence class SuccessiveHalving(SuccessiveHalvingBase): diff --git a/neps/optimizers/multi_fidelity_prior/priorband.py b/neps/optimizers/multi_fidelity_prior/priorband.py index a689aaf4..bc67c44e 100644 --- a/neps/optimizers/multi_fidelity_prior/priorband.py +++ b/neps/optimizers/multi_fidelity_prior/priorband.py @@ -91,7 +91,7 @@ def find_incumbent(self, rung: int | None = None) -> SearchSpace: else: # THIS block should not ever execute, but for runtime anomalies, if no # incumbent can be extracted, the prior is treated as the incumbent - inc = self.pipeline_space.from_dict(self.pipeline_space.default_config) + inc = self.pipeline_space.from_dict(self.pipeline_space.prior_config) logger.warning( "Treating the prior as the incumbent. " "Please check if this should not happen." @@ -259,7 +259,7 @@ def _prior_to_incumbent_ratio_dynamic(self, rung: int) -> tuple[float, float]: # requires at least eta completed configurations to begin computing scores if len(self.rung_histories[rung]["config"]) >= self.eta: # retrieve the prior - prior = self.pipeline_space.from_dict(self.pipeline_space.default_config) + prior = self.pipeline_space.from_dict(self.pipeline_space.prior_config) # retrieve the global incumbent inc = self.find_incumbent() # subsetting the top 1/eta configs from the rung diff --git a/neps/sampling/priors.py b/neps/sampling/priors.py index 550470b8..be43cb01 100644 --- a/neps/sampling/priors.py +++ b/neps/sampling/priors.py @@ -140,14 +140,14 @@ def from_parameters( for name, hp in parameters.items(): domains.append(hp.domain) - default = center_values.get(name, hp.default) + default = center_values.get(name, hp.prior) if default is None: centers.append(None) continue confidence_score = confidence_values.get( name, - _mapping[hp.default_confidence_choice], + _mapping[hp.prior_confidence_choice], ) center = hp.choices.index(default) if isinstance(hp, Categorical) else default centers.append((center, confidence_score)) @@ -283,7 +283,7 @@ def from_space( Args: space: The search space to createa a prior from. Will look - at the `.default` and `.default_confidence` of the parameters + at the `.default` and `.prior_confidence` of the parameters to create a truncated normal. Any parameters that do not have a `.default` will be covered by a uniform distribution. diff --git a/neps/search_spaces/architecture/graph_grammar.py b/neps/search_spaces/architecture/graph_grammar.py index 035a686e..e8ce9e90 100644 --- a/neps/search_spaces/architecture/graph_grammar.py +++ b/neps/search_spaces/architecture/graph_grammar.py @@ -43,7 +43,7 @@ class GraphParameter( # noqa: D101 # Essentially on the outside, we need to ensure we don't pass ih the graph object # itself DEFAULT_CONFIDENCE_SCORES: ClassVar[Mapping[str, float]] = {"not_in_use": 1.0} - default_confidence_choice = "not_in_use" + prior_confidence_choice = "not_in_use" has_prior: bool input_kwargs: dict[str, Any] @@ -186,7 +186,7 @@ def __init__( # noqa: D107, PLR0913 scope=scope, **kwargs, ) - GraphParameter.__init__(self, value=None, default=None, is_fidelity=False) + GraphParameter.__init__(self, value=None, prior=None, is_fidelity=False) self.string_tree: str = "" self._function_id: str = "" diff --git a/neps/search_spaces/hyperparameters/categorical.py b/neps/search_spaces/hyperparameters/categorical.py index 8e24690f..aa407d35 100644 --- a/neps/search_spaces/hyperparameters/categorical.py +++ b/neps/search_spaces/hyperparameters/categorical.py @@ -42,7 +42,7 @@ class Categorical(ParameterWithPrior[CategoricalTypes, CategoricalTypes]): for more details on the methods available for this class. """ - DEFAULT_CONFIDENCE_SCORES: ClassVar[Mapping[str, Any]] = { + PRIOR_CONFIDENCE_SCORES: ClassVar[Mapping[str, Any]] = { "low": 2, "medium": 4, "high": 6, @@ -52,23 +52,23 @@ def __init__( self, choices: Iterable[float | int | str], *, - default: float | int | str | None = None, - default_confidence: Literal["low", "medium", "high"] = "low", + prior: float | int | str | None = None, + prior_confidence: Literal["low", "medium", "high"] = "low", ): """Create a new `Categorical`. Args: choices: choices for the hyperparameter. - default: default value for the hyperparameter, must be in `choices=` + prior: prior value for the hyperparameter, must be in `choices=` if provided. - default_confidence: confidence score for the default value, used when + prior_confidence: confidence score for the prior value, used when condsider prior based optimization. """ choices = list(choices) if len(choices) <= 1: raise ValueError("Categorical choices must have more than one value.") - super().__init__(value=None, is_fidelity=False, default=default) + super().__init__(value=None, is_fidelity=False, prior=prior) for choice in choices: if not isinstance(choice, float | int | str): @@ -79,9 +79,9 @@ def __init__( if not all_unique(choices): raise ValueError(f"Choices must be unique but got duplicates.\n{choices}") - if default is not None and default not in choices: + if prior is not None and prior not in choices: raise ValueError( - f"Default value {default} is not in the provided choices {choices}" + f"Default value {prior} is not in the provided choices {choices}" ) self.choices = list(choices) @@ -91,14 +91,14 @@ def __init__( # currently we do a list.index() operation which is O(n). # However for small sized categoricals this is likely faster than # a lookup table. - # For now we can just cache the index of the value and default. + # For now we can just cache the index of the value and prior. self._value_index: int | None = None - self.default_confidence_choice = default_confidence - self.default_confidence_score = self.DEFAULT_CONFIDENCE_SCORES[default_confidence] - self.has_prior = self.default is not None - self._default_index: int | None = ( - self.choices.index(default) if default is not None else None + self.prior_confidence_choice = prior_confidence + self.prior_confidence_score = self.PRIOR_CONFIDENCE_SCORES[prior_confidence] + self.has_prior = self.prior is not None + self._prior_index: int | None = ( + self.choices.index(prior) if prior is not None else None ) self.domain = Domain.indices(len(self.choices)) @@ -106,8 +106,8 @@ def __init__( def clone(self) -> Self: clone = self.__class__( choices=self.choices, - default=self.default, - default_confidence=self.default_confidence_choice, # type: ignore + prior=self.prior, + prior_confidence=self.prior_confidence_choice, # type: ignore ) if self.value is not None: clone.set_value(self.value) @@ -122,26 +122,26 @@ def __eq__(self, other: Any) -> bool: self.choices == other.choices and self.value == other.value and self.is_fidelity == other.is_fidelity - and self.default == other.default + and self.prior == other.prior and self.has_prior == other.has_prior - and self.default_confidence_score == other.default_confidence_score + and self.prior_confidence_score == other.prior_confidence_score ) def __repr__(self) -> str: return f"" def _compute_user_prior_probabilities(self) -> npt.NDArray[f64]: - # The default value should have "default_confidence_score" more probability + # The prior value should have "prior_confidence_score" more probability # than all the other values. - assert self._default_index is not None + assert self._prior_index is not None probabilities = np.ones(len(self.choices)) - probabilities[self._default_index] = self.default_confidence_score + probabilities[self._prior_index] = self.prior_confidence_score return probabilities / np.sum(probabilities) @override def sample_value(self, *, user_priors: bool = False) -> Any: indices = np.arange(len(self.choices)) - if user_priors and self.default is not None: + if user_priors and self.prior is not None: probabilities = self._compute_user_prior_probabilities() return self.choices[np.random.choice(indices, p=probabilities)] @@ -179,16 +179,16 @@ def __init__( self, choices: Iterable[float | int | str], *, - default: float | int | str | None = None, - default_confidence: Literal["low", "medium", "high"] = "low", + prior: float | int | str | None = None, + prior_confidence: Literal["low", "medium", "high"] = "low", ): """Initialize a deprecated `CategoricalParameter`. Args: choices: choices for the hyperparameter. - default: default value for the hyperparameter, must be in `choices=` + prior: prior value for the hyperparameter, must be in `choices=` if provided. - default_confidence: confidence score for the default value, used when + prior_confidence: confidence score for the prior value, used when condsider prior based optimization. Raises: @@ -207,6 +207,6 @@ def __init__( ) super().__init__( choices=choices, - default=default, - default_confidence=default_confidence, + prior=prior, + prior_confidence=prior_confidence, ) diff --git a/neps/search_spaces/hyperparameters/constant.py b/neps/search_spaces/hyperparameters/constant.py index 2dab7bfd..155ddc9e 100644 --- a/neps/search_spaces/hyperparameters/constant.py +++ b/neps/search_spaces/hyperparameters/constant.py @@ -27,12 +27,12 @@ class Constant(Parameter[T, T]): !!! note As the name suggests, the value of a `Constant` only have one - value and so its [`.default`][neps.search_spaces.parameter.Parameter.default] + value and so its [`.prior`][neps.search_spaces.parameter.Parameter.prior] and [`.value`][neps.search_spaces.parameter.Parameter.value] should always be the same. This also implies that the - [`.default`][neps.search_spaces.parameter.Parameter.default] can never be `None`. + [`.prior`][neps.search_spaces.parameter.Parameter.prior] can never be `None`. Please use [`.set_constant_value()`][neps.search_spaces.hyperparameters.constant.Constant.set_constant_value] @@ -45,7 +45,7 @@ def __init__(self, value: T): Args: value: value for the hyperparameter. """ - super().__init__(value=value, default=value, is_fidelity=False) # type: ignore + super().__init__(value=value, prior=value, is_fidelity=False) # type: ignore self._value: T = value # type: ignore @override @@ -84,7 +84,7 @@ def set_value(self, value: T | None) -> None: [`.set_constant_value()`][neps.search_spaces.hyperparameters.constant.Constant.set_constant_value] which can be used to set both the [`.value`][neps.search_spaces.parameter.Parameter.value] - and the [`.default`][neps.search_spaces.parameter.Parameter.default] at once + and the [`.prior`][neps.search_spaces.parameter.Parameter.prior] at once Args: value: value to set the parameter to. @@ -94,7 +94,7 @@ def set_value(self, value: T | None) -> None: """ if value != self._value: raise ValueError( - f"Constant does not allow chaning the set value. " + f"Constant does not allow changing the set value. " f"Tried to set value to {value}, but it is already {self.value}" ) diff --git a/neps/search_spaces/hyperparameters/float.py b/neps/search_spaces/hyperparameters/float.py index f9003024..fef72f68 100644 --- a/neps/search_spaces/hyperparameters/float.py +++ b/neps/search_spaces/hyperparameters/float.py @@ -51,8 +51,8 @@ def __init__( *, log: bool = False, is_fidelity: bool = False, - default: Number | None = None, - default_confidence: Literal["low", "medium", "high"] = "low", + prior: Number | None = None, + prior_confidence: Literal["low", "medium", "high"] = "low", ): """Create a new `Float`. @@ -61,16 +61,16 @@ def __init__( upper: upper bound for the hyperparameter. log: whether the hyperparameter is on a log scale. is_fidelity: whether the hyperparameter is fidelity. - default: default value for the hyperparameter. - default_confidence: confidence score for the default value, used when + prior: prior value for the hyperparameter. + prior_confidence: confidence score for the prior value, used when condsidering prior based optimization.. """ super().__init__( lower=float(lower), upper=float(upper), log=log, - default=float(default) if default is not None else None, - default_confidence=default_confidence, + prior=float(prior) if prior is not None else None, + prior_confidence=prior_confidence, is_fidelity=is_fidelity, domain=Domain.floating(lower, upper, log=log), ) @@ -82,8 +82,8 @@ def clone(self) -> Self: upper=self.upper, log=self.log, is_fidelity=self.is_fidelity, - default=self.default, - default_confidence=self.default_confidence_choice, + prior=self.prior, + prior_confidence=self.prior_confidence_choice, ) if self.value is not None: clone.set_value(self.value) @@ -100,7 +100,7 @@ def set_value(self, value: float | None) -> None: if not self.lower <= value <= self.upper: cls_name = self.__class__.__name__ raise ValueError( - f"{cls_name} parameter: default bounds error. Expected lower <= default" + f"{cls_name} parameter: prior bounds error. Expected lower <= prior" f" <= upper, but got lower={self.lower}, value={value}," f" upper={self.upper}" ) @@ -114,13 +114,13 @@ def sample_value(self, *, user_priors: bool = False) -> float: if self.log: assert self.log_bounds is not None low, high = self.log_bounds - default = self.log_default + prior = self.log_prior else: - low, high, default = self.lower, self.upper, self.default + low, high, prior = self.lower, self.upper, self.prior if user_priors and self.has_prior: dist, std = self._get_truncnorm_prior_and_std() - value = dist.rvs() * std + default + value = dist.rvs() * std + prior else: value = np.random.uniform(low=low, high=high) @@ -171,8 +171,8 @@ def __init__( *, log: bool = False, is_fidelity: bool = False, - default: Number | None = None, - default_confidence: Literal["low", "medium", "high"] = "low", + prior: Number | None = None, + prior_confidence: Literal["low", "medium", "high"] = "low", ): """Initialize a deprecated `FloatParameter`. @@ -181,8 +181,8 @@ def __init__( upper: upper bound for the hyperparameter. log: whether the hyperparameter is on a log scale. is_fidelity: whether the hyperparameter is fidelity. - default: default value for the hyperparameter. - default_confidence: confidence score for the default value, used when + prior: prior value for the hyperparameter. + prior_confidence: confidence score for the prior value, used when condsidering prior based optimization.. Raises: @@ -204,6 +204,6 @@ def __init__( upper=upper, log=log, is_fidelity=is_fidelity, - default=default, - default_confidence=default_confidence, + prior=prior, + prior_confidence=prior_confidence, ) diff --git a/neps/search_spaces/hyperparameters/integer.py b/neps/search_spaces/hyperparameters/integer.py index 2644cd94..0386032d 100644 --- a/neps/search_spaces/hyperparameters/integer.py +++ b/neps/search_spaces/hyperparameters/integer.py @@ -47,8 +47,8 @@ def __init__( *, log: bool = False, is_fidelity: bool = False, - default: Number | None = None, - default_confidence: Literal["low", "medium", "high"] = "low", + prior: Number | None = None, + prior_confidence: Literal["low", "medium", "high"] = "low", ): """Create a new `Integer`. @@ -57,8 +57,8 @@ def __init__( upper: upper bound for the hyperparameter. log: whether the hyperparameter is on a log scale. is_fidelity: whether the hyperparameter is fidelity. - default: default value for the hyperparameter. - default_confidence: confidence score for the default value, used when + prior: prior value for the hyperparameter. + prior_confidence: confidence score for the prior value, used when condsider prior based optimization. """ lower = int(np.rint(lower)) @@ -75,8 +75,8 @@ def __init__( upper=int(np.rint(upper)), log=log, is_fidelity=is_fidelity, - default=int(np.rint(default)) if default is not None else None, - default_confidence=default_confidence, + prior=int(np.rint(prior)) if prior is not None else None, + prior_confidence=prior_confidence, domain=Domain.integer(lower, upper, log=log), ) @@ -88,8 +88,8 @@ def __init__( upper=self.upper + 0.499999, log=self.log, is_fidelity=is_fidelity, - default=default, - default_confidence=default_confidence, + prior=prior, + prior_confidence=prior_confidence, ) def __repr__(self) -> str: @@ -102,8 +102,8 @@ def clone(self) -> Self: upper=self.upper, log=self.log, is_fidelity=self.is_fidelity, - default=self.default, - default_confidence=self.default_confidence_choice, + prior=self.prior, + prior_confidence=self.prior_confidence_choice, ) if self.value is not None: clone.set_value(self.value) @@ -125,7 +125,7 @@ def set_value(self, value: int | None) -> None: if not self.lower <= value <= self.upper: cls_name = self.__class__.__name__ raise ValueError( - f"{cls_name} parameter: default bounds error. Expected lower <= default" + f"{cls_name} parameter: prior bounds error. Expected lower <= prior" f" <= upper, but got lower={self.lower}, value={value}," f" upper={self.upper}" ) @@ -164,8 +164,8 @@ def __init__( *, log: bool = False, is_fidelity: bool = False, - default: Number | None = None, - default_confidence: Literal["low", "medium", "high"] = "low", + prior: Number | None = None, + prior_confidence: Literal["low", "medium", "high"] = "low", ): """Initialize a deprecated `IntegerParameter`. @@ -174,8 +174,8 @@ def __init__( upper: upper bound for the hyperparameter. log: whether the hyperparameter is on a log scale. is_fidelity: whether the hyperparameter is fidelity. - default: default value for the hyperparameter. - default_confidence: confidence score for the default value, used when + prior: prior value for the hyperparameter. + prior_confidence: confidence score for the prior value, used when condsider prior based optimization. Raises: @@ -197,6 +197,6 @@ def __init__( upper=upper, log=log, is_fidelity=is_fidelity, - default=default, - default_confidence=default_confidence, + prior=prior, + prior_confidence=prior_confidence, ) diff --git a/neps/search_spaces/hyperparameters/numerical.py b/neps/search_spaces/hyperparameters/numerical.py index 45774195..037f0be9 100644 --- a/neps/search_spaces/hyperparameters/numerical.py +++ b/neps/search_spaces/hyperparameters/numerical.py @@ -13,7 +13,7 @@ base class for both of these hyperparameters, and includes methods from both [`ParameterWithPrior`][neps.search_spaces.ParameterWithPrior], allowing you to set a confidence along with a -[`.default`][neps.search_spaces.Parameter.default] that can be used +[`.prior`][neps.search_spaces.Parameter.prior] that can be used with certain algorithms. """ @@ -44,11 +44,11 @@ def _get_truncnorm_prior_and_std( low: int | float, high: int | float, - default: int | float, + prior: int | float, confidence_score: float, ) -> tuple[TruncNorm, float]: std = (high - low) * confidence_score - a, b = (low - default) / std, (high - default) / std + a, b = (low - prior) / std, (high - prior) / std return scipy.stats.truncnorm(a, b), float(std) @@ -60,10 +60,10 @@ class Numerical(ParameterWithPrior[T, T]): upper: The upper bound of the numerical hyperparameter. log: Whether the hyperparameter is in log space. log_bounds: The log bounds of the hyperparameter, if `log=True`. - log_default: The log default value of the hyperparameter, if `log=True` - and a `default` is set. - default_confidence_choice: The default confidence choice. - default_confidence_score: The default confidence score. + log_prior: The log prior value of the hyperparameter, if `log=True` + and a `prior` is set. + prior_confidence_choice: The prior confidence choice. + prior_confidence_score: The prior confidence score. has_prior: Whether the hyperparameter has a prior. """ @@ -75,10 +75,10 @@ def __init__( upper: T, *, log: bool = False, - default: T | None, + prior: T | None, is_fidelity: bool, domain: Domain[T], - default_confidence: Literal["low", "medium", "high"] = "low", + prior_confidence: Literal["low", "medium", "high"] = "low", ): """Initialize the numerical hyperparameter. @@ -86,12 +86,12 @@ def __init__( lower: The lower bound of the numerical hyperparameter. upper: The upper bound of the numerical hyperparameter. log: Whether the hyperparameter is in log space. - default: The default value of the hyperparameter. + prior: The prior value of the hyperparameter. is_fidelity: Whether the hyperparameter is a fidelity parameter. domain: The domain of the hyperparameter. - default_confidence: The default confidence choice. + prior_confidence: The prior confidence choice. """ - super().__init__(value=None, default=default, is_fidelity=is_fidelity) # type: ignore + super().__init__(value=None, prior=prior, is_fidelity=is_fidelity) # type: ignore _cls_name = self.__class__.__name__ if lower >= upper: raise ValueError( @@ -105,18 +105,18 @@ def __init__( f" Actual values: lower={lower}, upper={upper}" ) - if default is not None and not lower <= default <= upper: + if prior is not None and not lower <= prior <= upper: raise ValueError( - f"Float parameter: default bounds error. Expected lower <= default" - f" <= upper, but got lower={lower}, default={default}," + f"Float parameter: prior bounds error. Expected lower <= prior" + f" <= upper, but got lower={lower}, prior={prior}," f" upper={upper}" ) - if default_confidence not in self.DEFAULT_CONFIDENCE_SCORES: + if prior_confidence not in self.DEFAULT_CONFIDENCE_SCORES: raise ValueError( - f"{_cls_name} parameter: default confidence score error. Expected one of " + f"{_cls_name} parameter: prior confidence score error. Expected one of " f"{list(self.DEFAULT_CONFIDENCE_SCORES.keys())}, but got " - f"{default_confidence}" + f"{prior_confidence}" ) if is_fidelity and (lower <= 0 or upper <= 0): @@ -139,21 +139,17 @@ def __init__( self.log: bool = log self.domain: Domain[T] = domain self.log_bounds: tuple[float, float] | None = None - self.log_default: float | None = None + self.log_prior: float | None = None if self.log: self.log_bounds = (float(np.log(lower)), float(np.log(upper))) - self.log_default = ( - float(np.log(self.default)) if self.default is not None else None - ) + self.log_prior = float(np.log(self.prior)) if self.prior is not None else None - self.default_confidence_choice: Literal["low", "medium", "high"] = ( - default_confidence - ) + self.prior_confidence_choice: Literal["low", "medium", "high"] = prior_confidence - self.default_confidence_score: float = self.DEFAULT_CONFIDENCE_SCORES[ - default_confidence + self.prior_confidence_score: float = self.DEFAULT_CONFIDENCE_SCORES[ + prior_confidence ] - self.has_prior: bool = self.default is not None + self.has_prior: bool = self.prior is not None @override def __eq__(self, other: Any) -> bool: @@ -166,25 +162,25 @@ def __eq__(self, other: Any) -> bool: and self.log == other.log and self.is_fidelity == other.is_fidelity and self.value == other.value - and self.default == other.default - and self.default_confidence_score == other.default_confidence_score + and self.prior == other.prior + and self.prior_confidence_score == other.prior_confidence_score ) def _get_truncnorm_prior_and_std(self) -> tuple[TruncNorm, float]: if self.log: assert self.log_bounds is not None low, high = self.log_bounds - default = self.log_default + prior = self.log_prior else: low, high = self.lower, self.upper - default = self.default + prior = self.prior - assert default is not None + assert prior is not None return _get_truncnorm_prior_and_std( low=low, high=high, - default=default, - confidence_score=self.default_confidence_score, + prior=prior, + confidence_score=self.prior_confidence_score, ) @@ -201,10 +197,10 @@ def __init__( upper: T, *, log: bool = False, - default: T | None, + prior: T | None, is_fidelity: bool, domain: Domain[T], - default_confidence: Literal["low", "medium", "high"] = "low", + prior_confidence: Literal["low", "medium", "high"] = "low", ): """Initialize a deprecated `NumericalParameter`. @@ -212,10 +208,10 @@ def __init__( lower: The lower bound of the numerical hyperparameter. upper: The upper bound of the numerical hyperparameter. log: Whether the hyperparameter is in log space. - default: The default value of the hyperparameter. + prior: The prior value of the hyperparameter. is_fidelity: Whether the hyperparameter is a fidelity parameter. domain: The domain of the hyperparameter. - default_confidence: The default confidence choice. + prior_confidence: The prior confidence choice. Raises: DeprecationWarning: A warning indicating that `neps.NumericalParameter` is @@ -235,8 +231,8 @@ def __init__( lower=lower, upper=upper, log=log, - default=default, + prior=prior, is_fidelity=is_fidelity, domain=domain, - default_confidence=default_confidence, + prior_confidence=prior_confidence, ) diff --git a/neps/search_spaces/parameter.py b/neps/search_spaces/parameter.py index ea94a84d..f8b763cb 100644 --- a/neps/search_spaces/parameter.py +++ b/neps/search_spaces/parameter.py @@ -30,7 +30,7 @@ class Parameter(ABC, Generic[ValueT, SerializedT]): """A base class for hyperparameters. Attributes: - default: default value for the hyperparameter. This value + prior: default value for the hyperparameter. This value is used as a prior to inform algorithms about a decent default value for the hyperparameter, as well as use attributes from [`ParameterWithPrior`][neps.search_spaces.ParameterWithPrior], @@ -44,17 +44,17 @@ def __init__( self, *, value: ValueT | None, - default: ValueT | None, + prior: ValueT | None, is_fidelity: bool, ): """Create a new `Parameter`. Args: value: value for the hyperparameter. - default: default value for the hyperparameter. + prior: default value for the hyperparameter. is_fidelity: whether the hyperparameter is fidelity. """ - self.default = default + self.prior = prior self.is_fidelity = is_fidelity # TODO(eddiebergman): The reason to have this not as a straight alone @@ -69,7 +69,7 @@ def __init__( ) # TODO: Pass in through subclasses - self.default_confidence_score: float + self.prior_confidence_score: float # TODO(eddiebergman): All this does is just check values which highly unlikely # what we want. However this needs to be tackled in a seperate PR. @@ -165,16 +165,16 @@ class ParameterWithPrior(Parameter[ValueT, SerializedT]): """A base class for hyperparameters with priors. Attributes: - default_confidence_choice: The choice of how confident any algorithm should - be in the default value being a good value. - default_confidence_score: A score used by algorithms to utilize the default value. + prior_confidence_choice: The choice of how confident any algorithm should + be in the prior value being a good value. + prior_confidence_score: A score used by algorithms to utilize the prior value. has_prior: whether the hyperparameter has a prior that can be used by an - algorithm. In many cases, this refers to having a default value. + algorithm. In many cases, this refers to having a prior value. """ DEFAULT_CONFIDENCE_SCORES: ClassVar[Mapping[str, float]] - default_confidence_choice: str - default_confidence_score: float + prior_confidence_choice: str + prior_confidence_score: float has_prior: bool # NOTE(eddiebergman): Like the normal `Parameter.sample` but with `user_priors`. diff --git a/neps/search_spaces/search_space.py b/neps/search_spaces/search_space.py index a1566733..3cb69b85 100644 --- a/neps/search_spaces/search_space.py +++ b/neps/search_spaces/search_space.py @@ -61,26 +61,26 @@ def pipeline_space_from_configspace( elif isinstance(hyperparameter, CS.CategoricalHyperparameter): parameter = Categorical( hyperparameter.choices, - default=hyperparameter.default_value, + prior=hyperparameter.default_value, ) elif isinstance(hyperparameter, CS.OrdinalHyperparameter): parameter = Categorical( hyperparameter.sequence, - default=hyperparameter.default_value, + prior=hyperparameter.default_value, ) elif isinstance(hyperparameter, CS.UniformIntegerHyperparameter): parameter = Integer( lower=hyperparameter.lower, upper=hyperparameter.upper, log=hyperparameter.log, - default=hyperparameter.default_value, + prior=hyperparameter.default_value, ) elif isinstance(hyperparameter, CS.UniformFloatHyperparameter): parameter = Float( lower=hyperparameter.lower, upper=hyperparameter.upper, log=hyperparameter.log, - default=hyperparameter.default_value, + prior=hyperparameter.default_value, ) else: raise ValueError(f"Unknown hyperparameter type {hyperparameter}") @@ -219,27 +219,27 @@ def __init__(self, **hyperparameters: Parameter): # noqa: C901, PLR0912 self.fidelity_name: str | None = _fidelity_name self.has_prior: bool = _has_prior - self.default_config = {} + self.prior_config = {} for name, hp in _hyperparameters: - if hp.default is not None: - self.default_config[name] = hp.default + if hp.prior is not None: + self.prior_config[name] = hp.prior continue match hp: case Categorical(): first_choice = hp.choices[0] - self.default_config[name] = first_choice + self.prior_config[name] = first_choice case Integer() | Float(): if hp.is_fidelity: - self.default_config[name] = hp.upper + self.prior_config[name] = hp.upper continue midpoint = hp.domain.cast_one(0.5, frm=UNIT_FLOAT_DOMAIN) - self.default_config[name] = midpoint + self.prior_config[name] = midpoint case Constant(): - self.default_config[name] = hp.value + self.prior_config[name] = hp.value case GraphParameter(): - self.default_config[name] = hp.default + self.prior_config[name] = hp.prior case _: raise TypeError(f"Unknown hyperparameter type {hp}") diff --git a/neps_examples/convenience/neps_x_lightning.py b/neps_examples/convenience/neps_x_lightning.py index c3b06944..8e019957 100644 --- a/neps_examples/convenience/neps_x_lightning.py +++ b/neps_examples/convenience/neps_x_lightning.py @@ -252,11 +252,11 @@ def search_space() -> dict: space = dict( data_dir=neps.Constant("./data"), batch_size=neps.Constant(64), - lr=neps.Float(lower=1e-5, upper=1e-2, log=True, default=1e-3), + lr=neps.Float(lower=1e-5, upper=1e-2, log=True, prior=1e-3), weight_decay=neps.Float( - lower=1e-5, upper=1e-3, log=True, default=5e-4 + lower=1e-5, upper=1e-3, log=True, prior=5e-4 ), - optimizer=neps.Categorical(choices=["Adam", "SGD"], default="Adam"), + optimizer=neps.Categorical(choices=["Adam", "SGD"], prior="Adam"), epochs=neps.Integer(lower=1, upper=9, log=False, is_fidelity=True), ) return space diff --git a/neps_examples/efficiency/expert_priors_for_hyperparameters.py b/neps_examples/efficiency/expert_priors_for_hyperparameters.py index 3c85895f..e85802ba 100644 --- a/neps_examples/efficiency/expert_priors_for_hyperparameters.py +++ b/neps_examples/efficiency/expert_priors_for_hyperparameters.py @@ -28,13 +28,13 @@ def evaluate_pipeline(some_float, some_integer, some_cat): # that speeds up the search pipeline_space = dict( some_float=neps.Float( - lower=1, upper=1000, log=True, default=900, default_confidence="medium" + lower=1, upper=1000, log=True, prior=900, prior_confidence="medium" ), some_integer=neps.Integer( - lower=0, upper=50, default=35, default_confidence="low" + lower=0, upper=50, prior=35, prior_confidence="low" ), some_cat=neps.Categorical( - choices=["a", "b", "c"], default="a", default_confidence="high" + choices=["a", "b", "c"], prior="a", prior_confidence="high" ), ) diff --git a/neps_examples/efficiency/multi_fidelity_and_expert_priors.py b/neps_examples/efficiency/multi_fidelity_and_expert_priors.py index c5d3c11c..6a7655b0 100644 --- a/neps_examples/efficiency/multi_fidelity_and_expert_priors.py +++ b/neps_examples/efficiency/multi_fidelity_and_expert_priors.py @@ -17,13 +17,13 @@ def evaluate_pipeline(float1, float2, integer1, fidelity): pipeline_space = dict( float1=neps.Float( - lower=1, upper=1000, log=False, default=600, default_confidence="medium" + lower=1, upper=1000, log=False, prior=600, prior_confidence="medium" ), float2=neps.Float( - lower=-10, upper=10, default=0, default_confidence="medium" + lower=-10, upper=10, prior=0, prior_confidence="medium" ), integer1=neps.Integer( - lower=0, upper=50, default=35, default_confidence="low" + lower=0, upper=50, prior=35, prior_confidence="low" ), fidelity=neps.Integer(lower=1, upper=10, is_fidelity=True), ) diff --git a/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py b/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py index 2505f431..073f6992 100644 --- a/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py +++ b/neps_examples/experimental/expert_priors_for_architecture_and_hyperparameters.py @@ -119,13 +119,13 @@ def evaluate_pipeline(some_architecture, some_float, some_integer, some_cat): prior=prior_distr, ), some_float=neps.Float( - lower=1, upper=1000, log=True, default=900, default_confidence="medium" + lower=1, upper=1000, log=True, prior=900, prior_confidence="medium" ), some_integer=neps.Integer( - lower=0, upper=50, default=35, default_confidence="low" + lower=0, upper=50, prior=35, prior_confidence="low" ), some_cat=neps.Categorical( - choices=["a", "b", "c"], default="a", default_confidence="high" + choices=["a", "b", "c"], prior="a", prior_confidence="high" ), ) diff --git a/tests/test_neps_api/testing_scripts/default_neps.py b/tests/test_neps_api/testing_scripts/default_neps.py index 2d669fcf..c0c0905b 100644 --- a/tests/test_neps_api/testing_scripts/default_neps.py +++ b/tests/test_neps_api/testing_scripts/default_neps.py @@ -4,13 +4,13 @@ import neps pipeline_space_fidelity_priors = dict( - val1=neps.Float(lower=-10, upper=10, default=1), + val1=neps.Float(lower=-10, upper=10, prior=1), val2=neps.Integer(lower=1, upper=5, is_fidelity=True), ) pipeline_space_not_fidelity_priors = dict( - val1=neps.Float(lower=-10, upper=10, default=1), - val2=neps.Integer(lower=1, upper=5, default=1), + val1=neps.Float(lower=-10, upper=10, prior=1), + val2=neps.Integer(lower=1, upper=5, prior=1), ) pipeline_space_fidelity = dict( diff --git a/tests/test_state/test_neps_state.py b/tests/test_state/test_neps_state.py index 51773fdb..65f01210 100644 --- a/tests/test_state/test_neps_state.py +++ b/tests/test_state/test_neps_state.py @@ -49,20 +49,20 @@ def case_search_space_with_fid() -> SearchSpace: @case def case_search_space_no_fid_with_prior() -> SearchSpace: return SearchSpace( - a=Float(0, 1, default=0.5), - b=Categorical(["a", "b", "c"], default="a"), + a=Float(0, 1, prior=0.5), + b=Categorical(["a", "b", "c"], prior="a"), c=Constant("a"), - d=Integer(0, 10, default=5), + d=Integer(0, 10, prior=5), ) @case def case_search_space_fid_with_prior() -> SearchSpace: return SearchSpace( - a=Float(0, 1, default=0.5), - b=Categorical(["a", "b", "c"], default="a"), + a=Float(0, 1, prior=0.5), + b=Categorical(["a", "b", "c"], prior="a"), c=Constant("a"), - d=Integer(0, 10, default=5), + d=Integer(0, 10, prior=5), e=Integer(1, 10, is_fidelity=True), ) @@ -126,7 +126,7 @@ def optimizer_and_key(key: str, search_space: SearchSpace) -> tuple[BaseOptimize if key in JUST_SKIP: pytest.xfail(f"{key} is not instantiable") - if key in REQUIRES_PRIOR and search_space.hyperparameters["a"].default is None: + if key in REQUIRES_PRIOR and search_space.hyperparameters["a"].prior is None: pytest.xfail(f"{key} requires a prior") if len(search_space.fidelities) > 0 and key in OPTIMIZER_FAILS_WITH_FIDELITY: diff --git a/tests/test_yaml_search_space/test_search_space.py b/tests/test_yaml_search_space/test_search_space.py index 6d0b8c5c..08a08cc6 100644 --- a/tests/test_yaml_search_space/test_search_space.py +++ b/tests/test_yaml_search_space/test_search_space.py @@ -43,11 +43,11 @@ def test_correct_including_priors_yaml_file(): BASE_PATH + "correct_config_including_priors.yml" ) assert isinstance(pipeline_space, dict) - float1 = Float(0.00001, 0.1, log=True, is_fidelity=False, default=3.3e-2, default_confidence="high") + float1 = Float(0.00001, 0.1, log=True, is_fidelity=False, prior=3.3e-2, prior_confidence="high") assert float1.__eq__(pipeline_space["learning_rate"]) is True int1 = Integer(3, 30, log=False, is_fidelity=True) assert int1.__eq__(pipeline_space["num_epochs"]) is True - cat1 = Categorical(["adam", 90e-3, "rmsprop"], default=90e-3, default_confidence="medium") + cat1 = Categorical(["adam", 90e-3, "rmsprop"], prior=90e-3, prior_confidence="medium") assert cat1.__eq__(pipeline_space["optimizer"]) is True const1 = Constant(1e3) assert const1.__eq__(pipeline_space["dropout_rate"]) is True From d06b76ff03f2bbe5804f83aa36799e49a66b27d4 Mon Sep 17 00:00:00 2001 From: Meganton Date: Tue, 31 Dec 2024 03:15:05 +0100 Subject: [PATCH 21/24] rename default and default_confidence to prior and prior_confidence in YAML configuration files --- docs/doc_yamls/pipeline_space.yaml | 12 ++++++------ neps/optimizers/default_searchers/ifbo.yaml | 2 +- .../test_declarative_usage_docs/pipeline_space.yaml | 10 +++++----- .../search_space_with_priors.yaml | 8 ++++---- .../correct_config_including_priors.yml | 8 ++++---- .../default_not_in_range_config.yaml | 2 +- .../default_value_not_in_choices_config.yaml | 2 +- .../not_boolean_type_is_fidelity_cat_config.yaml | 2 +- .../not_boolean_type_is_fidelity_float_config.yaml | 2 +- .../not_boolean_type_log_config.yaml | 2 +- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/docs/doc_yamls/pipeline_space.yaml b/docs/doc_yamls/pipeline_space.yaml index 939a5358..8f877b98 100644 --- a/docs/doc_yamls/pipeline_space.yaml +++ b/docs/doc_yamls/pipeline_space.yaml @@ -3,8 +3,8 @@ learning_rate: lower: 1e-5 upper: 1e-1 log: true # Log scale for learning rate - default: 1e-2 - default_confidence: "medium" + prior: 1e-2 + prior_confidence: "medium" epochs: lower: 5 upper: 20 @@ -12,10 +12,10 @@ epochs: dropout_rate: lower: 0.1 upper: 0.5 - default: 0.2 - default_confidence: "high" + prior: 0.2 + prior_confidence: "high" optimizer: choices: [adam, sgd, adamw] - default: adam - # if default confidence is not defined it gets its default 'low' + prior: adam + # if prior confidence is not defined it gets its default 'low' batch_size: 64 diff --git a/neps/optimizers/default_searchers/ifbo.yaml b/neps/optimizers/default_searchers/ifbo.yaml index dda4ee8c..bbbd3abe 100644 --- a/neps/optimizers/default_searchers/ifbo.yaml +++ b/neps/optimizers/default_searchers/ifbo.yaml @@ -3,7 +3,7 @@ surrogate_model_args: version: "0.0.1" target_path: null # Defaults to current_working_directory/.model step_size: 1 # Step size to use for partial evaluations -use_priors: false # Whether to use priors set through `default` and `default_confidence` +use_priors: false # Whether to use priors set through `prior` and `prior_confidence` sample_default_first: false # Whether to sample the default configuration first sample_default_at_target: false # Whether to evaluate the default at the maximum fidelity or not initial_design_size: "ndim" # How many initial samples to try before using the model diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/pipeline_space.yaml b/tests/test_yaml_run_args/test_declarative_usage_docs/pipeline_space.yaml index f8c7a2aa..274d5387 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/pipeline_space.yaml +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/pipeline_space.yaml @@ -3,15 +3,15 @@ learning_rate: lower: 1e-5 upper: 1e-1 log: True # Log scale for learning rate - default: 1e-2 - default_confidence: "medium" + prior: 1e-2 + prior_confidence: "medium" epochs: lower: 5 upper: 20 - default: 10 + prior: 10 is_fidelity: True optimizer: choices: [adam, sgd, adamw] - default: adam - default_confidence: low + prior: adam + prior_confidence: low batch_size: 64 diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/search_space_with_priors.yaml b/tests/test_yaml_run_args/test_run_args_by_neps_run/search_space_with_priors.yaml index ede66cc7..5e8b1d38 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/search_space_with_priors.yaml +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/search_space_with_priors.yaml @@ -6,10 +6,10 @@ learning_rate: lower: 1e-6 upper: 1e-1 log: False - default: 1e-3 - default_confidence: "low" + prior: 1e-3 + prior_confidence: "low" optimizer: choices: ["a", "b", "c"] - default: "b" - default_confidence: "high" + prior: "b" + prior_confidence: "high" batch_size: 64 diff --git a/tests/test_yaml_search_space/correct_config_including_priors.yml b/tests/test_yaml_search_space/correct_config_including_priors.yml index 1c771110..305cb3aa 100644 --- a/tests/test_yaml_search_space/correct_config_including_priors.yml +++ b/tests/test_yaml_search_space/correct_config_including_priors.yml @@ -2,8 +2,8 @@ learning_rate: lower: 0.00001 upper: 0.1 log: true - default: 3.3E-2 - default_confidence: high + prior: 3.3E-2 + prior_confidence: high num_epochs: lower: 3 @@ -12,7 +12,7 @@ num_epochs: optimizer: choices: [adam, 90E-3, rmsprop] - default: 90E-3 - default_confidence: "medium" + prior: 0.09 + prior_confidence: "medium" dropout_rate: 1E3 diff --git a/tests/test_yaml_search_space/default_not_in_range_config.yaml b/tests/test_yaml_search_space/default_not_in_range_config.yaml index a7803821..e0ec7d58 100644 --- a/tests/test_yaml_search_space/default_not_in_range_config.yaml +++ b/tests/test_yaml_search_space/default_not_in_range_config.yaml @@ -1,6 +1,6 @@ param_float1: lower: 0.00001 upper: 0.1 - default: 0.0000000001 +prior: 0.0000000001 log: false is_fidelity: true diff --git a/tests/test_yaml_search_space/default_value_not_in_choices_config.yaml b/tests/test_yaml_search_space/default_value_not_in_choices_config.yaml index dbd6d31e..bc2e76d5 100644 --- a/tests/test_yaml_search_space/default_value_not_in_choices_config.yaml +++ b/tests/test_yaml_search_space/default_value_not_in_choices_config.yaml @@ -1,3 +1,3 @@ cat1: choices: ["a", "b", "c"] - default: "d" + prior: "d" diff --git a/tests/test_yaml_search_space/not_boolean_type_is_fidelity_cat_config.yaml b/tests/test_yaml_search_space/not_boolean_type_is_fidelity_cat_config.yaml index 1705900d..34427085 100644 --- a/tests/test_yaml_search_space/not_boolean_type_is_fidelity_cat_config.yaml +++ b/tests/test_yaml_search_space/not_boolean_type_is_fidelity_cat_config.yaml @@ -1,4 +1,4 @@ cat1: choices: ["a", "b", "c"] is_fidelity: fals - default: "c" + prior: "c" diff --git a/tests/test_yaml_search_space/not_boolean_type_is_fidelity_float_config.yaml b/tests/test_yaml_search_space/not_boolean_type_is_fidelity_float_config.yaml index 91f80f69..729f6191 100644 --- a/tests/test_yaml_search_space/not_boolean_type_is_fidelity_float_config.yaml +++ b/tests/test_yaml_search_space/not_boolean_type_is_fidelity_float_config.yaml @@ -1,6 +1,6 @@ param_float1: lower: 0.00001 upper: 0.1 - default: 0.001 + prior: 0.001 log: false is_fidelity: truee diff --git a/tests/test_yaml_search_space/not_boolean_type_log_config.yaml b/tests/test_yaml_search_space/not_boolean_type_log_config.yaml index 97848fad..c8ad4c47 100644 --- a/tests/test_yaml_search_space/not_boolean_type_log_config.yaml +++ b/tests/test_yaml_search_space/not_boolean_type_log_config.yaml @@ -1,6 +1,6 @@ param_float1: lower: 0.00001 upper: 0.1 - default: 0.001 + prior: 0.001 log: falsee is_fidelity: true From 43f2a14d63b0fde8444c03e5f44ab3fdba2d65af Mon Sep 17 00:00:00 2001 From: Meganton Date: Tue, 31 Dec 2024 03:27:21 +0100 Subject: [PATCH 22/24] rename sample_default_first to sample_prior_first --- docs/doc_yamls/set_up_optimizer.yaml | 2 +- docs/reference/optimizers.md | 2 +- .../bayesian_optimization/optimizer.py | 8 +-- neps/optimizers/default_searchers/asha.yaml | 4 +- .../default_searchers/asha_prior.yaml | 4 +- .../bayesian_optimization.yaml | 2 +- .../default_searchers/hyperband.yaml | 4 +- neps/optimizers/default_searchers/ifbo.yaml | 4 +- .../optimizers/default_searchers/mobster.yaml | 4 +- neps/optimizers/default_searchers/pibo.yaml | 2 +- .../default_searchers/priorband.yaml | 4 +- .../default_searchers/priorband_bo.yaml | 4 +- .../default_searchers/successive_halving.yaml | 4 +- .../successive_halving_prior.yaml | 4 +- neps/optimizers/initial_design.py | 10 ++-- neps/optimizers/multi_fidelity/hyperband.py | 50 +++++++++---------- neps/optimizers/multi_fidelity/ifbo.py | 12 ++--- .../multi_fidelity/successive_halving.py | 46 ++++++++--------- .../multi_fidelity_prior/async_priorband.py | 16 +++--- .../multi_fidelity_prior/priorband.py | 8 +-- .../solution_yamls/bo_neps_decided.yaml | 2 +- .../hyperband_neps_decided.yaml | 4 +- .../solution_yamls/pibo_neps_decided.yaml | 2 +- .../priorband_bo_user_decided.yaml | 4 +- .../priorband_neps_decided.yaml | 4 +- .../solution_yamls/user_yaml_bo.yaml | 2 +- .../testing_yaml/optimizer_test.yaml | 2 +- .../run_args_optimizer_settings.yaml | 4 +- tests/test_settings/test_settings.py | 12 ++--- .../set_up_optimizer.yaml | 2 +- .../config_priorband_with_args.yaml | 4 +- .../test_run_args_by_neps_run/neps_run.py | 4 +- .../hyperband_searcher_kwargs_yaml_args.yaml | 4 +- .../priorband_args_run_args.yaml | 4 +- .../optimizer_yamls/select_bo_run_args.yaml | 2 +- 35 files changed, 125 insertions(+), 125 deletions(-) diff --git a/docs/doc_yamls/set_up_optimizer.yaml b/docs/doc_yamls/set_up_optimizer.yaml index 90b52671..94922d78 100644 --- a/docs/doc_yamls/set_up_optimizer.yaml +++ b/docs/doc_yamls/set_up_optimizer.yaml @@ -2,4 +2,4 @@ strategy: bayesian_optimization # Specific arguments depending on the searcher initial_design_size: 7 use_priors: true -sample_default_first: false +sample_prior_first: false diff --git a/docs/reference/optimizers.md b/docs/reference/optimizers.md index 7750edc0..26e8a0d7 100644 --- a/docs/reference/optimizers.md +++ b/docs/reference/optimizers.md @@ -69,7 +69,7 @@ log_prior_weighted: false random_interleave_prob: 0.1 disable_priors: false prior_confidence: high -sample_default_first: false +sample_prior_first: false ``` ```python diff --git a/neps/optimizers/bayesian_optimization/optimizer.py b/neps/optimizers/bayesian_optimization/optimizer.py index 3ed74fe3..b95e0680 100644 --- a/neps/optimizers/bayesian_optimization/optimizer.py +++ b/neps/optimizers/bayesian_optimization/optimizer.py @@ -65,7 +65,7 @@ def __init__( use_priors: bool = False, use_cost: bool = False, cost_on_log_scale: bool = True, - sample_default_first: bool = False, + sample_prior_first: bool = False, device: torch.device | None = None, encoder: ConfigEncoder | None = None, seed: int | None = None, @@ -92,7 +92,7 @@ def __init__( If using `cost`, cost must be provided in the reports of the trials. cost_on_log_scale: Whether to use the log of the cost when using cost. - sample_default_first: Whether to sample the default configuration first. + sample_prior_first: Whether to sample the default configuration first. seed: Seed to use for the random number generator of samplers. device: Device to use for the optimization. encoder: Encoder to use for encoding the configurations. If None, it will @@ -126,7 +126,7 @@ def __init__( self.use_priors = use_priors self.cost_on_log_scale = cost_on_log_scale self.device = device - self.sample_default_first = sample_default_first + self.sample_prior_first = sample_prior_first self.n_initial_design = initial_design_size self.init_design: list[dict[str, Any]] | None = None @@ -145,7 +145,7 @@ def ask( self.init_design = make_initial_design( space=space, encoder=self.encoder, - sample_default_first=self.sample_default_first, + sample_prior_first=self.sample_prior_first, sampler=self.prior if self.prior is not None else "sobol", seed=None, # TODO: Seeding sample_size=( diff --git a/neps/optimizers/default_searchers/asha.yaml b/neps/optimizers/default_searchers/asha.yaml index 0b140484..5a4fcc82 100644 --- a/neps/optimizers/default_searchers/asha.yaml +++ b/neps/optimizers/default_searchers/asha.yaml @@ -5,8 +5,8 @@ early_stopping_rate: 0 initial_design_type: max_budget use_priors: false random_interleave_prob: 0.0 -sample_default_first: false -sample_default_at_target: false +sample_prior_first: false +sample_prior_at_target: false # Arguments that can not be modified by the user # sampling_policy: RandomUniformPolicy diff --git a/neps/optimizers/default_searchers/asha_prior.yaml b/neps/optimizers/default_searchers/asha_prior.yaml index 95bacb6c..4122c797 100644 --- a/neps/optimizers/default_searchers/asha_prior.yaml +++ b/neps/optimizers/default_searchers/asha_prior.yaml @@ -5,8 +5,8 @@ early_stopping_rate: 0 initial_design_type: max_budget prior_confidence: medium # or {"low", "high"} random_interleave_prob: 0.0 -sample_default_first: false -sample_default_at_target: false +sample_prior_first: false +sample_prior_at_target: false # Arguments that can not be modified by the user # sampling_policy: FixedPriorPolicy diff --git a/neps/optimizers/default_searchers/bayesian_optimization.yaml b/neps/optimizers/default_searchers/bayesian_optimization.yaml index 2c34a3a3..49e9fbae 100644 --- a/neps/optimizers/default_searchers/bayesian_optimization.yaml +++ b/neps/optimizers/default_searchers/bayesian_optimization.yaml @@ -3,5 +3,5 @@ strategy: bayesian_optimization initial_design_size: null # Defaults to depending on number or hyperparameters use_cost: false # Whether to factor in cost when selecting new configurations use_priors: false # Whether to use user set priors in optimization -sample_default_first: false # Whether to sample the default configuration first +sample_prior_first: false # Whether to sample the default configuration first device: null # Device to load the gaussian process model on with torch diff --git a/neps/optimizers/default_searchers/hyperband.yaml b/neps/optimizers/default_searchers/hyperband.yaml index b560af48..77bfd5a8 100644 --- a/neps/optimizers/default_searchers/hyperband.yaml +++ b/neps/optimizers/default_searchers/hyperband.yaml @@ -4,8 +4,8 @@ eta: 3 initial_design_type: max_budget use_priors: false random_interleave_prob: 0.0 -sample_default_first: false -sample_default_at_target: false +sample_prior_first: false +sample_prior_at_target: false # Arguments that can not be modified by the user # sampling_policy: RandomUniformPolicy diff --git a/neps/optimizers/default_searchers/ifbo.yaml b/neps/optimizers/default_searchers/ifbo.yaml index bbbd3abe..3e9ecb2b 100644 --- a/neps/optimizers/default_searchers/ifbo.yaml +++ b/neps/optimizers/default_searchers/ifbo.yaml @@ -4,8 +4,8 @@ surrogate_model_args: target_path: null # Defaults to current_working_directory/.model step_size: 1 # Step size to use for partial evaluations use_priors: false # Whether to use priors set through `prior` and `prior_confidence` -sample_default_first: false # Whether to sample the default configuration first -sample_default_at_target: false # Whether to evaluate the default at the maximum fidelity or not +sample_prior_first: false # Whether to sample the default configuration first +sample_prior_at_target: false # Whether to evaluate the default at the maximum fidelity or not initial_design_size: "ndim" # How many initial samples to try before using the model n_acquisition_new_configs: 1_000 # Number samples of new configs to include during acqusition device: null # Device to load the model on with torch diff --git a/neps/optimizers/default_searchers/mobster.yaml b/neps/optimizers/default_searchers/mobster.yaml index 42941b33..d1f0ed0a 100644 --- a/neps/optimizers/default_searchers/mobster.yaml +++ b/neps/optimizers/default_searchers/mobster.yaml @@ -4,8 +4,8 @@ eta: 3 initial_design_type: max_budget use_priors: false random_interleave_prob: 0.0 -sample_default_first: false -sample_default_at_target: false +sample_prior_first: false +sample_prior_at_target: false # arguments for model surrogate_model: gp diff --git a/neps/optimizers/default_searchers/pibo.yaml b/neps/optimizers/default_searchers/pibo.yaml index cac0e8f8..eb44b8b2 100644 --- a/neps/optimizers/default_searchers/pibo.yaml +++ b/neps/optimizers/default_searchers/pibo.yaml @@ -3,5 +3,5 @@ strategy: pibo initial_design_size: null # Defaults to depending on number or hyperparameters use_cost: false # Whether to factor in cost when selecting new configurations use_priors: true # Whether to use user set priors in optimization -sample_default_first: true # Whether to sample the default configuration first +sample_prior_first: true # Whether to sample the default configuration first device: null # Device to load the gaussian process model on with torch diff --git a/neps/optimizers/default_searchers/priorband.yaml b/neps/optimizers/default_searchers/priorband.yaml index 5d9dac86..3bb2dcc5 100644 --- a/neps/optimizers/default_searchers/priorband.yaml +++ b/neps/optimizers/default_searchers/priorband.yaml @@ -4,8 +4,8 @@ eta: 3 initial_design_type: max_budget prior_confidence: medium # or {"low", "high"} random_interleave_prob: 0.0 -sample_default_first: true -sample_default_at_target: false +sample_prior_first: true +sample_prior_at_target: false prior_weight_type: geometric inc_sample_type: mutation inc_mutation_rate: 0.5 diff --git a/neps/optimizers/default_searchers/priorband_bo.yaml b/neps/optimizers/default_searchers/priorband_bo.yaml index 104ff99e..49083df2 100644 --- a/neps/optimizers/default_searchers/priorband_bo.yaml +++ b/neps/optimizers/default_searchers/priorband_bo.yaml @@ -4,8 +4,8 @@ eta: 3 initial_design_type: max_budget prior_confidence: medium # or {"low", "high"} random_interleave_prob: 0.0 -sample_default_first: true -sample_default_at_target: false +sample_prior_first: true +sample_prior_at_target: false prior_weight_type: geometric inc_sample_type: mutation inc_mutation_rate: 0.5 diff --git a/neps/optimizers/default_searchers/successive_halving.yaml b/neps/optimizers/default_searchers/successive_halving.yaml index d7d20c9f..038e56ef 100644 --- a/neps/optimizers/default_searchers/successive_halving.yaml +++ b/neps/optimizers/default_searchers/successive_halving.yaml @@ -5,8 +5,8 @@ early_stopping_rate: 0 initial_design_type: max_budget use_priors: false random_interleave_prob: 0.0 -sample_default_first: false -sample_default_at_target: false +sample_prior_first: false +sample_prior_at_target: false # Arguments that can not be modified by the user # sampling_policy: RandomUniformPolicy diff --git a/neps/optimizers/default_searchers/successive_halving_prior.yaml b/neps/optimizers/default_searchers/successive_halving_prior.yaml index 7778fffd..2b198f7b 100644 --- a/neps/optimizers/default_searchers/successive_halving_prior.yaml +++ b/neps/optimizers/default_searchers/successive_halving_prior.yaml @@ -5,8 +5,8 @@ early_stopping_rate: 0 initial_design_type: max_budget prior_confidence: medium # or {"low", "high"} random_interleave_prob: 0.0 -sample_default_first: false -sample_default_at_target: false +sample_prior_first: false +sample_prior_at_target: false # Arguments that can not be modified by the user # sampling_policy: FixedPriorPolicy diff --git a/neps/optimizers/initial_design.py b/neps/optimizers/initial_design.py index 139ff82d..74c9c309 100644 --- a/neps/optimizers/initial_design.py +++ b/neps/optimizers/initial_design.py @@ -19,7 +19,7 @@ def make_initial_design( # noqa: PLR0912, C901 encoder: ConfigEncoder, sampler: Literal["sobol", "prior", "uniform"] | Sampler, sample_size: int | Literal["ndim"] | None = "ndim", - sample_default_first: bool = True, + sample_prior_first: bool = True, sample_fidelity: ( Literal["min", "max", True] | int | float | dict[str, int | float] ) = True, @@ -44,9 +44,9 @@ def make_initial_design( # noqa: PLR0912, C901 If "ndim", the number of configs will be equal to the number of dimensions. If None, no configurations will be sampled. - sample_default_first: Whether to sample the default configuration first. + sample_prior_first: Whether to sample the prior configuration first. sample_fidelity: - At what fidelity to sample the configurations, including the default. + At what fidelity to sample the configurations, including the prior. If set to "min" or "max", the configuration will be sampled at the minimum or maximum fidelity, respectively. If set to an integer @@ -95,11 +95,11 @@ def make_initial_design( # noqa: PLR0912, C901 fids = lambda: sample_fidelity case _: raise ValueError( - "Invalid value for `sample_default_at_target`. " + "Invalid value for `sample_prior_at_target`. " "Expected 'min', 'max', True, int, float, or dict." ) - if sample_default_first: + if sample_prior_first: # TODO: No way to pass a seed to the sampler default = { name: hp.prior if hp.prior is not None else hp.sample_value() diff --git a/neps/optimizers/multi_fidelity/hyperband.py b/neps/optimizers/multi_fidelity/hyperband.py index 7d858528..f4c2cd54 100644 --- a/neps/optimizers/multi_fidelity/hyperband.py +++ b/neps/optimizers/multi_fidelity/hyperband.py @@ -58,8 +58,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] | None = None, random_interleave_prob: float = 0.0, - sample_default_first: bool = False, - sample_default_at_target: bool = False, + sample_prior_first: bool = False, + sample_prior_at_target: bool = False, ): args = { "pipeline_space": pipeline_space, @@ -75,8 +75,8 @@ def __init__( "ignore_errors": ignore_errors, "prior_confidence": prior_confidence, "random_interleave_prob": random_interleave_prob, - "sample_default_first": sample_default_first, - "sample_default_at_target": sample_default_at_target, + "sample_prior_first": sample_prior_first, + "sample_prior_at_target": sample_prior_at_target, } super().__init__(**args) # stores the flattened sequence of SH brackets to loop over - the HB heuristic @@ -199,7 +199,7 @@ def clear_old_brackets(self) -> None: _min_rung = self.sh_brackets[self.current_sh_bracket].min_rung end = self.sh_brackets[self.current_sh_bracket].config_map[_min_rung] - if self.sample_default_first and self.sample_default_at_target: + if self.sample_prior_first and self.sample_prior_at_target: start += 1 end += 1 @@ -283,8 +283,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", random_interleave_prob: float = 0.0, - sample_default_first: bool = False, - sample_default_at_target: bool = False, + sample_prior_first: bool = False, + sample_prior_at_target: bool = False, ): super().__init__( pipeline_space=pipeline_space, @@ -299,8 +299,8 @@ def __init__( ignore_errors=ignore_errors, prior_confidence=prior_confidence, random_interleave_prob=random_interleave_prob, - sample_default_first=sample_default_first, - sample_default_at_target=sample_default_at_target, + sample_prior_first=sample_prior_first, + sample_prior_at_target=sample_prior_at_target, ) @@ -321,8 +321,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", random_interleave_prob: float = 0.0, - sample_default_first: bool = False, - sample_default_at_target: bool = False, + sample_prior_first: bool = False, + sample_prior_at_target: bool = False, ): super().__init__( pipeline_space=pipeline_space, @@ -336,8 +336,8 @@ def __init__( ignore_errors=ignore_errors, prior_confidence=prior_confidence, random_interleave_prob=random_interleave_prob, - sample_default_first=sample_default_first, - sample_default_at_target=sample_default_at_target, + sample_prior_first=sample_prior_first, + sample_prior_at_target=sample_prior_at_target, ) self.sampling_args = { "inc": None, @@ -372,8 +372,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] | None = None, random_interleave_prob: float = 0.0, - sample_default_first: bool = False, - sample_default_at_target: bool = False, + sample_prior_first: bool = False, + sample_prior_at_target: bool = False, ): args = { "pipeline_space": pipeline_space, @@ -388,8 +388,8 @@ def __init__( "ignore_errors": ignore_errors, "prior_confidence": prior_confidence, "random_interleave_prob": random_interleave_prob, - "sample_default_first": sample_default_first, - "sample_default_at_target": sample_default_at_target, + "sample_prior_first": sample_prior_first, + "sample_prior_at_target": sample_prior_at_target, } super().__init__(**args) # overwrite parent class SH brackets with Async SH brackets @@ -466,8 +466,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", random_interleave_prob: float = 0.0, - sample_default_first: bool = False, - sample_default_at_target: bool = False, + sample_prior_first: bool = False, + sample_prior_at_target: bool = False, ): super().__init__( pipeline_space=pipeline_space, @@ -482,8 +482,8 @@ def __init__( ignore_errors=ignore_errors, prior_confidence=prior_confidence, random_interleave_prob=random_interleave_prob, - sample_default_first=sample_default_first, - sample_default_at_target=sample_default_at_target, + sample_prior_first=sample_prior_first, + sample_prior_at_target=sample_prior_at_target, ) @@ -506,8 +506,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] | None = None, random_interleave_prob: float = 0.0, - sample_default_first: bool = False, - sample_default_at_target: bool = False, + sample_prior_first: bool = False, + sample_prior_at_target: bool = False, # new arguments for model model_policy: Any = ModelPolicy, surrogate_model: str | Any = "gp", # TODO: Remove @@ -531,8 +531,8 @@ def __init__( "ignore_errors": ignore_errors, "prior_confidence": prior_confidence, "random_interleave_prob": random_interleave_prob, - "sample_default_first": sample_default_first, - "sample_default_at_target": sample_default_at_target, + "sample_prior_first": sample_prior_first, + "sample_prior_at_target": sample_prior_at_target, } super().__init__(**hb_args) diff --git a/neps/optimizers/multi_fidelity/ifbo.py b/neps/optimizers/multi_fidelity/ifbo.py index b4e90d1d..54cf0ac6 100755 --- a/neps/optimizers/multi_fidelity/ifbo.py +++ b/neps/optimizers/multi_fidelity/ifbo.py @@ -92,8 +92,8 @@ def __init__( pipeline_space: SearchSpace, step_size: int | float = 1, use_priors: bool = False, - sample_default_first: bool = False, - sample_default_at_target: bool = False, + sample_prior_first: bool = False, + sample_prior_at_target: bool = False, surrogate_model_args: dict | None = None, initial_design_size: int | Literal["ndim"] = "ndim", n_acquisition_new_configs: int = 1_000, @@ -110,7 +110,7 @@ def __init__( step_size: The size of the step to take in the fidelity domain. sampling_policy: The type of sampling procedure to use promotion_policy: The type of promotion procedure to use - sample_default_first: Whether to sample the default configuration first + sample_prior_first: Whether to sample the default configuration first initial_design_size: Number of configs to sample before starting optimization If None, the number of configs will be equal to the number of dimensions. @@ -128,8 +128,8 @@ def __init__( super().__init__(pipeline_space=space) self.step_size = step_size self.use_priors = use_priors - self.sample_default_first = sample_default_first - self.sample_default_at_target = sample_default_at_target + self.sample_prior_first = sample_prior_first + self.sample_prior_at_target = sample_prior_at_target self.device = device self.n_initial_design: int | Literal["ndim"] = initial_design_size self.n_acquisition_new_configs = n_acquisition_new_configs @@ -181,7 +181,7 @@ def ask( self._initial_design = make_initial_design( space=self.pipeline_space, encoder=self._config_encoder, - sample_default_first=self.sample_default_first, + sample_prior_first=self.sample_prior_first, sampler="sobol" if self._prior is None else self._prior, seed=None, # TODO: sample_fidelity="min", diff --git a/neps/optimizers/multi_fidelity/successive_halving.py b/neps/optimizers/multi_fidelity/successive_halving.py index f580ed3d..a1baf47f 100644 --- a/neps/optimizers/multi_fidelity/successive_halving.py +++ b/neps/optimizers/multi_fidelity/successive_halving.py @@ -61,8 +61,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] | None = None, random_interleave_prob: float = 0.0, - sample_default_first: bool = False, - sample_default_at_target: bool = False, + sample_prior_first: bool = False, + sample_prior_at_target: bool = False, ): """Initialise an SH bracket. @@ -88,8 +88,8 @@ def __init__( The higher the confidence, the smaller is the standard deviation of the prior distribution centered around the default random_interleave_prob: Chooses the fraction of samples from random vs prior - sample_default_first: Whether to sample the default configuration first - sample_default_at_target: Whether to evaluate the default configuration at + sample_prior_first: Whether to sample the prior configuration first + sample_prior_at_target: Whether to evaluate the prior configuration at the target fidelity or max budget """ super().__init__( @@ -102,8 +102,8 @@ def __init__( if random_interleave_prob < 0 or random_interleave_prob > 1: raise ValueError("random_interleave_prob should be in [0.0, 1.0]") self.random_interleave_prob = random_interleave_prob - self.sample_default_first = sample_default_first - self.sample_default_at_target = sample_default_at_target + self.sample_prior_first = sample_prior_first + self.sample_prior_at_target = sample_prior_at_target assert self.pipeline_space.fidelity is not None, "Fidelity parameter not set." self.min_budget = self.pipeline_space.fidelity.lower @@ -286,8 +286,8 @@ def _get_rungs_state(self, observed_configs: pd.DataFrame | None = None) -> None ) # remove the default from being part of a Successive-Halving bracket if ( - self.sample_default_first - and self.sample_default_at_target + self.sample_prior_first + and self.sample_prior_at_target and 0 in observed_configs.index.values ): observed_configs = observed_configs.drop(index=0) @@ -429,10 +429,10 @@ def get_config_and_ids(self) -> tuple[RawConfig, str, str | None]: rng = random.Random(None) # TODO: Seeding if ( self.use_priors - and self.sample_default_first + and self.sample_prior_first and len(self.observed_configs) == 0 ): - if self.sample_default_at_target: + if self.sample_prior_at_target: # sets the default config to be evaluated at the target fidelity rung_id = self.max_rung logger.info("Next config will be evaluated at target fidelity.") @@ -512,7 +512,7 @@ def clear_old_brackets(self) -> None: # indexes to mark separate brackets start = 0 end = self.config_map[self.min_rung] # length of lowest rung in a bracket - if self.sample_default_at_target and self.sample_default_first: + if self.sample_prior_at_target and self.sample_prior_first: start += 1 end += 1 # iterates over the different SH brackets which span start-end by index @@ -570,8 +570,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", # medium = 0.25 random_interleave_prob: float = 0.0, - sample_default_first: bool = False, - sample_default_at_target: bool = False, + sample_prior_first: bool = False, + sample_prior_at_target: bool = False, ): super().__init__( pipeline_space=pipeline_space, @@ -587,8 +587,8 @@ def __init__( ignore_errors=ignore_errors, prior_confidence=prior_confidence, random_interleave_prob=random_interleave_prob, - sample_default_first=sample_default_first, - sample_default_at_target=sample_default_at_target, + sample_prior_first=sample_prior_first, + sample_prior_at_target=sample_prior_at_target, ) @@ -611,8 +611,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] | None = None, random_interleave_prob: float = 0.0, - sample_default_first: bool = False, - sample_default_at_target: bool = False, + sample_prior_first: bool = False, + sample_prior_at_target: bool = False, ): super().__init__( pipeline_space=pipeline_space, @@ -628,8 +628,8 @@ def __init__( ignore_errors=ignore_errors, prior_confidence=prior_confidence, random_interleave_prob=random_interleave_prob, - sample_default_first=sample_default_first, - sample_default_at_target=sample_default_at_target, + sample_prior_first=sample_prior_first, + sample_prior_at_target=sample_prior_at_target, ) @@ -653,8 +653,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", random_interleave_prob: float = 0.0, - sample_default_first: bool = False, - sample_default_at_target: bool = False, + sample_prior_first: bool = False, + sample_prior_at_target: bool = False, ): super().__init__( pipeline_space=pipeline_space, @@ -670,6 +670,6 @@ def __init__( ignore_errors=ignore_errors, prior_confidence=prior_confidence, random_interleave_prob=random_interleave_prob, - sample_default_first=sample_default_first, - sample_default_at_target=sample_default_at_target, + sample_prior_first=sample_prior_first, + sample_prior_at_target=sample_prior_at_target, ) diff --git a/neps/optimizers/multi_fidelity_prior/async_priorband.py b/neps/optimizers/multi_fidelity_prior/async_priorband.py index 1290e145..192eb0bd 100644 --- a/neps/optimizers/multi_fidelity_prior/async_priorband.py +++ b/neps/optimizers/multi_fidelity_prior/async_priorband.py @@ -45,8 +45,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", random_interleave_prob: float = 0.0, - sample_default_first: bool = True, - sample_default_at_target: bool = True, + sample_prior_first: bool = True, + sample_prior_at_target: bool = True, prior_weight_type: Literal["geometric", "linear", "50-50"] = "geometric", inc_sample_type: Literal[ "crossover", "gaussian", "hypersphere", "mutation" @@ -81,8 +81,8 @@ def __init__( ignore_errors=ignore_errors, prior_confidence=prior_confidence, random_interleave_prob=random_interleave_prob, - sample_default_first=sample_default_first, - sample_default_at_target=sample_default_at_target, + sample_prior_first=sample_prior_first, + sample_prior_at_target=sample_prior_at_target, ) self.prior_weight_type = prior_weight_type self.inc_sample_type = inc_sample_type @@ -153,8 +153,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", random_interleave_prob: float = 0.0, - sample_default_first: bool = True, - sample_default_at_target: bool = True, + sample_prior_first: bool = True, + sample_prior_at_target: bool = True, prior_weight_type: Literal["geometric", "linear", "50-50"] = "geometric", inc_sample_type: Literal[ "crossover", "gaussian", "hypersphere", "mutation" @@ -190,8 +190,8 @@ def __init__( "ignore_errors": ignore_errors, "prior_confidence": prior_confidence, "random_interleave_prob": random_interleave_prob, - "sample_default_first": sample_default_first, - "sample_default_at_target": sample_default_at_target, + "sample_prior_first": sample_prior_first, + "sample_prior_at_target": sample_prior_at_target, } super().__init__( **args, diff --git a/neps/optimizers/multi_fidelity_prior/priorband.py b/neps/optimizers/multi_fidelity_prior/priorband.py index bc67c44e..b73d9a27 100644 --- a/neps/optimizers/multi_fidelity_prior/priorband.py +++ b/neps/optimizers/multi_fidelity_prior/priorband.py @@ -314,8 +314,8 @@ def __init__( ignore_errors: bool = False, prior_confidence: Literal["low", "medium", "high"] = "medium", random_interleave_prob: float = 0.0, - sample_default_first: bool = True, - sample_default_at_target: bool = True, + sample_prior_first: bool = True, + sample_prior_at_target: bool = True, prior_weight_type: Literal["geometric", "linear", "50-50"] = "geometric", inc_sample_type: Literal[ "hypersphere", "mutation", "crossover", "gaussian" @@ -347,8 +347,8 @@ def __init__( ignore_errors=ignore_errors, prior_confidence=prior_confidence, random_interleave_prob=random_interleave_prob, - sample_default_first=sample_default_first, - sample_default_at_target=sample_default_at_target, + sample_prior_first=sample_prior_first, + sample_prior_at_target=sample_prior_at_target, ) self.prior_weight_type = prior_weight_type self.inc_sample_type = inc_sample_type diff --git a/tests/test_neps_api/solution_yamls/bo_neps_decided.yaml b/tests/test_neps_api/solution_yamls/bo_neps_decided.yaml index 98be780b..f2ca8472 100644 --- a/tests/test_neps_api/solution_yamls/bo_neps_decided.yaml +++ b/tests/test_neps_api/solution_yamls/bo_neps_decided.yaml @@ -6,5 +6,5 @@ searcher_args: initial_design_size: null use_priors: false use_cost: false - sample_default_first: false + sample_prior_first: false device: null diff --git a/tests/test_neps_api/solution_yamls/hyperband_neps_decided.yaml b/tests/test_neps_api/solution_yamls/hyperband_neps_decided.yaml index 29bf8dec..dbd7723f 100644 --- a/tests/test_neps_api/solution_yamls/hyperband_neps_decided.yaml +++ b/tests/test_neps_api/solution_yamls/hyperband_neps_decided.yaml @@ -7,5 +7,5 @@ searcher_args: initial_design_type: max_budget use_priors: false random_interleave_prob: 0.0 - sample_default_first: false - sample_default_at_target: false + sample_prior_first: false + sample_prior_at_target: false diff --git a/tests/test_neps_api/solution_yamls/pibo_neps_decided.yaml b/tests/test_neps_api/solution_yamls/pibo_neps_decided.yaml index 3b7c36b2..d94ea209 100644 --- a/tests/test_neps_api/solution_yamls/pibo_neps_decided.yaml +++ b/tests/test_neps_api/solution_yamls/pibo_neps_decided.yaml @@ -6,5 +6,5 @@ searcher_args: initial_design_size: null use_priors: true use_cost: false - sample_default_first: true + sample_prior_first: true device: null diff --git a/tests/test_neps_api/solution_yamls/priorband_bo_user_decided.yaml b/tests/test_neps_api/solution_yamls/priorband_bo_user_decided.yaml index cd555f33..c0a98cb3 100644 --- a/tests/test_neps_api/solution_yamls/priorband_bo_user_decided.yaml +++ b/tests/test_neps_api/solution_yamls/priorband_bo_user_decided.yaml @@ -7,8 +7,8 @@ searcher_args: initial_design_type: max_budget prior_confidence: medium random_interleave_prob: 0.0 - sample_default_first: true - sample_default_at_target: false + sample_prior_first: true + sample_prior_at_target: false prior_weight_type: geometric inc_sample_type: mutation inc_mutation_rate: 0.5 diff --git a/tests/test_neps_api/solution_yamls/priorband_neps_decided.yaml b/tests/test_neps_api/solution_yamls/priorband_neps_decided.yaml index eb3b0179..6899bd00 100644 --- a/tests/test_neps_api/solution_yamls/priorband_neps_decided.yaml +++ b/tests/test_neps_api/solution_yamls/priorband_neps_decided.yaml @@ -7,8 +7,8 @@ searcher_args: initial_design_type: max_budget prior_confidence: medium random_interleave_prob: 0.0 - sample_default_first: true - sample_default_at_target: false + sample_prior_first: true + sample_prior_at_target: false prior_weight_type: geometric inc_sample_type: mutation inc_mutation_rate: 0.5 diff --git a/tests/test_neps_api/solution_yamls/user_yaml_bo.yaml b/tests/test_neps_api/solution_yamls/user_yaml_bo.yaml index 1a20bc12..c6cbe0ee 100644 --- a/tests/test_neps_api/solution_yamls/user_yaml_bo.yaml +++ b/tests/test_neps_api/solution_yamls/user_yaml_bo.yaml @@ -5,4 +5,4 @@ neps_decision_tree: false searcher_args: initial_design_size: 5 use_priors: true - sample_default_first: true + sample_prior_first: true diff --git a/tests/test_neps_api/testing_yaml/optimizer_test.yaml b/tests/test_neps_api/testing_yaml/optimizer_test.yaml index a4deff20..e6efcf0e 100644 --- a/tests/test_neps_api/testing_yaml/optimizer_test.yaml +++ b/tests/test_neps_api/testing_yaml/optimizer_test.yaml @@ -2,4 +2,4 @@ strategy: bayesian_optimization # Specific arguments depending on the searcher initial_design_size: 7 use_priors: true -sample_default_first: true +sample_prior_first: true diff --git a/tests/test_settings/run_args_optimizer_settings.yaml b/tests/test_settings/run_args_optimizer_settings.yaml index d2daa042..4c049813 100644 --- a/tests/test_settings/run_args_optimizer_settings.yaml +++ b/tests/test_settings/run_args_optimizer_settings.yaml @@ -42,8 +42,8 @@ searcher: initial_design_type: max_budget use_priors: false random_interleave_prob: 0.0 - sample_default_first: false - sample_default_at_target: false + sample_prior_first: false + sample_prior_at_target: false # Hooks pre_load_hooks: diff --git a/tests/test_settings/test_settings.py b/tests/test_settings/test_settings.py index e943e721..18892f68 100644 --- a/tests/test_settings/test_settings.py +++ b/tests/test_settings/test_settings.py @@ -214,8 +214,8 @@ "initial_design_type": "max_budget", "use_priors": False, "random_interleave_prob": 0.0, - "sample_default_first": False, - "sample_default_at_target": False, + "sample_prior_first": False, + "sample_prior_at_target": False, }, }, "run_args_optimizer_settings.yaml", @@ -241,15 +241,15 @@ "initial_design_type": "max_budget", "use_priors": False, "random_interleave_prob": 0.0, - "sample_default_first": False, - "sample_default_at_target": False, + "sample_prior_first": False, + "sample_prior_at_target": False, }, "searcher_kwargs": { "initial_design_type": "max_budget", "use_priors": False, "random_interleave_prob": 0.0, - "sample_default_first": False, - "sample_default_at_target": False, + "sample_prior_first": False, + "sample_prior_at_target": False, }, }, ), diff --git a/tests/test_yaml_run_args/test_declarative_usage_docs/set_up_optimizer.yaml b/tests/test_yaml_run_args/test_declarative_usage_docs/set_up_optimizer.yaml index 90b52671..94922d78 100644 --- a/tests/test_yaml_run_args/test_declarative_usage_docs/set_up_optimizer.yaml +++ b/tests/test_yaml_run_args/test_declarative_usage_docs/set_up_optimizer.yaml @@ -2,4 +2,4 @@ strategy: bayesian_optimization # Specific arguments depending on the searcher initial_design_size: 7 use_priors: true -sample_default_first: false +sample_prior_first: false diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/config_priorband_with_args.yaml b/tests/test_yaml_run_args/test_run_args_by_neps_run/config_priorband_with_args.yaml index b68ae9b7..2d94740b 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/config_priorband_with_args.yaml +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/config_priorband_with_args.yaml @@ -21,8 +21,8 @@ searcher: strategy: "priorband" initial_design_type: max_budget prior_confidence: medium - sample_default_first: true - sample_default_at_target: false + sample_prior_first: true + sample_prior_at_target: false prior_weight_type: geometric inc_sample_type: mutation inc_mutation_rate: 0.2 diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py b/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py index e470580c..bbc0760f 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/neps_run.py @@ -37,8 +37,8 @@ def evaluate_pipeline(learning_rate, epochs, optimizer, batch_size): args = parser.parse_args() hyperband_args_optimizer = {"random_interleave_prob": 0.9, - "sample_default_first": False, - "sample_default_at_target": False, + "sample_prior_first": False, + "sample_prior_at_target": False, "eta": 7} if args.kwargs_flag: diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/hyperband_searcher_kwargs_yaml_args.yaml b/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/hyperband_searcher_kwargs_yaml_args.yaml index 4300ca79..cbb03131 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/hyperband_searcher_kwargs_yaml_args.yaml +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/hyperband_searcher_kwargs_yaml_args.yaml @@ -7,5 +7,5 @@ searcher_args: initial_design_type: max_budget use_priors: false random_interleave_prob: 0.9 - sample_default_first: false - sample_default_at_target: false + sample_prior_first: false + sample_prior_at_target: false diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/priorband_args_run_args.yaml b/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/priorband_args_run_args.yaml index 4969fa29..66a4a3db 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/priorband_args_run_args.yaml +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/priorband_args_run_args.yaml @@ -7,8 +7,8 @@ searcher_args: initial_design_type: max_budget prior_confidence: medium random_interleave_prob: 0.0 - sample_default_first: true - sample_default_at_target: false + sample_prior_first: true + sample_prior_at_target: false prior_weight_type: geometric inc_sample_type: mutation inc_mutation_rate: 0.2 diff --git a/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/select_bo_run_args.yaml b/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/select_bo_run_args.yaml index 9871ca63..3bdb0943 100644 --- a/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/select_bo_run_args.yaml +++ b/tests/test_yaml_run_args/test_run_args_by_neps_run/optimizer_yamls/select_bo_run_args.yaml @@ -6,5 +6,5 @@ searcher_args: initial_design_size: null use_priors: false use_cost: false - sample_default_first: false + sample_prior_first: false device: null From efd6048561d0d79c9a4fef731ea21e59e3149e11 Mon Sep 17 00:00:00 2001 From: Meganton Date: Tue, 31 Dec 2024 03:28:47 +0100 Subject: [PATCH 23/24] rename run_pipeline to evaluate_pipeline in user_yaml_neps.py --- tests/test_neps_api/testing_scripts/user_yaml_neps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_neps_api/testing_scripts/user_yaml_neps.py b/tests/test_neps_api/testing_scripts/user_yaml_neps.py index 135c4b35..60d294df 100644 --- a/tests/test_neps_api/testing_scripts/user_yaml_neps.py +++ b/tests/test_neps_api/testing_scripts/user_yaml_neps.py @@ -27,7 +27,7 @@ def evaluate_pipeline(val1, val2): parent_directory = os.path.join(script_directory, os.pardir) searcher_path = Path(parent_directory) / "testing_yaml" / "optimizer_test" neps.run( - evaluate_pipeline=run_pipeline, + evaluate_pipeline=evaluate_pipeline, pipeline_space=pipeline_space, root_directory="user_yaml_bo", max_evaluations_total=1, From a85a6f9d4656cca03d3cfe7f34c93cbc74736b51 Mon Sep 17 00:00:00 2001 From: Meganton Date: Fri, 8 Nov 2024 01:14:49 +0100 Subject: [PATCH 24/24] rename budget to max_cost_total --- neps/api.py | 2 +- neps/optimizers/base_optimizer.py | 8 +++--- .../acquisition_functions/cost_cooling.py | 6 ++--- .../bayesian_optimization/models/ftpfn.py | 4 +-- .../bayesian_optimization/models/gp.py | 2 +- .../bayesian_optimization/optimizer.py | 12 +++++---- neps/optimizers/grid_search/optimizer.py | 2 +- neps/optimizers/multi_fidelity/hyperband.py | 26 +++++++++---------- neps/optimizers/multi_fidelity/ifbo.py | 4 +-- .../multi_fidelity/successive_halving.py | 26 +++++++++---------- .../multi_fidelity_prior/async_priorband.py | 10 +++---- .../multi_fidelity_prior/priorband.py | 4 +-- neps/optimizers/random_search/optimizer.py | 2 +- neps/runtime.py | 4 +-- neps/state/filebased.py | 2 +- neps/state/neps_state.py | 19 +++++++++----- neps/state/optimizer.py | 4 +-- neps/utils/cli.py | 4 +-- neps/utils/run_args.py | 2 +- tests/regression_runner.py | 8 +++--- .../testing_scripts/baseoptimizer_neps.py | 2 +- .../test_default_report_values.py | 2 +- .../test_error_handling_strategies.py | 2 +- tests/test_runtime/test_stopping_criterion.py | 2 +- tests/test_state/test_filebased_neps_state.py | 8 +++--- tests/test_state/test_neps_state.py | 10 +++---- tests/test_state/test_synced.py | 8 +++--- 27 files changed, 97 insertions(+), 88 deletions(-) diff --git a/neps/api.py b/neps/api.py index 55d92a8a..215fb6ae 100644 --- a/neps/api.py +++ b/neps/api.py @@ -416,7 +416,7 @@ def _run_args( SearcherMapping, searcher_alg, "searcher", as_class=True )( pipeline_space=pipeline_space, - budget=max_cost_total, # TODO: use max_cost_total everywhere + max_cost_total=max_cost_total, # TODO: use max_cost_total everywhere **searcher_config, ) diff --git a/neps/optimizers/base_optimizer.py b/neps/optimizers/base_optimizer.py index 69872584..a7ce9bd1 100644 --- a/neps/optimizers/base_optimizer.py +++ b/neps/optimizers/base_optimizer.py @@ -89,7 +89,7 @@ def __init__( pipeline_space: SearchSpace, patience: int = 50, logger: logging.Logger | None = None, - budget: int | float | None = None, + max_cost_total: int | float | None = None, objective_to_minimize_value_on_error: float | None = None, cost_value_on_error: float | None = None, learning_curve_on_error: float | list[float] | None = None, @@ -98,7 +98,7 @@ def __init__( if patience < 1: raise ValueError("Patience should be at least 1") - self.budget = budget + self.max_cost_total = max_cost_total self.pipeline_space = pipeline_space self.patience = patience self.logger = logger or logging.getLogger("neps") @@ -111,13 +111,13 @@ def __init__( def ask( self, trials: Mapping[str, Trial], - budget_info: BudgetInfo | None, + max_cost_total_info: BudgetInfo | None, ) -> SampledConfig: """Sample a new configuration. Args: trials: All of the trials that are known about. - budget_info: information about the budget + max_cost_total_info: information about the max_cost_total Returns: SampledConfig: a sampled configuration diff --git a/neps/optimizers/bayesian_optimization/acquisition_functions/cost_cooling.py b/neps/optimizers/bayesian_optimization/acquisition_functions/cost_cooling.py index 4095d6f2..46fe1309 100644 --- a/neps/optimizers/bayesian_optimization/acquisition_functions/cost_cooling.py +++ b/neps/optimizers/bayesian_optimization/acquisition_functions/cost_cooling.py @@ -41,14 +41,14 @@ def apply_cost_cooling( def cost_cooled_acq( acq_fn: AcquisitionFunction, model: GPyTorchModel, - used_budget_percentage: float, + used_max_cost_total_percentage: float, ) -> WeightedAcquisition: - assert 0 <= used_budget_percentage <= 1 + assert 0 <= used_max_cost_total_percentage <= 1 return WeightedAcquisition( acq=acq_fn, apply_weight=partial( apply_cost_cooling, cost_model=model, - alpha=1 - used_budget_percentage, + alpha=1 - used_max_cost_total_percentage, ), ) diff --git a/neps/optimizers/bayesian_optimization/models/ftpfn.py b/neps/optimizers/bayesian_optimization/models/ftpfn.py index da8c126f..2990b095 100644 --- a/neps/optimizers/bayesian_optimization/models/ftpfn.py +++ b/neps/optimizers/bayesian_optimization/models/ftpfn.py @@ -164,7 +164,7 @@ def encode_ftpfn( device=device, dtype=dtype, ) - train_budgets = budget_domain.cast( + train_max_cost_total = budget_domain.cast( train_fidelities, frm=space.fidelity.domain, dtype=dtype ) @@ -192,7 +192,7 @@ def encode_ftpfn( ) maximize_ys = 1 - minimize_ys x_train = torch.cat( - [ids.unsqueeze(1), train_budgets.unsqueeze(1), train_configs], dim=1 + [ids.unsqueeze(1), train_max_cost_total.unsqueeze(1), train_configs], dim=1 ) return x_train, maximize_ys diff --git a/neps/optimizers/bayesian_optimization/models/gp.py b/neps/optimizers/bayesian_optimization/models/gp.py index bf01601a..2210e44b 100644 --- a/neps/optimizers/bayesian_optimization/models/gp.py +++ b/neps/optimizers/bayesian_optimization/models/gp.py @@ -401,7 +401,7 @@ def fit_and_acquire_from_gp( acquisition = cost_cooled_acq( acq_fn=acquisition, model=cost_gp, - used_budget_percentage=cost_percentage_used, + used_max_cost_total_percentage=cost_percentage_used, ) _n = n_candidates_required if n_candidates_required is not None else 1 diff --git a/neps/optimizers/bayesian_optimization/optimizer.py b/neps/optimizers/bayesian_optimization/optimizer.py index b95e0680..743395b2 100644 --- a/neps/optimizers/bayesian_optimization/optimizer.py +++ b/neps/optimizers/bayesian_optimization/optimizer.py @@ -69,7 +69,7 @@ def __init__( device: torch.device | None = None, encoder: ConfigEncoder | None = None, seed: int | None = None, - budget: Any | None = None, # TODO: remove + max_cost_total: Any | None = None, # TODO: remove surrogate_model: Any | None = None, # TODO: remove objective_to_minimize_value_on_error: Any | None = None, # TODO: remove cost_value_on_error: Any | None = None, # TODO: remove @@ -134,7 +134,7 @@ def __init__( def ask( self, trials: Mapping[str, Trial], - budget_info: BudgetInfo | None = None, + max_cost_total_info: BudgetInfo | None = None, ) -> SampledConfig: n_sampled = len(trials) config_id = str(n_sampled + 1) @@ -164,14 +164,16 @@ def ask( cost_percent = None if self.use_cost: - if budget_info is None: + if max_cost_total_info is None: raise ValueError( "Must provide a 'cost' to configurations if using cost" " with BayesianOptimization." ) - if budget_info.max_cost_budget is None: + if max_cost_total_info.max_cost_total is None: raise ValueError("Cost budget must be set if using cost") - cost_percent = budget_info.used_cost_budget / budget_info.max_cost_budget + cost_percent = ( + max_cost_total_info.used_cost_budget / max_cost_total_info.max_cost_total + ) # If we should use the prior, weight the acquisition function by # the probability of it being sampled from the prior. diff --git a/neps/optimizers/grid_search/optimizer.py b/neps/optimizers/grid_search/optimizer.py index 1da004e7..7bd61286 100644 --- a/neps/optimizers/grid_search/optimizer.py +++ b/neps/optimizers/grid_search/optimizer.py @@ -97,7 +97,7 @@ def __init__(self, pipeline_space: SearchSpace, seed: int | None = None): @override def ask( - self, trials: Mapping[str, Trial], budget_info: BudgetInfo | None + self, trials: Mapping[str, Trial], max_cost_total_info: BudgetInfo | None ) -> SampledConfig: _num_previous_configs = len(trials) if _num_previous_configs > len(self.configs_list) - 1: diff --git a/neps/optimizers/multi_fidelity/hyperband.py b/neps/optimizers/multi_fidelity/hyperband.py index f4c2cd54..e92b1939 100644 --- a/neps/optimizers/multi_fidelity/hyperband.py +++ b/neps/optimizers/multi_fidelity/hyperband.py @@ -47,7 +47,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", use_priors: bool = False, @@ -63,7 +63,7 @@ def __init__( ): args = { "pipeline_space": pipeline_space, - "budget": budget, + "max_cost_total": max_cost_total, "eta": eta, "early_stopping_rate": self.early_stopping_rate, # HB subsumes this from SH "initial_design_type": initial_design_type, @@ -125,7 +125,7 @@ def _handle_promotions(self) -> None: def ask( self, trials: Mapping[str, Trial], - budget_info: BudgetInfo | None, + max_cost_total_info: BudgetInfo | None, ) -> SampledConfig: completed: dict[str, ConfigResult] = { trial_id: trial.into_config_result(self.pipeline_space.from_dict) @@ -273,7 +273,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = FixedPriorPolicy, @@ -288,7 +288,7 @@ def __init__( ): super().__init__( pipeline_space=pipeline_space, - budget=budget, + max_cost_total=max_cost_total, eta=eta, initial_design_type=initial_design_type, use_priors=self.use_priors, # key change to the base HB class @@ -311,7 +311,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = EnsemblePolicy, @@ -326,7 +326,7 @@ def __init__( ): super().__init__( pipeline_space=pipeline_space, - budget=budget, + max_cost_total=max_cost_total, eta=eta, initial_design_type=initial_design_type, sampling_policy=sampling_policy, @@ -361,7 +361,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", use_priors: bool = False, @@ -377,7 +377,7 @@ def __init__( ): args = { "pipeline_space": pipeline_space, - "budget": budget, + "max_cost_total": max_cost_total, "eta": eta, "initial_design_type": initial_design_type, "use_priors": use_priors, @@ -456,7 +456,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = FixedPriorPolicy, @@ -471,7 +471,7 @@ def __init__( ): super().__init__( pipeline_space=pipeline_space, - budget=budget, + max_cost_total=max_cost_total, eta=eta, initial_design_type=initial_design_type, use_priors=self.use_priors, # key change to the base Async HB class @@ -495,7 +495,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", use_priors: bool = False, @@ -520,7 +520,7 @@ def __init__( ): hb_args = { "pipeline_space": pipeline_space, - "budget": budget, + "max_cost_total": max_cost_total, "eta": eta, "initial_design_type": initial_design_type, "use_priors": use_priors, diff --git a/neps/optimizers/multi_fidelity/ifbo.py b/neps/optimizers/multi_fidelity/ifbo.py index 54cf0ac6..632d548e 100755 --- a/neps/optimizers/multi_fidelity/ifbo.py +++ b/neps/optimizers/multi_fidelity/ifbo.py @@ -98,7 +98,7 @@ def __init__( initial_design_size: int | Literal["ndim"] = "ndim", n_acquisition_new_configs: int = 1_000, device: torch.device | None = None, - budget: int | float | None = None, # TODO: Remove + max_cost_total: int | float | None = None, # TODO: Remove objective_to_minimize_value_on_error: float | None = None, # TODO: Remove cost_value_on_error: float | None = None, # TODO: Remove ignore_errors: bool = False, # TODO: Remove @@ -171,7 +171,7 @@ def __init__( def ask( self, trials: Mapping[str, Trial], - budget_info: BudgetInfo | None = None, + max_cost_total_info: BudgetInfo | None = None, ) -> SampledConfig: ids = [int(config_id.split("_", maxsplit=1)[0]) for config_id in trials] new_id = max(ids) + 1 if len(ids) > 0 else 0 diff --git a/neps/optimizers/multi_fidelity/successive_halving.py b/neps/optimizers/multi_fidelity/successive_halving.py index a1baf47f..debe6522 100644 --- a/neps/optimizers/multi_fidelity/successive_halving.py +++ b/neps/optimizers/multi_fidelity/successive_halving.py @@ -49,7 +49,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int | None = None, + max_cost_total: int | None = None, eta: int = 3, early_stopping_rate: int = 0, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", @@ -68,7 +68,7 @@ def __init__( Args: pipeline_space: Space in which to search - budget: Maximum budget + max_cost_total: Maximum budget eta: The reduction factor used by SH early_stopping_rate: Determines the number of rungs in an SH bracket Choosing 0 creates maximal rungs given the fidelity bounds @@ -94,7 +94,7 @@ def __init__( """ super().__init__( pipeline_space=pipeline_space, - budget=budget, + max_cost_total=max_cost_total, objective_to_minimize_value_on_error=objective_to_minimize_value_on_error, cost_value_on_error=cost_value_on_error, ignore_errors=ignore_errors, @@ -320,7 +320,7 @@ def _fit_models(self) -> None: def ask( self, trials: Mapping[str, Trial], - budget_info: BudgetInfo | None, + max_cost_total_info: BudgetInfo | None, ) -> SampledConfig: """This is basically the fit method.""" completed: dict[str, ConfigResult] = { @@ -489,13 +489,13 @@ def _enhance_priors(self, confidence_score: dict[str, float] | None = None) -> N class SuccessiveHalving(SuccessiveHalvingBase): def _calc_budget_used_in_bracket(self, config_history: list[int]) -> int: - budget = 0 + max_cost_total = 0 for rung in self.config_map: count = sum(config_history == rung) # `range(min_rung, rung+1)` counts the black-box cost of promotions since # SH budgets assume each promotion involves evaluation from scratch - budget += count * sum(np.arange(self.min_rung, rung + 1)) - return budget + max_cost_total += count * sum(np.arange(self.min_rung, rung + 1)) + return max_cost_total def clear_old_brackets(self) -> None: """Enforces reset at each new bracket. @@ -559,7 +559,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, early_stopping_rate: int = 0, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", @@ -575,7 +575,7 @@ def __init__( ): super().__init__( pipeline_space=pipeline_space, - budget=budget, + max_cost_total=max_cost_total, eta=eta, early_stopping_rate=early_stopping_rate, initial_design_type=initial_design_type, @@ -599,7 +599,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, early_stopping_rate: int = 0, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", @@ -616,7 +616,7 @@ def __init__( ): super().__init__( pipeline_space=pipeline_space, - budget=budget, + max_cost_total=max_cost_total, eta=eta, early_stopping_rate=early_stopping_rate, initial_design_type=initial_design_type, @@ -642,7 +642,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, early_stopping_rate: int = 0, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", @@ -658,7 +658,7 @@ def __init__( ): super().__init__( pipeline_space=pipeline_space, - budget=budget, + max_cost_total=max_cost_total, eta=eta, early_stopping_rate=early_stopping_rate, initial_design_type=initial_design_type, diff --git a/neps/optimizers/multi_fidelity_prior/async_priorband.py b/neps/optimizers/multi_fidelity_prior/async_priorband.py index 192eb0bd..60300fa0 100644 --- a/neps/optimizers/multi_fidelity_prior/async_priorband.py +++ b/neps/optimizers/multi_fidelity_prior/async_priorband.py @@ -34,7 +34,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, early_stopping_rate: int = 0, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", @@ -70,7 +70,7 @@ def __init__( ): super().__init__( pipeline_space=pipeline_space, - budget=budget, + max_cost_total=max_cost_total, eta=eta, early_stopping_rate=early_stopping_rate, initial_design_type=initial_design_type, @@ -143,7 +143,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = EnsemblePolicy, # key difference to ASHA @@ -179,7 +179,7 @@ def __init__( # collecting arguments required by ASHA args: dict[str, Any] = { "pipeline_space": pipeline_space, - "budget": budget, + "max_cost_total": max_cost_total, "eta": eta, "early_stopping_rate": self.early_stopping_rate, "initial_design_type": initial_design_type, @@ -238,7 +238,7 @@ def _update_sh_bracket_state(self) -> None: def ask( self, trials: Mapping[str, Trial], - budget_info: BudgetInfo | None, + max_cost_total_info: BudgetInfo | None, ) -> SampledConfig: """This is basically the fit method.""" completed: dict[str, ConfigResult] = { diff --git a/neps/optimizers/multi_fidelity_prior/priorband.py b/neps/optimizers/multi_fidelity_prior/priorband.py index b73d9a27..bcbd8c9c 100644 --- a/neps/optimizers/multi_fidelity_prior/priorband.py +++ b/neps/optimizers/multi_fidelity_prior/priorband.py @@ -304,7 +304,7 @@ def __init__( self, *, pipeline_space: SearchSpace, - budget: int, + max_cost_total: int, eta: int = 3, initial_design_type: Literal["max_budget", "unique_configs"] = "max_budget", sampling_policy: Any = EnsemblePolicy, @@ -337,7 +337,7 @@ def __init__( ): super().__init__( pipeline_space=pipeline_space, - budget=budget, + max_cost_total=max_cost_total, eta=eta, initial_design_type=initial_design_type, sampling_policy=sampling_policy, diff --git a/neps/optimizers/random_search/optimizer.py b/neps/optimizers/random_search/optimizer.py index 8bcc8178..285fd964 100644 --- a/neps/optimizers/random_search/optimizer.py +++ b/neps/optimizers/random_search/optimizer.py @@ -55,7 +55,7 @@ def __init__( def ask( self, trials: Mapping[str, Trial], - budget_info: BudgetInfo | None, + max_cost_total_info: BudgetInfo | None, ) -> SampledConfig: n_trials = len(trials) config = self.sampler.sample_one(to=self.encoder.domains) diff --git a/neps/runtime.py b/neps/runtime.py index 4f326535..7fcdf6a4 100644 --- a/neps/runtime.py +++ b/neps/runtime.py @@ -517,9 +517,9 @@ def _launch_runtime( # noqa: PLR0913 directory=optimization_dir, optimizer_info=OptimizerInfo(optimizer_info), optimizer_state=OptimizationState( - budget=( + max_cost_total_info=( BudgetInfo( - max_cost_budget=max_cost_total, + max_cost_total=max_cost_total, used_cost_budget=0, max_evaluations=max_evaluations_total, used_evaluations=0, diff --git a/neps/state/filebased.py b/neps/state/filebased.py index cf53c622..152893d7 100644 --- a/neps/state/filebased.py +++ b/neps/state/filebased.py @@ -392,7 +392,7 @@ def read(cls, directory: Path) -> OptimizationState: budget = BudgetInfo(**budget_info) if budget_info is not None else None return OptimizationState( shared_state=state.get("shared_state") or {}, - budget=budget, + max_cost_total_info=budget, ) @override diff --git a/neps/state/neps_state.py b/neps/state/neps_state.py index 1ed3f67b..f60718d4 100644 --- a/neps/state/neps_state.py +++ b/neps/state/neps_state.py @@ -103,10 +103,14 @@ def sample_trial( optimizer = hook(optimizer) # NOTE: We don't want optimizers mutating this before serialization - budget = opt_state.budget.clone() if opt_state.budget is not None else None + max_cost_total = ( + opt_state.max_cost_total_info.clone() + if opt_state.max_cost_total_info is not None + else None + ) sampled_config_maybe_new_opt_state = optimizer.ask( trials=trials, - budget_info=budget, + max_cost_total_info=max_cost_total, ) if isinstance(sampled_config_maybe_new_opt_state, tuple): @@ -138,7 +142,10 @@ def sample_trial( seed_state.recapture() put_seed_state(seed_state) put_opt( - OptimizationState(budget=opt_state.budget, shared_state=new_opt_state) + OptimizationState( + max_cost_total_info=opt_state.max_cost_total_info, + shared_state=new_opt_state, + ) ) return trial @@ -169,11 +176,11 @@ def report_trial_evaluation( with self._optimizer_state.acquire() as (opt_state, put_opt_state): # TODO: If an optimizer doesn't use the state, this is a waste of time. # Update the budget if we have one. - if opt_state.budget is not None: - budget_info = opt_state.budget + if opt_state.max_cost_total_info is not None: + max_cost_total_info = opt_state.max_cost_total_info if report.cost is not None: - budget_info.used_cost_budget += report.cost + max_cost_total_info.used_cost_budget += report.cost put_opt_state(opt_state) if report.err is not None: diff --git a/neps/state/optimizer.py b/neps/state/optimizer.py index 38d0bfb5..f8981e6c 100644 --- a/neps/state/optimizer.py +++ b/neps/state/optimizer.py @@ -11,7 +11,7 @@ class BudgetInfo: """Information about the budget of an optimizer.""" - max_cost_budget: float | None = None + max_cost_total: float | None = None used_cost_budget: float = 0.0 max_evaluations: int | None = None used_evaluations: int = 0 @@ -25,7 +25,7 @@ def clone(self) -> BudgetInfo: class OptimizationState: """The current state of an optimizer.""" - budget: BudgetInfo | None + max_cost_total_info: BudgetInfo | None """Information regarind the budget used by the optimization trajectory.""" shared_state: dict[str, Any] diff --git a/neps/utils/cli.py b/neps/utils/cli.py index b475519b..67d67a7b 100644 --- a/neps/utils/cli.py +++ b/neps/utils/cli.py @@ -144,8 +144,8 @@ def init_config(args: argparse.Namespace) -> None: directory=directory, optimizer_info=OptimizerInfo(optimizer_info), optimizer_state=OptimizationState( - budget=( - BudgetInfo(max_cost_budget=max_cost_total, used_cost_budget=0) + max_cost_total_info=( + BudgetInfo(max_cost_total=max_cost_total, used_cost_budget=0) if max_cost_total is not None else None ), diff --git a/neps/utils/run_args.py b/neps/utils/run_args.py index c1d09dbc..2fbd740c 100644 --- a/neps/utils/run_args.py +++ b/neps/utils/run_args.py @@ -98,7 +98,7 @@ def get_run_args_from_yaml(path: str | Path) -> dict: f"provided via run_args." f"See here all valid arguments:" f" {', '.join(expected_parameters)}, " - f"'run_pipeline', 'preload_hooks', 'pipeline_space'" + f"'evaluate_pipeline', 'preload_hooks', 'pipeline_space'" ) # Process complex configurations (e.g., 'pipeline_space', 'searcher') and integrate diff --git a/tests/regression_runner.py b/tests/regression_runner.py index 612c74f3..25d6a11c 100644 --- a/tests/regression_runner.py +++ b/tests/regression_runner.py @@ -51,7 +51,7 @@ def __init__( objective: RegressionObjectiveBase | Callable, iterations: int = 100, max_evaluations: int = 150, - budget: int = 10000, + max_cost_total: int = 10000, experiment_name: str = "", **kwargs, ): @@ -62,7 +62,7 @@ def __init__( objective: callable that takes a configuration as input and evaluates it iterations: number of times to record the whole optimization process max_evaluations: maximum number of total evaluations for each optimization process - budget: budget for cost aware optimizers + max_cost_total: budget for cost aware optimizers experiment_name: string to identify different experiments """ self.objective = objective @@ -98,7 +98,7 @@ def __init__( self.benchmark = None # Cost cooling optimizer expects budget but none of the others does - self.budget = budget if "cost" in self.optimizer else None + self.max_cost_total = max_cost_total if "cost" in self.optimizer else None self.max_evaluations = max_evaluations self.final_losses: list[float] = [] @@ -134,7 +134,7 @@ def neps_run(self, working_directory: Path): evaluate_pipeline=self.objective, pipeline_space=self.pipeline_space, searcher=self.optimizer, - max_cost_total=self.budget, + max_cost_total=self.max_cost_total, root_directory=working_directory, max_evaluations_total=self.max_evaluations, ) diff --git a/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py b/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py index 007a14dc..75038a40 100644 --- a/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py +++ b/tests/test_neps_api/testing_scripts/baseoptimizer_neps.py @@ -51,7 +51,7 @@ def evaluate_pipeline_fidelity(val1, val2): # Case 2: Testing BaseOptimizer as searcher with Hyperband search_space_fidelity = SearchSpace(**pipeline_space_fidelity) -my_custom_searcher_2 = Hyperband(pipeline_space=search_space_fidelity, budget=1) +my_custom_searcher_2 = Hyperband(pipeline_space=search_space_fidelity, max_cost_total=1) neps.run( evaluate_pipeline=evaluate_pipeline_fidelity, root_directory="hyperband_custom_created", diff --git a/tests/test_runtime/test_default_report_values.py b/tests/test_runtime/test_default_report_values.py index 24ee3659..1a87aecf 100644 --- a/tests/test_runtime/test_default_report_values.py +++ b/tests/test_runtime/test_default_report_values.py @@ -17,7 +17,7 @@ def neps_state(tmp_path: Path) -> NePSState[Path]: return create_or_load_filebased_neps_state( directory=tmp_path / "neps_state", optimizer_info=OptimizerInfo(info={"nothing": "here"}), - optimizer_state=OptimizationState(budget=None, shared_state={}), + optimizer_state=OptimizationState(max_cost_total_info=None, shared_state={}), ) diff --git a/tests/test_runtime/test_error_handling_strategies.py b/tests/test_runtime/test_error_handling_strategies.py index 05cf762a..ca401060 100644 --- a/tests/test_runtime/test_error_handling_strategies.py +++ b/tests/test_runtime/test_error_handling_strategies.py @@ -22,7 +22,7 @@ def neps_state(tmp_path: Path) -> NePSState[Path]: return create_or_load_filebased_neps_state( directory=tmp_path / "neps_state", optimizer_info=OptimizerInfo(info={"nothing": "here"}), - optimizer_state=OptimizationState(budget=None, shared_state={}), + optimizer_state=OptimizationState(max_cost_total_info=None, shared_state={}), ) diff --git a/tests/test_runtime/test_stopping_criterion.py b/tests/test_runtime/test_stopping_criterion.py index cdc9313b..3410042f 100644 --- a/tests/test_runtime/test_stopping_criterion.py +++ b/tests/test_runtime/test_stopping_criterion.py @@ -18,7 +18,7 @@ def neps_state(tmp_path: Path) -> NePSState[Path]: return create_or_load_filebased_neps_state( directory=tmp_path / "neps_state", optimizer_info=OptimizerInfo(info={"nothing": "here"}), - optimizer_state=OptimizationState(budget=None, shared_state={}), + optimizer_state=OptimizationState(max_cost_total_info=None, shared_state={}), ) diff --git a/tests/test_state/test_filebased_neps_state.py b/tests/test_state/test_filebased_neps_state.py index 8b2d4eb5..ae29ef05 100644 --- a/tests/test_state/test_filebased_neps_state.py +++ b/tests/test_state/test_filebased_neps_state.py @@ -17,13 +17,13 @@ @fixture -@parametrize("budget", [BudgetInfo(max_cost_budget=10, used_cost_budget=0), None]) +@parametrize("max_cost_total_info", [BudgetInfo(max_cost_total=10, used_cost_budget=0), None]) @parametrize("shared_state", [{"a": "b"}, {}]) def optimizer_state( - budget: BudgetInfo | None, + max_cost_total_info: BudgetInfo | None, shared_state: dict[str, Any], ) -> OptimizationState: - return OptimizationState(budget=budget, shared_state=shared_state) + return OptimizationState(max_cost_total_info=max_cost_total_info, shared_state=shared_state) @fixture @@ -71,7 +71,7 @@ def test_create_or_load_with_load_filebased_neps_state( # that we prioritize what's in the existing data over what # was passed in. different_state = OptimizationState( - budget=BudgetInfo(max_cost_budget=20, used_cost_budget=10), + max_cost_total_info=BudgetInfo(max_cost_total=20, used_cost_budget=10), shared_state={"c": "d"}, ) neps_state2 = create_or_load_filebased_neps_state( diff --git a/tests/test_state/test_neps_state.py b/tests/test_state/test_neps_state.py index 65f01210..e298223b 100644 --- a/tests/test_state/test_neps_state.py +++ b/tests/test_state/test_neps_state.py @@ -139,7 +139,7 @@ def optimizer_and_key(key: str, search_space: SearchSpace) -> tuple[BaseOptimize "pipeline_space": search_space, } if key in OPTIMIZER_REQUIRES_BUDGET: - kwargs["budget"] = 10 + kwargs["max_cost_total"] = 10 optimizer_cls = SearcherMapping[key] @@ -147,11 +147,11 @@ def optimizer_and_key(key: str, search_space: SearchSpace) -> tuple[BaseOptimize @parametrize("optimizer_info", [OptimizerInfo({"a": "b"}), OptimizerInfo({})]) -@parametrize("budget", [BudgetInfo(max_cost_budget=10, used_cost_budget=0), None]) +@parametrize("max_cost_total", [BudgetInfo(max_cost_total=10, used_cost_budget=0), None]) @parametrize("shared_state", [{"a": "b"}, {}]) def case_neps_state_filebased( tmp_path: Path, - budget: BudgetInfo | None, + max_cost_total: BudgetInfo | None, optimizer_info: OptimizerInfo, shared_state: dict[str, Any], ) -> NePSState: @@ -159,7 +159,7 @@ def case_neps_state_filebased( return create_or_load_filebased_neps_state( directory=new_path, optimizer_info=optimizer_info, - optimizer_state=OptimizationState(budget=budget, shared_state=shared_state), + optimizer_state=OptimizationState(max_cost_total_info=max_cost_total, shared_state=shared_state), ) @@ -169,7 +169,7 @@ def test_sample_trial( optimizer_and_key: tuple[BaseOptimizer, str], ) -> None: optimizer, key = optimizer_and_key - if key in REQUIRES_COST and neps_state.optimizer_state().budget is None: + if key in REQUIRES_COST and neps_state.optimizer_state().max_cost_total_info is None: pytest.xfail(f"{key} requires a cost budget") assert neps_state.get_all_trials() == {} diff --git a/tests/test_state/test_synced.py b/tests/test_state/test_synced.py index 1d002b3f..eeeb19bd 100644 --- a/tests/test_state/test_synced.py +++ b/tests/test_state/test_synced.py @@ -339,19 +339,19 @@ def _update(optimizer_info: OptimizerInfo) -> None: @case @pytest.mark.parametrize( - "budget", (None, BudgetInfo(max_cost_budget=10, used_cost_budget=0)) + "max_cost_total_info", (None, BudgetInfo(max_cost_total=10, used_cost_budget=0)) ) @pytest.mark.parametrize("shared_state", ({}, {"a": "b"})) def case_optimization_state( tmp_path: Path, - budget: BudgetInfo | None, + max_cost_total_info: BudgetInfo | None, shared_state: dict[str, Any], ) -> tuple[Synced[OptimizationState, Path], Callable[[OptimizationState], None]]: - optimization_state = OptimizationState(budget=budget, shared_state=shared_state) + optimization_state = OptimizationState(max_cost_total_info=max_cost_total_info, shared_state=shared_state) def _update(optimization_state: OptimizationState) -> None: optimization_state.shared_state["a"] = "c" # type: ignore # NOTE: We shouldn't be mutating but anywho... - optimization_state.budget = BudgetInfo(max_cost_budget=10, used_cost_budget=5) + optimization_state.max_cost_total_info = BudgetInfo(max_cost_total=10, used_cost_budget=5) x = Synced.new( data=optimization_state,