From b117132697e4e0dd1d79b6c3e2534069f665af87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Mon, 20 Oct 2025 13:52:32 +0300 Subject: [PATCH 01/13] reorder fields in OptimizationCache for cleaner dispatches Since we always dispatch on the optimizer, it makes much more sense to have this as the first argument (and first type parameter) --- lib/OptimizationBase/src/cache.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/OptimizationBase/src/cache.jl b/lib/OptimizationBase/src/cache.jl index 9454e4f03..309199405 100644 --- a/lib/OptimizationBase/src/cache.jl +++ b/lib/OptimizationBase/src/cache.jl @@ -5,8 +5,9 @@ struct AnalysisResults{O, C} constraints::C end -struct OptimizationCache{F, RC, LB, UB, LC, UC, S, O, P, C, M} <: +struct OptimizationCache{O, F, RC, LB, UB, LC, UC, S, P, C, M} <: SciMLBase.AbstractOptimizationCache + opt::O f::F reinit_cache::RC lb::LB @@ -14,7 +15,6 @@ struct OptimizationCache{F, RC, LB, UB, LC, UC, S, O, P, C, M} <: lcons::LC ucons::UC sense::S - opt::O progress::P callback::C manifold::M @@ -46,13 +46,13 @@ function OptimizationCache(prob::SciMLBase.OptimizationProblem, opt; prob.f.adtype isa AutoZygote) && (SciMLBase.requireshessian(opt) || SciMLBase.requiresconshess(opt) || SciMLBase.requireslagh(opt)) - @warn "The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. - So a `SecondOrder` with $(prob.f.adtype) for both inner and outer will be created, this can be suboptimal and not work in some cases so + @warn "The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. + So a `SecondOrder` with $(prob.f.adtype) for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended." elseif prob.f.adtype isa AutoZygote && (SciMLBase.requiresconshess(opt) || SciMLBase.requireslagh(opt) || SciMLBase.requireshessian(opt)) - @warn "The selected optimization algorithm requires second order derivatives, but `AutoZygote` ADtype was provided. + @warn "The selected optimization algorithm requires second order derivatives, but `AutoZygote` ADtype was provided. So a `SecondOrder` with `AutoZygote` for inner and `AutoForwardDiff` for outer will be created, for choosing another pair an explicit `SecondOrder` ADtype is recommended." end @@ -71,9 +71,9 @@ function OptimizationCache(prob::SciMLBase.OptimizationProblem, opt; cons_res = nothing end - return OptimizationCache(f, reinit_cache_passedon, prob.lb, prob.ub, prob.lcons, + return OptimizationCache(opt, f, reinit_cache_passedon, prob.lb, prob.ub, prob.lcons, prob.ucons, prob.sense, - opt, progress, callback, manifold, AnalysisResults(obj_res, cons_res), + progress, callback, manifold, AnalysisResults(obj_res, cons_res), merge((; maxiters, maxtime, abstol, reltol), NamedTuple(kwargs))) end From 6e4e7c6d297701857c9077c7bc4e2b18a633f7a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Wed, 15 Oct 2025 17:02:21 +0300 Subject: [PATCH 02/13] bump version number for OptimizationBase this is for changing the order of the fields in the OptimizationCache --- lib/OptimizationBase/Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OptimizationBase/Project.toml b/lib/OptimizationBase/Project.toml index b71b86852..ab8af9ca9 100644 --- a/lib/OptimizationBase/Project.toml +++ b/lib/OptimizationBase/Project.toml @@ -1,7 +1,7 @@ name = "OptimizationBase" uuid = "bca83a33-5cc9-4baa-983d-23429ab6bcbb" authors = ["Vaibhav Dixit and contributors"] -version = "3.3.1" +version = "4.0.0" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" From cced8fc93811ca41068dd0da3c1a8c1b87dd1208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Wed, 22 Oct 2025 15:44:04 +0300 Subject: [PATCH 03/13] replace supports_opt_cache_interface with has_init --- lib/OptimizationBase/Project.toml | 2 +- lib/OptimizationBase/src/OptimizationBase.jl | 8 ++------ lib/OptimizationBase/src/solve.jl | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/OptimizationBase/Project.toml b/lib/OptimizationBase/Project.toml index ab8af9ca9..4576abbf6 100644 --- a/lib/OptimizationBase/Project.toml +++ b/lib/OptimizationBase/Project.toml @@ -55,7 +55,7 @@ ModelingToolkit = "10.23" PDMats = "0.11" Reexport = "1.2" ReverseDiff = "1.14" -SciMLBase = "2.104" +SciMLBase = "2.122" SparseConnectivityTracer = "0.6, 1" SparseMatrixColorings = "0.4" SymbolicAnalysis = "0.3" diff --git a/lib/OptimizationBase/src/OptimizationBase.jl b/lib/OptimizationBase/src/OptimizationBase.jl index 4849f74ae..230f5bca8 100644 --- a/lib/OptimizationBase/src/OptimizationBase.jl +++ b/lib/OptimizationBase/src/OptimizationBase.jl @@ -15,15 +15,10 @@ import SciMLBase: solve, init, solve!, __init, __solve, requireshessian, requiresconsjac, requiresconshess -supports_opt_cache_interface(alg) = false -@static if !hasmethod(SciMLBase.__solve, Tuple{OptimizationProblem, SciMLBase.AbstractOptimizationAlgorithm}) - include("solve.jl") -end - export ObjSense, MaxSense, MinSense export allowsbounds, requiresbounds, allowsconstraints, requiresconstraints, allowscallback, requiresgradient, requireshessian, - requiresconsjac, requiresconshess, supports_opt_cache_interface + requiresconsjac, requiresconshess using FastClosures @@ -36,6 +31,7 @@ const DEFAULT_DATA = Iterators.cycle((NullData(),)) Base.iterate(::NullData, i = 1) = nothing Base.length(::NullData) = 0 +include("solve.jl") include("adtypes.jl") include("symify.jl") include("cache.jl") diff --git a/lib/OptimizationBase/src/solve.jl b/lib/OptimizationBase/src/solve.jl index 273c32e38..cd1a80607 100644 --- a/lib/OptimizationBase/src/solve.jl +++ b/lib/OptimizationBase/src/solve.jl @@ -92,7 +92,7 @@ from NLopt for an example. The common local optimizer arguments are: """ function solve(prob::SciMLBase.OptimizationProblem, alg, args...; kwargs...)::SciMLBase.AbstractOptimizationSolution - if SciMLBase.supports_opt_cache_interface(alg) + if SciMLBase.has_init(alg) solve!(init(prob, alg, args...; kwargs...)) else if prob.u0 !== nothing && !isconcretetype(eltype(prob.u0)) From 707fcead80e7af7aa758f82c2ea6ca2574396ef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Wed, 22 Oct 2025 15:58:14 +0300 Subject: [PATCH 04/13] fix typo --- lib/OptimizationManopt/test/runtests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/OptimizationManopt/test/runtests.jl b/lib/OptimizationManopt/test/runtests.jl index 3a1e276b7..9e22be677 100644 --- a/lib/OptimizationManopt/test/runtests.jl +++ b/lib/OptimizationManopt/test/runtests.jl @@ -166,7 +166,7 @@ R2 = Euclidean(2) opt = OptimizationManopt.TrustRegionsOptimizer() - #TODO: This autodiff currently provides a Hessian that seem to not procide a Hessian + #TODO: This autodiff currently provides a Hessian that seem to not provide a Hessian # TR Fails but also AD before that warns. So it passes _some_ hessian but a wrong one, even in format optprob = OptimizationFunction(rosenbrock, AutoForwardDiff()) prob = OptimizationProblem(optprob, x0, p; manifold = R2) @@ -187,4 +187,4 @@ R2 = Euclidean(2) #TODO: What is this? @test_throws SciMLBase.IncompatibleOptimizerError OptimizationBase.solve(prob_cons, opt) end -end \ No newline at end of file +end From d69f421708e91c4d59cdea729131cb450043c18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Wed, 22 Oct 2025 19:21:17 +0300 Subject: [PATCH 05/13] dev OptimizationBase for Core tests --- test/runtests.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/test/runtests.jl b/test/runtests.jl index 2e1b7f39f..cc49b3f5b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -15,6 +15,7 @@ function activate_subpkg_env(subpkg) end if GROUP == "All" || GROUP == "Core" + dev_subpkg("OptimizationBase") dev_subpkg("OptimizationOptimJL") dev_subpkg("OptimizationOptimisers") dev_subpkg("OptimizationMOI") From ab856a0a9531062ac524b8e50a09d95712ce2b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Wed, 22 Oct 2025 19:21:28 +0300 Subject: [PATCH 06/13] use julia 1.11 --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 1a5824453..0492be430 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -45,7 +45,7 @@ jobs: - OptimizationPolyalgorithms - OptimizationNLPModels version: - - '1' + - '1.1' - 'lts' steps: - uses: actions/checkout@v4 From d75f3ee0c31ed269858067656654509518d9ba3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Wed, 22 Oct 2025 19:28:01 +0300 Subject: [PATCH 07/13] use `dev_subpkg` when sources is not available --- test/runtests.jl | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index cc49b3f5b..193d2c51b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -14,17 +14,19 @@ function activate_subpkg_env(subpkg) Pkg.instantiate() end -if GROUP == "All" || GROUP == "Core" - dev_subpkg("OptimizationBase") - dev_subpkg("OptimizationOptimJL") - dev_subpkg("OptimizationOptimisers") - dev_subpkg("OptimizationMOI") -elseif GROUP == "GPU" || GROUP == "OptimizationPolyalgorithms" - dev_subpkg("OptimizationOptimJL") - dev_subpkg("OptimizationOptimisers") -elseif GROUP == "OptimizationNLPModels" - dev_subpkg("OptimizationOptimJL") - dev_subpkg("OptimizationMOI") +if VERSION < v"1.11" + if GROUP == "All" || GROUP == "Core" + dev_subpkg("OptimizationBase") + dev_subpkg("OptimizationOptimJL") + dev_subpkg("OptimizationOptimisers") + dev_subpkg("OptimizationMOI") + elseif GROUP == "GPU" || GROUP == "OptimizationPolyalgorithms" + dev_subpkg("OptimizationOptimJL") + dev_subpkg("OptimizationOptimisers") + elseif GROUP == "OptimizationNLPModels" + dev_subpkg("OptimizationOptimJL") + dev_subpkg("OptimizationMOI") + end end @time begin From df32e69c4372bb2553d28731d6a71a949d62c0d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Wed, 22 Oct 2025 19:41:01 +0300 Subject: [PATCH 08/13] add the julia version to the cache key Co-authored-by: Claude --- .github/workflows/CI.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 0492be430..56f225edb 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -57,10 +57,10 @@ jobs: cache-name: cache-artifacts with: path: ~/.julia/artifacts - key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} + key: ${{ runner.os }}-test-${{ matrix.version }}-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} restore-keys: | - ${{ runner.os }}-test-${{ env.cache-name }}- - ${{ runner.os }}-test- + ${{ runner.os }}-test-${{ matrix.version }}-${{ env.cache-name }}- + ${{ runner.os }}-test-${{ matrix.version }}- ${{ runner.os }}- - uses: julia-actions/julia-buildpkg@v1 - if: ${{ matrix.group == 'OptimizationQuadDIRECT' }} From 12437afe0ab382b9a5796503319387a658ff0fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Wed, 22 Oct 2025 19:54:11 +0300 Subject: [PATCH 09/13] fix julia version --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 56f225edb..d1abf8879 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -45,7 +45,7 @@ jobs: - OptimizationPolyalgorithms - OptimizationNLPModels version: - - '1.1' + - '1.11' - 'lts' steps: - uses: actions/checkout@v4 From a389bc7ee5949563fe79fb64d20dd42944418d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Wed, 22 Oct 2025 19:54:18 +0300 Subject: [PATCH 10/13] fix compat --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 00af684ea..7bc2875ba 100644 --- a/Project.toml +++ b/Project.toml @@ -49,7 +49,7 @@ ModelingToolkit = "10.23" Mooncake = "0.4.138" Optim = ">= 1.4.1" Optimisers = ">= 0.2.5" -OptimizationBase = "3" +OptimizationBase = "4" OptimizationLBFGSB = "1" OptimizationMOI = "0.5" OptimizationOptimJL = "0.4" From cb89f61ee45e8394cbab14e384db5bbda639d9cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Wed, 22 Oct 2025 20:10:58 +0300 Subject: [PATCH 11/13] add OptimizationBase tests to CI Co-authored-by: Claude --- .github/workflows/CI.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d1abf8879..e0a9ec268 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -19,6 +19,7 @@ jobs: matrix: group: - Core + - OptimizationBase - OptimizationAuglag - OptimizationBBO - OptimizationCMAEvolutionStrategy @@ -70,7 +71,7 @@ jobs: GROUP: ${{ matrix.group }} - uses: julia-actions/julia-processcoverage@v1 with: - directories: src,lib/OptimizationBBO/src,lib/OptimizationCMAEvolutionStrategy/src,lib/OptimizationEvolutionary/src,lib/OptimizationGCMAES/src,lib/OptimizationIpopt/src,lib/OptimizationMadNLP/src,lib/OptimizationManopt/src,lib/OptimizationMOI/src,lib/OptimizationMetaheuristics/src,lib/OptimizationMultistartOptimization/src,lib/OptimizationNLopt/src,lib/OptimizationNOMAD/src,lib/OptimizationOptimJL/src,lib/OptimizationOptimisers/src,lib/OptimizationPolyalgorithms/src,lib/OptimizationQuadDIRECT/src,lib/OptimizationSpeedMapping/src + directories: src,lib/OptimizationBase/src,lib/OptimizationBBO/src,lib/OptimizationCMAEvolutionStrategy/src,lib/OptimizationEvolutionary/src,lib/OptimizationGCMAES/src,lib/OptimizationIpopt/src,lib/OptimizationMadNLP/src,lib/OptimizationManopt/src,lib/OptimizationMOI/src,lib/OptimizationMetaheuristics/src,lib/OptimizationMultistartOptimization/src,lib/OptimizationNLopt/src,lib/OptimizationNOMAD/src,lib/OptimizationOptimJL/src,lib/OptimizationOptimisers/src,lib/OptimizationPolyalgorithms/src,lib/OptimizationQuadDIRECT/src,lib/OptimizationSpeedMapping/src - uses: codecov/codecov-action@v5 with: - file: lcov.info + files: lcov.info From 4bd29a7422b8bcbe029c4a03c2f251e1e0ffd03d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Thu, 23 Oct 2025 14:36:59 +0300 Subject: [PATCH 12/13] add IIP parameter to OptimizationCache --- lib/OptimizationBase/src/cache.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/OptimizationBase/src/cache.jl b/lib/OptimizationBase/src/cache.jl index 309199405..cddd20f9c 100644 --- a/lib/OptimizationBase/src/cache.jl +++ b/lib/OptimizationBase/src/cache.jl @@ -5,7 +5,9 @@ struct AnalysisResults{O, C} constraints::C end -struct OptimizationCache{O, F, RC, LB, UB, LC, UC, S, P, C, M} <: +struct OptimizationCache{ + O, IIP, F <: SciMLBase.AbstractOptimizationFunction{IIP}, + RC, LB, UB, LC, UC, S, P, C, M} <: SciMLBase.AbstractOptimizationCache opt::O f::F @@ -74,8 +76,7 @@ function OptimizationCache(prob::SciMLBase.OptimizationProblem, opt; return OptimizationCache(opt, f, reinit_cache_passedon, prob.lb, prob.ub, prob.lcons, prob.ucons, prob.sense, progress, callback, manifold, AnalysisResults(obj_res, cons_res), - merge((; maxiters, maxtime, abstol, reltol), - NamedTuple(kwargs))) + merge((; maxiters, maxtime, abstol, reltol), NamedTuple(kwargs))) end function SciMLBase.__init(prob::SciMLBase.OptimizationProblem, opt; From 3480babff79df27b9712a87abb01b20f75550be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Miclu=C8=9Ba-C=C3=A2mpeanu?= Date: Thu, 23 Oct 2025 14:46:38 +0300 Subject: [PATCH 13/13] add isinplace for OptimizationCache --- lib/OptimizationBase/src/cache.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/OptimizationBase/src/cache.jl b/lib/OptimizationBase/src/cache.jl index cddd20f9c..ec633283f 100644 --- a/lib/OptimizationBase/src/cache.jl +++ b/lib/OptimizationBase/src/cache.jl @@ -92,6 +92,8 @@ function SciMLBase.__init(prob::SciMLBase.OptimizationProblem, opt; kwargs...) end +SciMLBase.isinplace(::OptimizationCache{o, iip}) where {o, iip} = iip + # Wrapper for fields that may change in `reinit!(cache)` of a cache. mutable struct ReInitCache{uType, P} u0::uType