dfbench 0.3.0__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dfbench-0.3.0 → dfbench-0.3.2}/PKG-INFO +8 -7
- {dfbench-0.3.0 → dfbench-0.3.2}/README.md +7 -4
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Algorithms.md +1 -1
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Architecture-Overview.md +23 -17
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Implementing-a-New-Algorithm.md +24 -5
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Installation.md +4 -4
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Objective-API-Reference.md +60 -42
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Problems.md +2 -2
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Storage-and-Checkpointing.md +23 -6
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Testing.md +3 -2
- {dfbench-0.3.0 → dfbench-0.3.2}/pyproject.toml +1 -3
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/__init__.py +1 -1
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/hebo_bo.py +13 -5
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/objective.py +378 -670
- dfbench-0.3.2/src/dfbench/core/storage/saveconfig.py +194 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/storage/state.py +12 -11
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/problems/base_problem.py +16 -12
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/problems/voyager/constrained_voyager_problem.py +1 -1
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_bo_batch.py +5 -5
- dfbench-0.3.2/tests/test_hebo_packaging.py +53 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_objective_invariants.py +48 -3
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_objective_penalty_fn.py +405 -35
- dfbench-0.3.0/src/dfbench/core/storage/saveconfig.py +0 -312
- {dfbench-0.3.0 → dfbench-0.3.2}/.gitignore +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/LICENSE +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Algorithm-Status.md +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Benchmarking.md +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/FAQ.md +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Home.md +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Metrics-Reference.md +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/Utilities-and-Helpers.md +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/_Sidebar.md +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/algorithm-status/main.typ +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/docs/algorithm-status/template.typ +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/derivative_free/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/derivative_free/_dfo_common.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/derivative_free/_scipy_common.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/derivative_free/nelder_mead.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/derivative_free/omads_mads.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/derivative_free/pdfo/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/derivative_free/pdfo/lincoa.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/derivative_free/pdfo/newuoa.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/derivative_free/pdfo/uobyqa.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/derivative_free/powell.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/derivative_free/pybobyqa.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/cmaes_sep_cma.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/evosax_es.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/evox_es.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/evox_pso.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/jax_es.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/nevergrad/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/nevergrad/_common.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/nevergrad/ngopt.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/nevergrad/oneplusone.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/nevergrad/tbpsa.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/evolutionary/pycma_cmaes.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/generative/vae_sampling.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/global_search/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/global_search/basin_hopping.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/global_search/dual_annealing.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/global_search/random_search.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/adam_gd.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/custom_jax.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/lbfgs_gd.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/na_adam_gd.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/_common.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/adabelief.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/adadelta.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/adafactor.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/adagrad.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/adam.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/adamax.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/adamaxw.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/adamw.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/adan.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/amsgrad.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/lamb.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/lion.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/lookahead.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/nadam.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/nadamw.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/noisy_sgd.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/novograd.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/oadam.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/ogd.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/polyak_sgd.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/radam.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/rmsprop.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/rprop.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/sam.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/schedule_free_adam.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/sgd.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/sign.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/sm3.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/sophia.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax/yogi.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/optax_lbfgs.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/sa_gd.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/_common.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/bfgs.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/cobyla.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/cobyqa.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/dogleg.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/lbfgsb.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/newton_cg.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/nonlinear_cg.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/slsqp.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/sr1.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/tnc.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/trust_constr.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/trust_krylov.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/gradient_based/scipy/trust_ncg.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/ax_baxus.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/ax_saasbo.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/botorch/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/botorch/_botorch_common.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/botorch/botorch_bo.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/botorch/botorch_gebo.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/botorch/botorch_linebo.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/botorch/botorch_qkg.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/botorch/botorch_qnei.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/botorch/botorch_rembo.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/botorch/botorch_turbo.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/restir.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/smac_bo.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/surrogate_based/turbo_lbfgs.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/utils/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/utils/gp.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/utils/initial_design.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/utils/misc.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/algorithms/utils/weighted_acq.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/benchmark/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/benchmark/benchmark.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/benchmark/metrics.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/_init_env.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/algorithm.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/config.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/display.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/problem.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/storage/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/storage/backends.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/storage/exporter.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/storage/manager.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/storage/resolver.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/storage/serializers.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/core/utils.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/problems/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/problems/uifo/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/problems/uifo/uifo_problem.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/problems/voyager/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/problems/voyager/voyager_problem.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/src/dfbench/problems/voyager/voyager_tuning_problem.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/conftest.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/slow/__init__.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/slow/test_algorithms_integration.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/slow/test_benchmark_full.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/slow/test_problem_bounds_gradients.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/slow/test_problems_full.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_algorithm_protocol.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_algorithms_uniform.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_algorithms_unit.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_api_imports.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_benchmark_smoke.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_cma_family.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_config.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_custom_jax_batch.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_dfo_algorithms.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_display.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_init_env.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_metrics.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_objective_randomness.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_objective_space_mode.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_problem_bounds_overrides.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_problem_protocol.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_problem_spec.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_scipy_wrapper.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_storage.py +0 -0
- {dfbench-0.3.0 → dfbench-0.3.2}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dfbench
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: dfbench: A Black-Box Optimization Framework for JAX-Differentiable Gravitational Wave Detector Discovery
|
|
5
5
|
Project-URL: Homepage, https://github.com/artificial-scientist-lab/Differometor-Benchmark
|
|
6
6
|
Project-URL: Repository, https://github.com/artificial-scientist-lab/Differometor-Benchmark
|
|
@@ -34,7 +34,6 @@ Requires-Dist: cmaes>=0.10.0; extra == 'all'
|
|
|
34
34
|
Requires-Dist: evosax>=0.1.6; extra == 'all'
|
|
35
35
|
Requires-Dist: evox>=1.3.0; extra == 'all'
|
|
36
36
|
Requires-Dist: gpytorch>=1.14; extra == 'all'
|
|
37
|
-
Requires-Dist: hebo>=0.3.2; extra == 'all'
|
|
38
37
|
Requires-Dist: nevergrad>=1.0.12; extra == 'all'
|
|
39
38
|
Requires-Dist: omads>=2408.0; extra == 'all'
|
|
40
39
|
Requires-Dist: optax>=0.2.6; extra == 'all'
|
|
@@ -55,7 +54,6 @@ Provides-Extra: bo
|
|
|
55
54
|
Requires-Dist: ax-platform>=1.2.4; extra == 'bo'
|
|
56
55
|
Requires-Dist: botorch>=0.16.1; extra == 'bo'
|
|
57
56
|
Requires-Dist: gpytorch>=1.14; extra == 'bo'
|
|
58
|
-
Requires-Dist: hebo>=0.3.2; extra == 'bo'
|
|
59
57
|
Requires-Dist: torch>=2.9.1; extra == 'bo'
|
|
60
58
|
Provides-Extra: cuda12
|
|
61
59
|
Requires-Dist: jax[cuda12]==0.9.0.1; extra == 'cuda12'
|
|
@@ -179,7 +177,7 @@ This adds negligible overhead compared to the objective function itself.
|
|
|
179
177
|
|
|
180
178
|
Both constrained problems accept a `power_penalty_fn(value, threshold)` callable to control how power-constraint violations are penalized. Built-in presets: `squashed_relu_penalty` (default), `relu_penalty`, `zero_penalty`. Feel free to try own ones. The penalty function can also be swapped after construction via `obj.set_penalty_fn(fn)` (before `obj.start_logging()`), which re-traces the objective so the change takes effect. The unconstrained Voyager problems reject this call because they have no power-constraint path.
|
|
181
179
|
|
|
182
|
-
Constrained problems also expose aux diagnostics. `obj.value_aux(params)` and `obj.vmap_value_aux(batch)` return `(loss, aux)` where `aux` carries the loss decomposition, a physical `is_feasible` flag, per-constraint violations, and the raw per-group power arrays. Enable `save` tokens like `is_feasible`, `power_values`, or the `aux` alias and
|
|
180
|
+
Constrained problems also expose aux diagnostics. `obj.value_aux(params)` and `obj.vmap_value_aux(batch)` return `(loss, aux)` where `aux` carries the loss decomposition, a physical `is_feasible` flag, per-constraint violations, and the raw per-group power arrays. Enable `save` tokens like `is_feasible`, `power_values`, or the `aux` alias and standard value-bearing calls such as `obj.value` / `obj.value_and_grad` record the enabled aux fields in the same forward pass, with no code change. Derivative-only `grad` / `hessian` calls do not produce aux and append aligned `None` entries when aux histories are enabled. See [Problems](https://github.com/artificial-scientist-lab/Differometor-Benchmark/wiki/Problems) for the aux schema and [Objective API Reference](https://github.com/artificial-scientist-lab/Differometor-Benchmark/wiki/Objective-API-Reference) for the full method set.
|
|
183
181
|
|
|
184
182
|
All problems also support `bounds_overrides` (e.g. `{"tuning": (0, 45)}`) to narrow default property bounds and `signal_floor` to floor detector signal magnitudes before sensitivity normalization. `signal_floor` defaults to `1e-20`. Use `problem.print_bounds()` to inspect effective bounds.
|
|
185
183
|
|
|
@@ -197,11 +195,13 @@ pip install "dfbench[optax,scipy]" # Common local optimizers
|
|
|
197
195
|
pip install "dfbench[evolution]" # CMA, EvoX, Nevergrad, Evosax
|
|
198
196
|
pip install "dfbench[bo]" # BoTorch/Ax surrogate optimizers
|
|
199
197
|
pip install "dfbench[dfo,smac]" # Derivative-free and SMAC optimizers
|
|
200
|
-
pip install "dfbench[all]" # All optimizer backends
|
|
198
|
+
pip install "dfbench[all]" # All packaged optimizer backends
|
|
201
199
|
pip install "dfbench[cuda13]" # CUDA 13 JAX support
|
|
202
200
|
pip install "dfbench[analysis]" # Notebook/profiling tools
|
|
203
201
|
```
|
|
204
202
|
|
|
203
|
+
The HEBO adapter is available in the API, but no dfbench extra installs HEBO because its dependency stack conflicts with dfbench's NumPy 2.x stack. Use it only with a separately managed compatible HEBO installation.
|
|
204
|
+
|
|
205
205
|
### From Source With `uv` (recommended for development)
|
|
206
206
|
|
|
207
207
|
[uv](https://uv.dev/) handles virtual environments and dependency resolution automatically.
|
|
@@ -217,7 +217,7 @@ uv sync --group cuda13 --group analysis # Everything
|
|
|
217
217
|
|
|
218
218
|
```bash
|
|
219
219
|
pip install -e . # CPU-only editable install
|
|
220
|
-
pip install -e ".[all,cuda13,analysis]" #
|
|
220
|
+
pip install -e ".[all,cuda13,analysis]" # Packaged backends, CUDA 13, and analysis extras
|
|
221
221
|
```
|
|
222
222
|
|
|
223
223
|
See [Installation](https://github.com/artificial-scientist-lab/Differometor-Benchmark/wiki/Installation) for GPU setup details and HPC notes.
|
|
@@ -473,7 +473,8 @@ class MyAlgorithm(OptimizationAlgorithm):
|
|
|
473
473
|
| `obj.vmap_value_and_grad(batch)` | Batched gradient methods | batch losses, grads, params |
|
|
474
474
|
| `obj.vmap_hessian(batch)` | Batched second-order methods | batch hessians, batch params |
|
|
475
475
|
| `obj.vmap_value_grad_and_hessian(batch)` | Batched second-order methods | batch losses, grads, hessians, params |
|
|
476
|
-
| `obj.
|
|
476
|
+
| `obj.value_function_aux(...)` | Raw aux-aware callable for custom JIT loops | nothing; use `log_evaluation` afterwards |
|
|
477
|
+
| `obj.log_evaluation(...)` | Custom JIT'd loop | supplied values; aux only for matching save tokens |
|
|
477
478
|
|
|
478
479
|
### Register It
|
|
479
480
|
|
|
@@ -87,7 +87,7 @@ This adds negligible overhead compared to the objective function itself.
|
|
|
87
87
|
|
|
88
88
|
Both constrained problems accept a `power_penalty_fn(value, threshold)` callable to control how power-constraint violations are penalized. Built-in presets: `squashed_relu_penalty` (default), `relu_penalty`, `zero_penalty`. Feel free to try own ones. The penalty function can also be swapped after construction via `obj.set_penalty_fn(fn)` (before `obj.start_logging()`), which re-traces the objective so the change takes effect. The unconstrained Voyager problems reject this call because they have no power-constraint path.
|
|
89
89
|
|
|
90
|
-
Constrained problems also expose aux diagnostics. `obj.value_aux(params)` and `obj.vmap_value_aux(batch)` return `(loss, aux)` where `aux` carries the loss decomposition, a physical `is_feasible` flag, per-constraint violations, and the raw per-group power arrays. Enable `save` tokens like `is_feasible`, `power_values`, or the `aux` alias and
|
|
90
|
+
Constrained problems also expose aux diagnostics. `obj.value_aux(params)` and `obj.vmap_value_aux(batch)` return `(loss, aux)` where `aux` carries the loss decomposition, a physical `is_feasible` flag, per-constraint violations, and the raw per-group power arrays. Enable `save` tokens like `is_feasible`, `power_values`, or the `aux` alias and standard value-bearing calls such as `obj.value` / `obj.value_and_grad` record the enabled aux fields in the same forward pass, with no code change. Derivative-only `grad` / `hessian` calls do not produce aux and append aligned `None` entries when aux histories are enabled. See [Problems](https://github.com/artificial-scientist-lab/Differometor-Benchmark/wiki/Problems) for the aux schema and [Objective API Reference](https://github.com/artificial-scientist-lab/Differometor-Benchmark/wiki/Objective-API-Reference) for the full method set.
|
|
91
91
|
|
|
92
92
|
All problems also support `bounds_overrides` (e.g. `{"tuning": (0, 45)}`) to narrow default property bounds and `signal_floor` to floor detector signal magnitudes before sensitivity normalization. `signal_floor` defaults to `1e-20`. Use `problem.print_bounds()` to inspect effective bounds.
|
|
93
93
|
|
|
@@ -105,11 +105,13 @@ pip install "dfbench[optax,scipy]" # Common local optimizers
|
|
|
105
105
|
pip install "dfbench[evolution]" # CMA, EvoX, Nevergrad, Evosax
|
|
106
106
|
pip install "dfbench[bo]" # BoTorch/Ax surrogate optimizers
|
|
107
107
|
pip install "dfbench[dfo,smac]" # Derivative-free and SMAC optimizers
|
|
108
|
-
pip install "dfbench[all]" # All optimizer backends
|
|
108
|
+
pip install "dfbench[all]" # All packaged optimizer backends
|
|
109
109
|
pip install "dfbench[cuda13]" # CUDA 13 JAX support
|
|
110
110
|
pip install "dfbench[analysis]" # Notebook/profiling tools
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
+
The HEBO adapter is available in the API, but no dfbench extra installs HEBO because its dependency stack conflicts with dfbench's NumPy 2.x stack. Use it only with a separately managed compatible HEBO installation.
|
|
114
|
+
|
|
113
115
|
### From Source With `uv` (recommended for development)
|
|
114
116
|
|
|
115
117
|
[uv](https://uv.dev/) handles virtual environments and dependency resolution automatically.
|
|
@@ -125,7 +127,7 @@ uv sync --group cuda13 --group analysis # Everything
|
|
|
125
127
|
|
|
126
128
|
```bash
|
|
127
129
|
pip install -e . # CPU-only editable install
|
|
128
|
-
pip install -e ".[all,cuda13,analysis]" #
|
|
130
|
+
pip install -e ".[all,cuda13,analysis]" # Packaged backends, CUDA 13, and analysis extras
|
|
129
131
|
```
|
|
130
132
|
|
|
131
133
|
See [Installation](https://github.com/artificial-scientist-lab/Differometor-Benchmark/wiki/Installation) for GPU setup details and HPC notes.
|
|
@@ -381,7 +383,8 @@ class MyAlgorithm(OptimizationAlgorithm):
|
|
|
381
383
|
| `obj.vmap_value_and_grad(batch)` | Batched gradient methods | batch losses, grads, params |
|
|
382
384
|
| `obj.vmap_hessian(batch)` | Batched second-order methods | batch hessians, batch params |
|
|
383
385
|
| `obj.vmap_value_grad_and_hessian(batch)` | Batched second-order methods | batch losses, grads, hessians, params |
|
|
384
|
-
| `obj.
|
|
386
|
+
| `obj.value_function_aux(...)` | Raw aux-aware callable for custom JIT loops | nothing; use `log_evaluation` afterwards |
|
|
387
|
+
| `obj.log_evaluation(...)` | Custom JIT'd loop | supplied values; aux only for matching save tokens |
|
|
385
388
|
|
|
386
389
|
### Register It
|
|
387
390
|
|
|
@@ -942,7 +942,7 @@ optimizer.optimize(
|
|
|
942
942
|
|
|
943
943
|
### HEBO (Heteroscedastic Evolutionary BO)
|
|
944
944
|
|
|
945
|
-
Winner of the NeurIPS 2020 BBO challenge. Uses a heteroscedastic GP, input warping, and multi-objective acquisition.
|
|
945
|
+
Winner of the NeurIPS 2020 BBO challenge. Uses a heteroscedastic GP, input warping, and multi-objective acquisition. HEBO is not installed by a dfbench extra because its dependency stack conflicts with dfbench's NumPy 2.x stack; using this adapter requires a separately managed compatible installation.
|
|
946
946
|
|
|
947
947
|
Reference: Cowen-Rivers et al., *An Empirical Study of Assumptions in Bayesian Optimisation*, 2020.
|
|
948
948
|
|
|
@@ -67,7 +67,7 @@ A problem defines *what* is being optimised. Every problem subclasses `Continuou
|
|
|
67
67
|
|
|
68
68
|
- Maps unbounded coordinates into problem bounds when needed, then evaluates the bounded problem objective
|
|
69
69
|
- Prepares `jax.grad`, `jax.hessian`, `jax.value_and_grad`, and `jax.vmap` variants
|
|
70
|
-
- Records every
|
|
70
|
+
- Records every admitted call with aligned loss / gradient / Hessian / params / timestamp histories
|
|
71
71
|
- Enforces wall-clock time and evaluation-count budgets
|
|
72
72
|
- Provides deterministic random sampling via a splittable JAX PRNG
|
|
73
73
|
- Delegates all file I/O to the modular `dfbench.core.storage` layer (see [Storage & Checkpointing](Storage-and-Checkpointing))
|
|
@@ -114,39 +114,45 @@ See [Storage & Checkpointing](Storage-and-Checkpointing) for the full reference.
|
|
|
114
114
|
│ │ │ │
|
|
115
115
|
└────────────┴───────┬───────┴──────────────────────┘
|
|
116
116
|
│
|
|
117
|
-
Objective.
|
|
117
|
+
Objective._value_func / derivative transforms / vmapped transforms
|
|
118
118
|
│
|
|
119
119
|
▼
|
|
120
120
|
┌──────────────────────────────┐
|
|
121
121
|
│ optional Objective mapping │
|
|
122
|
-
│
|
|
122
|
+
│ objective_function or │
|
|
123
|
+
│ objective_function_aux │
|
|
123
124
|
└──────────────┬───────────────┘
|
|
124
125
|
│
|
|
125
126
|
▼
|
|
126
127
|
Differometor.simulate()
|
|
127
128
|
│
|
|
128
129
|
▼
|
|
129
|
-
|
|
130
|
+
value / derivatives + optional aux
|
|
130
131
|
│
|
|
132
|
+
▼
|
|
133
|
+
_log(params, loss, grad, hessian, aux)
|
|
134
|
+
│
|
|
135
|
+
▼
|
|
136
|
+
_log_evals(..., aux)
|
|
131
137
|
│
|
|
138
|
+
┌───────────┴────────────┐
|
|
139
|
+
│ admitted │ rejected
|
|
140
|
+
▼ ▼
|
|
141
|
+
time + standard histories no history mutation
|
|
142
|
+
+ best/stagnation + selected aux histories
|
|
143
|
+
│ │
|
|
144
|
+
└───────────┬────────────┘
|
|
132
145
|
▼
|
|
133
|
-
|
|
146
|
+
_log_to_file()
|
|
134
147
|
│
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
(append) │ │
|
|
139
|
-
▼ ▼ ▼
|
|
140
|
-
_time_steps _loss_history periodic
|
|
141
|
-
_params_history checkpoint
|
|
142
|
-
_grad_history via CheckpointManager
|
|
143
|
-
_hessian_history -> StorageBackend
|
|
144
|
-
_best_loss / _best_params
|
|
148
|
+
▼
|
|
149
|
+
periodic checkpoint via
|
|
150
|
+
CheckpointManager -> StorageBackend
|
|
145
151
|
```
|
|
146
152
|
|
|
147
|
-
Every call to `obj.value()`, `obj.value_and_grad()`, `obj.hessian()`, `obj.value_grad_and_hessian()`, or any `vmap_*` variant follows this
|
|
153
|
+
Every call to `obj.value()`, `obj.value_and_grad()`, `obj.hessian()`, `obj.value_grad_and_hessian()`, or any `vmap_*` variant follows this pipeline. Value-bearing methods carry one primal aux pytree when aux storage is selected; derivative-only methods carry no aux and contribute `None` to selected aux histories. The internal `_log()` coordinator takes one time snapshot, delegates atomic admission and history tracking to `_log_evals()`, appends the timestamp only for an admitted call, and triggers `_log_to_file()` for periodic checkpoints. `_log_to_file()` calls `CheckpointManager.tick()`, which checks the cadence (`save_every`), lazily builds a `RunState` only when a checkpoint is due, saves it through the internal `StorageBackend`, and returns the save duration so the Objective can exclude it from the elapsed-time clock. The algorithm receives the computed result; logging is a side effect invisible to the caller.
|
|
148
154
|
|
|
149
|
-
For algorithms with custom JIT-compiled evaluation loops (e.g. L-BFGS with line-search), `obj.value_function(...)`
|
|
155
|
+
For algorithms with custom JIT-compiled evaluation loops (e.g. L-BFGS with line-search), `obj.value_function(...)` and `obj.value_function_aux(...)` provide the same Objective-owned bounded/unbounded mapping without Python-side logging. The latter returns an aux-aware callable whose invocation yields `(loss, aux)`, or `None` when unsupported. After logging has started, `obj.log_evaluation(params, loss, grad=None, hessian=None, aux=None)` records the completed evaluation through the same logging pipeline. Manual logging never manufactures aux; omitting it appends `None` to each enabled aux history. Do not call the private methods directly.
|
|
150
156
|
|
|
151
157
|
---
|
|
152
158
|
|
|
@@ -271,19 +271,38 @@ while not obj.budget_exceeded:
|
|
|
271
271
|
| `obj.vmap_hessian(batch)` | Batched second-order optimization | batch hessians, batch params |
|
|
272
272
|
| `obj.vmap_value_grad_and_hessian(batch)` | Batched second-order optimization | batch losses, grads, hessians, params |
|
|
273
273
|
| `obj.value_function(...)` | Raw JAX callable for custom JIT loops | nothing; use `log_evaluation` afterwards |
|
|
274
|
-
| `obj.
|
|
274
|
+
| `obj.value_function_aux(...)` | Raw `(loss, aux)` JAX callable for custom JIT loops | nothing; use `log_evaluation` afterwards |
|
|
275
|
+
| `obj.log_evaluation(...)` | Custom JIT'd loop | supplied values; aux only for matching save tokens |
|
|
275
276
|
|
|
276
|
-
**Important:** `obj.grad()` and `obj.hessian()` do **not** log a loss value. If
|
|
277
|
+
**Important:** `obj.grad()` and `obj.hessian()` do **not** log a loss value or produce aux diagnostics. If aux histories are enabled, derivative-only methods append aligned `None` entries. With an aux save token, `obj.value_and_grad()` and `obj.value_grad_and_hessian()` auto-log primal aux while retaining their standard return signatures. Use `obj.value_and_grad_aux()` when the algorithm itself must receive aux.
|
|
277
278
|
|
|
278
279
|
### Custom JIT-compiled loops with `log_evaluation()`
|
|
279
280
|
|
|
280
281
|
Some optimizers (e.g. Optax's L-BFGS) need to call `value_and_grad` *inside* a JIT-compiled function, for instance because the optimizer's line-search requires the raw value function. In that case you can't use `obj.value_and_grad()` (which has Python-side logging). Instead:
|
|
281
282
|
|
|
282
|
-
1. Get an unlogged
|
|
283
|
+
1. Get an unlogged scalar callable from `obj.value_function(...)`, or an aux-aware callable from `obj.value_function_aux(...)` whose invocation yields `(loss, aux)`
|
|
283
284
|
2. Build your own JIT-compiled step
|
|
284
|
-
3. After each step, call `obj.log_evaluation(params, loss, grad, hessian=None)` to record the results
|
|
285
|
+
3. After each step, call `obj.log_evaluation(params, loss, grad, hessian=None, aux=None)` to record the results
|
|
285
286
|
|
|
286
|
-
`obj.value_function(unbounded=None)` follows the Objective's active space mode by default. Pass `unbounded=True` when the JIT loop works in unbounded coordinates and needs Objective's mapping into problem bounds; pass `unbounded=False` for bounded coordinates.
|
|
287
|
+
`obj.value_function(unbounded=None)` follows the Objective's active space mode by default. Pass `unbounded=True` when the JIT loop works in unbounded coordinates and needs Objective's mapping into problem bounds; pass `unbounded=False` for bounded coordinates. `obj.value_function_aux(...)` follows the same mapping rules and returns an unlogged callable whose invocation yields `(loss, aux)`, or `None` when the problem has no aux objective. Neither callable logs anything.
|
|
288
|
+
|
|
289
|
+
`log_evaluation()` never computes missing aux diagnostics. If the Objective has aux save tokens and the custom loop does not pass `aux`, each selected aux history receives `None` for that call. A custom loop that already computed a conforming aux pytree may pass it explicitly.
|
|
290
|
+
|
|
291
|
+
To compute mapped aux inside the custom loop, preserve it as auxiliary output during differentiation:
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
value_aux_fn = obj.value_function_aux()
|
|
295
|
+
if value_aux_fn is None:
|
|
296
|
+
raise RuntimeError("this problem has no aux objective")
|
|
297
|
+
value_and_grad_aux_fn = jax.jit(jax.value_and_grad(value_aux_fn, has_aux=True))
|
|
298
|
+
|
|
299
|
+
_ = value_and_grad_aux_fn(params) # JIT warmup before timing
|
|
300
|
+
obj.start_logging()
|
|
301
|
+
(loss, aux), grads = value_and_grad_aux_fn(params)
|
|
302
|
+
obj.log_evaluation(params, loss, grads, aux=aux)
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Only aux fields selected in the Objective's `save` configuration are persisted.
|
|
287
306
|
|
|
288
307
|
```python
|
|
289
308
|
# Get the raw function for JIT compilation
|
|
@@ -21,15 +21,15 @@ The base install keeps heavyweight optimizer backends optional. Add extras for t
|
|
|
21
21
|
```bash
|
|
22
22
|
pip install "dfbench[optax,scipy]" # common local optimizers
|
|
23
23
|
pip install "dfbench[evolution]" # CMA, EvoX, Nevergrad, Evosax
|
|
24
|
-
pip install "dfbench[bo]" # BoTorch/Ax
|
|
24
|
+
pip install "dfbench[bo]" # BoTorch/Ax surrogate optimizers
|
|
25
25
|
pip install "dfbench[dfo,smac]" # derivative-free and SMAC optimizers
|
|
26
|
-
pip install "dfbench[all]" # all optimizer backends
|
|
26
|
+
pip install "dfbench[all]" # all packaged optimizer backends
|
|
27
27
|
pip install "dfbench[cuda13]" # CUDA 13 JAX support
|
|
28
28
|
pip install "dfbench[cuda12]" # CUDA 12 JAX support
|
|
29
29
|
pip install "dfbench[analysis]" # notebooks, profiling, plotting helpers
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
`HEBO` is
|
|
32
|
+
`HEBO` is intentionally not exposed through a project extra because its dependency stack is incompatible with dfbench's NumPy 2.x stack. The guarded wrapper remains available for users who provide and test a compatible HEBO installation themselves. Other optional backends are imported lazily: `import dfbench` succeeds when their extras are not installed.
|
|
33
33
|
|
|
34
34
|
## Development Install with `uv`
|
|
35
35
|
|
|
@@ -78,7 +78,7 @@ pip install -e .
|
|
|
78
78
|
# With CUDA GPU support
|
|
79
79
|
pip install -e ".[cuda12]"
|
|
80
80
|
|
|
81
|
-
# With all optimizer backends and analysis tools
|
|
81
|
+
# With all packaged optimizer backends and analysis tools (HEBO excluded)
|
|
82
82
|
pip install -e ".[all,analysis]"
|
|
83
83
|
```
|
|
84
84
|
|
|
@@ -48,7 +48,7 @@ Objective(
|
|
|
48
48
|
| `save_time_steps` | `bool` | `True` | Record elapsed-time timestamp for each evaluation. |
|
|
49
49
|
| `save_params_history` | `bool` | `True` | Record the parameter vector at each evaluation. |
|
|
50
50
|
| `save_batched_params_history` | `bool` | `False` | Store full `(batch, n_params)` parameter arrays for batched evals instead of the reduced representative point. |
|
|
51
|
-
| `save` | `list[str] \| None` | `None` | List of advanced save tokens for recording additional / batched histories. Standard tokens: `"grad"`, `"hessian"`, `"eval_type"`, `"batched_loss"`, `"batched_grad"`, `"batched_hessian"`, `"batched"` (convenience alias expanding to the three batched tokens above). Aux diagnostics tokens
|
|
51
|
+
| `save` | `list[str] \| None` | `None` | List of advanced save tokens for recording additional / batched histories. Standard tokens: `"grad"`, `"hessian"`, `"eval_type"`, `"batched_loss"`, `"batched_grad"`, `"batched_hessian"`, `"batched"` (convenience alias expanding to the three batched tokens above). Aux diagnostics tokens: `"sensitivity_loss"`, `"penalty"`, `"is_feasible"`, `"power_values"`, `"violations"`, `"aux"` (convenience alias expanding to all five), plus per-field `batched_*` variants and `"batched_aux"`. On a problem exposing `objective_function_aux`, these tokens persist diagnostics from explicit `*_aux` methods and standard value-bearing methods. Derivative-only calls append aligned `None` entries. On a problem without `objective_function_aux`, aux tokens emit `RuntimeWarning` and automatic aux logging remains disabled; explicit aux methods still raise `RuntimeError`. The active configuration is recorded as a `SaveConfig` and restored from checkpoints so a resumed run keeps the original history schema. |
|
|
52
52
|
| `verbose` | `int` | `0` | Verbosity level. `0` = silent; `1` = periodic progress prints; `2` is WIP. |
|
|
53
53
|
| `print_every` | `int` | `100` | When `verbose ≥ 1`, print a progress summary every N evaluations. |
|
|
54
54
|
| `algorithm_str` | `str \| None` | `None` | If `None`, this is set by the algorithm via `prepare()` of `OptimizationAlgorithm`. Optional identifier string used in file names and logs. |
|
|
@@ -127,11 +127,11 @@ You do **not** need to handle bounds scaling; the Objective does that automatica
|
|
|
127
127
|
|
|
128
128
|
### Choosing what to save
|
|
129
129
|
|
|
130
|
-
The Objective always
|
|
130
|
+
The Objective always maintains an aligned `loss_history`: value-bearing calls store their loss, while derivative-only calls store a NaN placeholder because they do not return a primal loss. Three standard boolean flags control the most commonly toggled histories:
|
|
131
131
|
|
|
132
132
|
| Flag | Default | Effect |
|
|
133
133
|
|------|---------|--------|
|
|
134
|
-
| `save_time_steps` | `True` | Record elapsed-time
|
|
134
|
+
| `save_time_steps` | `True` | Record one elapsed-time timestamp per admitted logged call |
|
|
135
135
|
| `save_params_history` | `True` | Record parameter vectors (reduced for batches) |
|
|
136
136
|
| `save_batched_params_history` | `False` | Store full `(batch, n_params)` parameter arrays instead of the reduced representative point |
|
|
137
137
|
|
|
@@ -139,23 +139,23 @@ For advanced combinations (gradients, Hessians, eval types, full batched arrays)
|
|
|
139
139
|
|
|
140
140
|
| Token | Effect |
|
|
141
141
|
|-------|--------|
|
|
142
|
-
| `"grad"` | Record
|
|
143
|
-
| `"hessian"` | Record
|
|
144
|
-
| `"eval_type"` | Record
|
|
142
|
+
| `"grad"` | Record gradients (one entry per logged call; batches reduced) |
|
|
143
|
+
| `"hessian"` | Record Hessians (one entry per logged call; batches reduced) |
|
|
144
|
+
| `"eval_type"` | Record one call-type bitmask per logged call |
|
|
145
145
|
| `"batched_loss"` | Store full `(batch,)` loss vectors instead of batch min |
|
|
146
146
|
| `"batched_grad"` | Store full `(batch, n_params)` gradient arrays |
|
|
147
147
|
| `"batched_hessian"` | Store full `(batch, n_params, n_params)` Hessian arrays |
|
|
148
148
|
| `"batched"` | Convenience alias expanding to the three `batched_*` tokens above |
|
|
149
149
|
|
|
150
|
-
Aux diagnostics tokens are recorded by the `*_aux` evaluation methods
|
|
150
|
+
Aux diagnostics tokens are recorded by the explicit `*_aux` evaluation methods and by the standard value-bearing methods (`value`, `value_and_grad`, `vmap_value`, `vmap_value_and_grad`, `value_grad_and_hessian`, `vmap_value_grad_and_hessian`). Auto-logging turns on when at least one aux token is in the `save` list and the problem exposes `objective_function_aux` (the built-in examples are `ConstrainedVoyagerProblem` and `UIFOProblem`). The standard methods then run the aux objective in the same forward pass and populate the aux histories without changing their return signatures (see [Auto-logging aux](#auto-logging-aux-from-standard-value-bearing-methods)). Each token controls one aux field, so enabling `is_feasible` does not force storing the bulky `power_values` arrays. On a problem without `objective_function_aux`, construction emits `RuntimeWarning`, standard methods continue through the scalar objective, and aux histories remain empty.
|
|
151
151
|
|
|
152
152
|
| Token | Effect |
|
|
153
153
|
|-------|--------|
|
|
154
|
-
| `"sensitivity_loss"` | Record the unpenalised sensitivity loss per
|
|
155
|
-
| `"penalty"` | Record the summed penalty per
|
|
156
|
-
| `"is_feasible"` | Record the physical feasibility flag per
|
|
157
|
-
| `"power_values"` | Record per-group powers (hard, soft, detector) per
|
|
158
|
-
| `"violations"` | Record per-constraint penalty values per
|
|
154
|
+
| `"sensitivity_loss"` | Record the unpenalised sensitivity loss per logged call (reduced for batches; `None` when no aux is produced) |
|
|
155
|
+
| `"penalty"` | Record the summed penalty per logged call (reduced for batches; `None` when no aux is produced) |
|
|
156
|
+
| `"is_feasible"` | Record the physical feasibility flag per logged call (reduced for batches; `None` when no aux is produced) |
|
|
157
|
+
| `"power_values"` | Record per-group powers (hard, soft, detector) per logged call (reduced for batches; `None` when no aux is produced) |
|
|
158
|
+
| `"violations"` | Record per-constraint penalty values per logged call (reduced for batches; `None` when no aux is produced) |
|
|
159
159
|
| `"aux"` | Convenience alias expanding to the five non-batched aux tokens above |
|
|
160
160
|
| `"batched_sensitivity_loss"` | Store full batched sensitivity loss arrays |
|
|
161
161
|
| `"batched_penalty"` | Store full batched penalty arrays |
|
|
@@ -164,7 +164,7 @@ Aux diagnostics tokens are recorded by the `*_aux` evaluation methods, and also
|
|
|
164
164
|
| `"batched_violations"` | Store full batched per-constraint violation arrays |
|
|
165
165
|
| `"batched_aux"` | Convenience alias expanding to the five `batched_*` aux tokens above |
|
|
166
166
|
|
|
167
|
-
When a `batched_*` aux token is off and the corresponding non-batched token is on, batched
|
|
167
|
+
When a `batched_*` aux token is off and the corresponding non-batched token is on, aux from every batched value-bearing call—including a singleton batch—is reduced to the representative point. Value-bearing calls select the index of the best loss, so the recorded `is_feasible` and `violations` reflect that best point. This matches the representative used for parameters, gradients, and Hessians.
|
|
168
168
|
|
|
169
169
|
```python
|
|
170
170
|
# Record gradients and full batched losses
|
|
@@ -178,7 +178,7 @@ obj = Objective(problem, save=["grad", "hessian", "eval_type", "batched"])
|
|
|
178
178
|
obj = Objective(problem, save=["aux", "batched_is_feasible"])
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
-
The active configuration is stored as a `SaveConfig` and embedded in every checkpoint's `RunMetadata`. On `load_run_data`, the Objective warns if the checkpoint
|
|
181
|
+
The active configuration is stored as a `SaveConfig` and embedded in every checkpoint's `RunMetadata`. On `load_run_data`, the Objective warns if the checkpoint config differs and adopts the stored config before restoring state, so resumed evaluations keep the run's original history schema.
|
|
182
182
|
|
|
183
183
|
### Storage (internal)
|
|
184
184
|
|
|
@@ -203,7 +203,7 @@ obj.value_grad_and_hessian(params) # -> (float, Array[n_params], Array[n_params
|
|
|
203
203
|
```
|
|
204
204
|
|
|
205
205
|
- `value(params)`: Evaluates the loss at `params`. Logs loss and params.
|
|
206
|
-
- `grad(params)`: Computes the gradient.
|
|
206
|
+
- `grad(params)`: Computes the gradient. The scalar primal is evaluated as part of differentiation, but its value is not returned or logged; `loss_history` receives a NaN placeholder.
|
|
207
207
|
- `hessian(params)`: Computes the exact Hessian. Logs Hessian and params, but **not** a loss value.
|
|
208
208
|
- `value_and_grad(params)`: Computes both in a single forward+backward pass. Logs all three. **Preferred when you need both loss and gradient** because it is more efficient than calling `value` and `grad` separately and it logs the loss.
|
|
209
209
|
- `value_grad_and_hessian(params)`: Computes loss, gradient, and Hessian together and logs all four.
|
|
@@ -233,7 +233,7 @@ Batched methods use `jax.vmap` and evaluate the entire batch as **one** history
|
|
|
233
233
|
|
|
234
234
|
### Aux evaluation
|
|
235
235
|
|
|
236
|
-
Available on problems that
|
|
236
|
+
Available on problems that expose `objective_function_aux` (`ConstrainedVoyagerProblem` and `UIFOProblem` are the built-in examples). These methods return the loss plus an `aux` pytree dict carrying the loss decomposition, a physical `is_feasible` flag, per-constraint violations, and the raw per-group power arrays. See the [Power thresholds and aux diagnostics](#power-thresholds-and-aux-diagnostics) section for the aux schema.
|
|
237
237
|
|
|
238
238
|
```python
|
|
239
239
|
obj.value_aux(params) # -> (float, dict)
|
|
@@ -243,21 +243,21 @@ obj.vmap_value_and_grad_aux(params_batch) # -> (Array[batch], Array[batch, n_par
|
|
|
243
243
|
```
|
|
244
244
|
|
|
245
245
|
- `value_aux(params)` returns `(loss, aux)`. The loss is logged into the standard loss history; aux fields are recorded into the per-field aux histories only when the matching save token is enabled.
|
|
246
|
-
- `value_and_grad_aux(params)` computes loss, gradient, and aux in one forward+backward pass via `jax.value_and_grad(..., has_aux=True)`. The gradient is taken with respect to the loss
|
|
246
|
+
- `value_and_grad_aux(params)` computes loss, gradient, and aux in one forward+backward pass via `jax.value_and_grad(..., has_aux=True)`. The gradient is taken with respect to the total returned loss, including any parameter-dependent penalty. `has_aux=True` carries the aux pytree through unchanged; derivatives of aux are neither returned nor logged.
|
|
247
247
|
- `vmap_value_aux` and `vmap_value_and_grad_aux` are the batched variants. Because `aux` is a JAX pytree, a batched call adds a leading batch dim to every leaf, including the `power_values` sub-arrays.
|
|
248
|
-
- The aux methods raise `RuntimeError`
|
|
248
|
+
- The explicit aux methods raise `RuntimeError` when the wrapped problem does not expose `objective_function_aux` (for example `VoyagerProblem` and `VoyagerTuningProblem`). A custom `ContinuousProblem` may opt in by implementing the same aux objective contract.
|
|
249
249
|
|
|
250
250
|
Warmup helpers `warmup_value_aux`, `warmup_value_and_grad_aux`, `warmup_vmap_value_aux`, and `warmup_vmap_value_and_grad_aux` compile the aux callables before `start_logging()`. On problems without an aux objective they are a no-op (with a notice at `verbose >= 1`) rather than raising, so an algorithm that unconditionally warms up aux does not break on a non-constrained problem.
|
|
251
251
|
|
|
252
|
-
### Auto-logging aux from
|
|
252
|
+
### Auto-logging aux from standard value-bearing methods
|
|
253
253
|
|
|
254
|
-
When one or more aux save tokens are enabled and the problem exposes `objective_function_aux`, the standard
|
|
254
|
+
When one or more aux save tokens are enabled and the problem exposes `objective_function_aux`, the standard value-bearing methods (`value`, `value_and_grad`, `vmap_value`, `vmap_value_and_grad`, `value_grad_and_hessian`, `vmap_value_grad_and_hessian`) run the aux objective in the same forward pass and record the enabled aux diagnostics. No code change is needed in the optimization loop: a plain `obj.value(params)` call populates `is_feasible_history`, `sensitivity_loss_history`, and so on, in addition to `loss_history`.
|
|
255
255
|
|
|
256
|
-
This rebinds the internal
|
|
256
|
+
This rebinds the internal value-bearing callables to the aux variants at bind time, so the aux pytree comes out of the same simulation that produced the loss. There is no second forward pass. The returned values keep their usual shapes (`value` still returns a scalar, `value_and_grad` still returns `(loss, grad)`); internally, exactly one aux pytree travels alongside the value result and is passed directly to `_log(..., aux=aux)`.
|
|
257
257
|
|
|
258
|
-
Grad-only and Hessian-only calls (`grad`, `hessian`, `vmap_grad`, `vmap_hessian`) do not
|
|
258
|
+
Grad-only and Hessian-only calls (`grad`, `hessian`, `vmap_grad`, `vmap_hessian`) differentiate the scalar objective but do not return or carry a primal loss/aux result. They therefore append `None` placeholders to enabled aux histories so those histories stay length-aligned with `loss_history`. The history properties preserve these `None` entries; `best_is_feasible` interprets one at the best-loss index as unavailable.
|
|
259
259
|
|
|
260
|
-
Auto-logging is active only when both conditions hold: at least one aux token is in the `save` list, and the problem
|
|
260
|
+
Auto-logging is active only when both conditions hold: at least one aux token is in the construction-time `save` list, and the problem exposes `objective_function_aux`. With no aux token, standard methods use the scalar primal and aux histories stay empty, so non-aux runs pay no aux-computation overhead. Supplying an aux token for a problem without an aux objective emits `RuntimeWarning` and falls back to the same scalar path; explicit aux methods still raise `RuntimeError`. Calling `set_penalty_fn` rebinds the cached callables so the selected value family stays in sync after a penalty swap.
|
|
261
261
|
|
|
262
262
|
```python
|
|
263
263
|
obj = Objective(problem, save=["is_feasible"])
|
|
@@ -289,13 +289,31 @@ When `unbounded=True`, the returned callable maps unbounded parameters into the
|
|
|
289
289
|
|
|
290
290
|
Because this callable is intentionally unlogged, pair it with `obj.log_evaluation(...)` after each completed optimizer step if the evaluation should count toward benchmark histories. For ordinary algorithm loops, prefer `obj.value(...)`, `obj.value_and_grad(...)`, or the batched evaluation methods.
|
|
291
291
|
|
|
292
|
+
### Unlogged raw value-and-aux function
|
|
293
|
+
|
|
294
|
+
```python
|
|
295
|
+
aux_value_fn = obj.value_function_aux() # follows obj.unbounded
|
|
296
|
+
if aux_value_fn is None:
|
|
297
|
+
raise RuntimeError("this problem has no aux objective")
|
|
298
|
+
|
|
299
|
+
value_and_grad_aux_fn = jax.jit(
|
|
300
|
+
jax.value_and_grad(aux_value_fn, has_aux=True)
|
|
301
|
+
)
|
|
302
|
+
_ = value_and_grad_aux_fn(params) # JIT warmup before timing
|
|
303
|
+
obj.start_logging()
|
|
304
|
+
(loss, aux), grad = value_and_grad_aux_fn(params)
|
|
305
|
+
obj.log_evaluation(params=params, loss=loss, grad=grad, aux=aux)
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
`value_function_aux(unbounded=None)` is the mapped, JAX-compatible counterpart to `value_function()`. It returns an unlogged callable whose invocation yields `(loss, aux)`, follows the same `unbounded` argument semantics, and returns `None` when the problem does not expose `objective_function_aux`. This is the safe way for a custom JIT loop to obtain aux without bypassing the Objective's space mapping. `log_evaluation` persists only fields selected by aux save tokens.
|
|
309
|
+
|
|
292
310
|
### Manual logging
|
|
293
311
|
|
|
294
312
|
```python
|
|
295
|
-
obj.log_evaluation(params=..., loss=..., grad=..., hessian=...)
|
|
313
|
+
obj.log_evaluation(params=..., loss=..., grad=..., hessian=..., aux=...)
|
|
296
314
|
```
|
|
297
315
|
|
|
298
|
-
For algorithms with custom JIT-compiled evaluation loops that use `obj.value_function(...)` instead of calling `obj.value()` directly. Accepts
|
|
316
|
+
For algorithms with custom JIT-compiled evaluation loops that use `obj.value_function(...)` or `obj.value_function_aux(...)` instead of calling `obj.value()` directly. Accepts `params`, `loss`, `grad`, `hessian`, and optional `aux` results and performs the same history recording. Supplied aux is persisted only for matching save tokens. In an aux-enabled run, omitting `aux` records `None` in each selected aux history; manual logging never manufactures aux diagnostics.
|
|
299
317
|
|
|
300
318
|
---
|
|
301
319
|
|
|
@@ -376,7 +394,7 @@ obj.set_space_mode(
|
|
|
376
394
|
|
|
377
395
|
Sets the wrapped problem's penalty function and re-binds all internal JAX evaluation paths.
|
|
378
396
|
|
|
379
|
-
For problems that opt into the power-penalty contract (`ConstrainedVoyagerProblem`, `UIFOProblem`), this forwards to `problem.set_penalty_fn(fn)`, which updates the problem's penalty callable and
|
|
397
|
+
For problems that opt into the power-penalty contract (`ConstrainedVoyagerProblem`, `UIFOProblem`), this forwards to `problem.set_penalty_fn(fn)`, which updates the problem's penalty callable and rebuilds both its JIT-compiled scalar and aux objectives. The Objective then re-binds its own cached `value` / `grad` / `hessian` / `vmap_*` callables, mirroring the tail of `set_space_mode`.
|
|
380
398
|
|
|
381
399
|
- Must be called before `start_logging()`
|
|
382
400
|
- Raises `RuntimeError` if the wrapped problem does not opt into the power-penalty contract. The opt-in marker is the class attribute `_supports_power_penalty`; problems without a power-constraint path (`VoyagerProblem`, `VoyagerTuningProblem`, and any non-optical `ContinuousProblem`) leave it `False` and reject the call rather than silently rebuilding, even though they inherit the method from `OpticalSetupProblem`
|
|
@@ -402,10 +420,10 @@ The constrained problems also expose a JIT-compiled `objective_function_aux(para
|
|
|
402
420
|
| `sensitivity_loss` | scalar | The unpenalised sensitivity loss. |
|
|
403
421
|
| `penalty` | scalar | The summed penalty contribution. |
|
|
404
422
|
| `is_feasible` | scalar bool | `True` iff every per-group power is at or below its threshold. This is a physical check, independent of the active `power_penalty_fn` preset. |
|
|
405
|
-
| `violations` | `(n_constraints,
|
|
423
|
+
| `violations` | `(n_constraints,)` | Per-constraint penalty values. |
|
|
406
424
|
| `power_values` | dict with `hard`, `soft`, `detector` leaves | Raw per-group power arrays. |
|
|
407
425
|
|
|
408
|
-
`aux` is a JAX pytree, so `objective_function_aux` vmapps cleanly: a batched call adds a leading batch dim to every leaf, including the `power_values` sub-arrays. The Objective-level `
|
|
426
|
+
`aux` is a JAX pytree, so `objective_function_aux` vmapps cleanly: a batched call adds a leading batch dim to every leaf, including the `power_values` sub-arrays. The Objective-level explicit `*_aux` wrappers and standard value-bearing methods thread aux through logging and the save-token system; see the [Aux evaluation](#aux-evaluation) subsection and the aux tokens in [Choosing what to save](#choosing-what-to-save).
|
|
409
427
|
|
|
410
428
|
---
|
|
411
429
|
|
|
@@ -479,7 +497,7 @@ bounded ≈ lb + (ub - lb) * forward(random_params_unbounded(...))
|
|
|
479
497
|
| `best_params_bounded` | `Array \| None` | Best parameters mapped to bounded space via the active mapping (custom mapping if configured, otherwise sigmoid). **Use this for final output.** |
|
|
480
498
|
| `best_eval_index` | `int \| None` | Index into the loss history holding the best loss, or `None` before the first improvement. |
|
|
481
499
|
| `best_batch_index` | `int \| None` | Within-batch index of the best loss when it came from a batched evaluation, or `None` for single-point evals. |
|
|
482
|
-
| `best_is_feasible` | `bool \| None` | Feasibility of the best-loss point, or `None` when
|
|
500
|
+
| `best_is_feasible` | `bool \| None` | Feasibility of the best-loss point, or `None` when neither `is_feasible` nor `batched_is_feasible` was enabled, no evaluation has improved yet, or a manually logged best point omitted aux. Uses the physical `power <= threshold` check, so it stays meaningful even when the penalty is disabled with `zero_penalty`. For batched best losses, the feasibility of the winning batch element is returned when `batched_is_feasible` storage is on; otherwise the per-call reduced entry is used. |
|
|
483
501
|
|
|
484
502
|
### Current State
|
|
485
503
|
|
|
@@ -500,15 +518,15 @@ These properties return **copies** to prevent external mutation.
|
|
|
500
518
|
| `params_history` | `list` | All recorded parameter vectors (raw space, i.e. as it was given to the `Objective`). |
|
|
501
519
|
| `params_history_bounded` | `list` | Params history mapped to bounded space. |
|
|
502
520
|
| `time_steps` | `list[float]` | Elapsed time at each recorded evaluation. |
|
|
503
|
-
| `sensitivity_loss_history` | `list` | Per-
|
|
504
|
-
| `penalty_history` | `list` | Per-
|
|
505
|
-
| `is_feasible_history` | `list` | Per-
|
|
506
|
-
| `violations_history` | `list` | Per-
|
|
507
|
-
| `power_hard_history` | `list` | Per-
|
|
508
|
-
| `power_soft_history` | `list` | Per-
|
|
509
|
-
| `power_detector_history` | `list` | Per-
|
|
521
|
+
| `sensitivity_loss_history` | `list` | Per-logged-call unpenalised sensitivity loss when selected; `None` for calls without aux. |
|
|
522
|
+
| `penalty_history` | `list` | Per-logged-call summed penalty when selected; `None` for calls without aux. |
|
|
523
|
+
| `is_feasible_history` | `list` | Per-logged-call physical feasibility flag when selected; `None` for calls without aux. |
|
|
524
|
+
| `violations_history` | `list` | Per-logged-call constraint violation arrays when selected; `None` for calls without aux. |
|
|
525
|
+
| `power_hard_history` | `list` | Per-logged-call hard-group power arrays when `power_values` storage is selected; `None` for calls without aux. |
|
|
526
|
+
| `power_soft_history` | `list` | Per-logged-call soft-group power arrays when `power_values` storage is selected; `None` for calls without aux. |
|
|
527
|
+
| `power_detector_history` | `list` | Per-logged-call detector-group power arrays when `power_values` storage is selected; `None` for calls without aux. |
|
|
510
528
|
|
|
511
|
-
|
|
529
|
+
Each enabled aux history is index-aligned with `loss_history`: value-bearing standard and explicit aux calls append the selected diagnostics, while derivative-only calls and `log_evaluation(..., aux=None)` append `None`. Aux histories whose save token is disabled remain empty.
|
|
512
530
|
|
|
513
531
|
### Reduced History
|
|
514
532
|
|
|
@@ -552,7 +570,7 @@ The first save without explicit overrides caches the path; subsequent periodic s
|
|
|
552
570
|
|
|
553
571
|
### `load_run_data(filepath)`
|
|
554
572
|
|
|
555
|
-
Restores all tracking state from a checkpoint via `CheckpointManager.load()` -> `Objective._apply_run_state()`. Adjusts `start_time` so that `time_elapsed` continues seamlessly from where the checkpoint left off. The loaded path is cached so a later `save_run_data()` overwrites the same file. If the checkpoint's `SaveConfig` differs from the
|
|
573
|
+
Restores all tracking state from a checkpoint via `CheckpointManager.load()` -> `Objective._apply_run_state()`. Adjusts `start_time` so that `time_elapsed` continues seamlessly from where the checkpoint left off. The loaded path is cached so a later `save_run_data()` overwrites the same file. If the checkpoint's `SaveConfig` differs from the constructor configuration, `RuntimeWarning` is emitted and the checkpoint configuration is adopted before state is applied. When the problem supports aux logging, empty legacy aux histories selected by that config are backfilled with one `None` entry per prior logged call before evaluation resumes.
|
|
556
574
|
|
|
557
575
|
The originating `Problem` can be rebuilt from the embedded `problem_spec`:
|
|
558
576
|
|
|
@@ -603,12 +621,12 @@ Returns a snapshot dictionary:
|
|
|
603
621
|
Every evaluation method follows the same pipeline internally:
|
|
604
622
|
|
|
605
623
|
1. **Execute** the JAX function (`_func`, `_value_and_grad_func`, `_vmap_func`, etc.)
|
|
606
|
-
2. **`_log(params, loss, grad, hessian)`**:
|
|
607
|
-
3. **`_log_evals(params, loss, grad, hessian, time_exceeded)`**:
|
|
624
|
+
2. **`_log(params, loss, grad, hessian, aux)`**: takes one elapsed-time snapshot, asks `_log_evals()` to admit and atomically record the call, appends the timestamp only when admitted, then invokes `_log_to_file()`.
|
|
625
|
+
3. **`_log_evals(params, loss, grad, hessian, aux, time_exceeded)`**: checks the evaluation/time budget, resolves selected aux leaves before mutating histories, records all aligned histories, updates best/stagnation state, and returns whether the call was admitted.
|
|
608
626
|
4. **`_log_to_file()`**: calls `CheckpointManager.tick(eval_count, state_factory)`, which checks the cadence (`save_every`, set from `save_to_file_every`), lazily builds a `RunState` only when a checkpoint is due, saves it through the internal `StorageBackend`, and returns the wall-clock duration of the save. The Objective advances `_start_time` by that duration so the checkpoint write does not consume wall-clock budget.
|
|
609
627
|
|
|
610
|
-
> **Important:** These are private methods; do not call `_log()`, `_log_evals()`, or `_log_to_file()` directly from algorithm code. If you want manual logging, use the public `log_evaluation(params, loss, grad, hessian=None)` method instead, which delegates to `_log()`. See the [JIT-compiled loop guide](Implementing-a-New-Algorithm#custom-jit-compiled-loops-with-log_evaluation) for details.
|
|
628
|
+
> **Important:** These are private methods; do not call `_log()`, `_log_evals()`, or `_log_to_file()` directly from algorithm code. If you want manual logging, use the public `log_evaluation(params, loss, grad=None, hessian=None, aux=None)` method instead, which delegates to `_log()`. See the [JIT-compiled loop guide](Implementing-a-New-Algorithm#custom-jit-compiled-loops-with-log_evaluation) for details.
|
|
611
629
|
|
|
612
630
|
Budget enforcement happens *after* the evaluation returns. This means the algorithm always receives a valid result, but once any budget is exceeded the history stops growing and `budget_exceeded` becomes `True`.
|
|
613
631
|
|
|
614
|
-
When a batch evaluation (`vmap_*`) would push `eval_count` past `max_evals`, the evaluations are counted but *not logged*, preserving history alignment and setting the `budget_exceeded` flag to `True`.
|
|
632
|
+
When a batch evaluation (`vmap_*`) would push `eval_count` past `max_evals`, the evaluations are counted but *not logged*, preserving history alignment and setting the `budget_exceeded` flag to `True`. Because admission happens before history mutation, no loss, parameter, derivative, aux, or time entry needs to be rolled back. Reducing population as `evals_left` nears zero avoids evaluating an unrecorded batch.
|
|
@@ -197,7 +197,7 @@ problem = ConstrainedVoyagerProblem(n_frequencies=50, signal_floor=1e-20)
|
|
|
197
197
|
problem = ConstrainedVoyagerProblem(power_penalty_fn=my_quadratic_penalty)
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
The penalty function can also be swapped **after** the problem has been constructed (e.g. after wrapping it in an `Objective`), via `Objective.set_penalty_fn(fn)`. This
|
|
200
|
+
The penalty function can also be swapped **after** the problem has been constructed (e.g. after wrapping it in an `Objective`), via `Objective.set_penalty_fn(fn)`. This rebuilds the problem's JIT-compiled scalar and aux objectives and re-binds the Objective's cached evaluation callables, so the new penalty takes effect on subsequent evaluations. It must be called before `Objective.start_logging()`:
|
|
201
201
|
|
|
202
202
|
```python
|
|
203
203
|
from dfbench import Objective
|
|
@@ -229,7 +229,7 @@ The constrained problems also expose a JIT-compiled `objective_function_aux(para
|
|
|
229
229
|
|
|
230
230
|
Because `aux` is a JAX pytree, `objective_function_aux` vmapps cleanly: a batched call adds a leading batch dim to every leaf, including the `power_values` sub-arrays.
|
|
231
231
|
|
|
232
|
-
The `Objective` wraps this with `value_aux`, `value_and_grad_aux`, `vmap_value_aux`, and `vmap_value_and_grad_aux`. These thread aux through logging
|
|
232
|
+
The `Objective` wraps this with `value_aux`, `value_and_grad_aux`, `vmap_value_aux`, and `vmap_value_and_grad_aux`. These explicit methods—and standard value-bearing methods when an aux save token is selected—thread aux through logging without a second forward pass. Each aux field has its own token (`sensitivity_loss`, `penalty`, `is_feasible`, `power_values`, `violations`) plus a `batched_*` variant and `aux` / `batched_aux` convenience aliases. Derivative-only calls do not produce a primal aux pytree and append `None` to enabled aux histories. When a `batched_*` token is off and the non-batched token is on, aux from every batched value-bearing call, including a singleton batch, is reduced to the representative point picked by the loss minimum. `Objective.best_is_feasible` reports the feasibility of the best-loss point from that recorded history. Full reference in the [Objective API Reference](Objective-API-Reference).
|
|
233
233
|
|
|
234
234
|
---
|
|
235
235
|
|