Skip to content

Commit

Permalink
Merge pull request #782 from SciML/retcodefix
Browse files Browse the repository at this point in the history
Add more retcode testing and fix space in lbfgsb return
  • Loading branch information
Vaibhavdixit02 authored Jun 28, 2024
2 parents 3cf9340 + 88f2a5b commit 0f30302
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 154 deletions.
1 change: 0 additions & 1 deletion docs/pages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ pages = ["index.md",
"BlackBoxOptim.jl" => "optimization_packages/blackboxoptim.md",
"CMAEvolutionStrategy.jl" => "optimization_packages/cmaevolutionstrategy.md",
"Evolutionary.jl" => "optimization_packages/evolutionary.md",
"Flux.jl" => "optimization_packages/flux.md",
"GCMAES.jl" => "optimization_packages/gcmaes.md",
"Manopt.jl" => "optimization_packages/manopt.md",
"MathOptInterface.jl" => "optimization_packages/mathoptinterface.md",
Expand Down
135 changes: 0 additions & 135 deletions docs/src/optimization_packages/flux.md

This file was deleted.

6 changes: 4 additions & 2 deletions lib/OptimizationManopt/src/OptimizationManopt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,10 @@ function SciMLBase.__solve(cache::OptimizationCache{
local x, cur, state

manifold = haskey(cache.solver_args, :manifold) ? cache.solver_args[:manifold] : nothing
gradF = haskey(cache.solver_args, :riemannian_grad) ? cache.solver_args[:riemannian_grad] : nothing
hessF = haskey(cache.solver_args, :riemannian_hess) ? cache.solver_args[:riemannian_hess] : nothing
gradF = haskey(cache.solver_args, :riemannian_grad) ?
cache.solver_args[:riemannian_grad] : nothing
hessF = haskey(cache.solver_args, :riemannian_hess) ?
cache.solver_args[:riemannian_hess] : nothing

if manifold === nothing
throw(ArgumentError("Manifold not specified in the problem for e.g. `OptimizationProblem(f, x, p; manifold = SymmetricPositiveDefinite(5))`."))
Expand Down
24 changes: 16 additions & 8 deletions src/lbfgsb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,11 @@ function SciMLBase.__solve(cache::OptimizationCache{
n = length(cache.u0)

if cache.lb === nothing
optimizer, bounds = LBFGSB._opt_bounds(n, cache.opt.m, [-Inf for i in 1:n], [Inf for i in 1:n])
optimizer, bounds = LBFGSB._opt_bounds(
n, cache.opt.m, [-Inf for i in 1:n], [Inf for i in 1:n])
else
optimizer, bounds = LBFGSB._opt_bounds(n, cache.opt.m, solver_kwargs.lb, solver_kwargs.ub)
optimizer, bounds = LBFGSB._opt_bounds(
n, cache.opt.m, solver_kwargs.lb, solver_kwargs.ub)
end

solver_kwargs = Base.structdiff(solver_kwargs, (; lb = nothing, ub = nothing))
Expand All @@ -182,7 +184,8 @@ function SciMLBase.__solve(cache::OptimizationCache{
prev_eqcons .= cons_tmp[eq_inds]
prevβ .= copy(β)

res = optimizer(_loss, aug_grad, θ, bounds; solver_kwargs..., m = cache.opt.m, pgtol = sqrt(ϵ), maxiter = maxiters / 100)
res = optimizer(_loss, aug_grad, θ, bounds; solver_kwargs...,
m = cache.opt.m, pgtol = sqrt(ϵ), maxiter = maxiters / 100)
# @show res[2]
# @show res[1]
# @show cons_tmp
Expand Down Expand Up @@ -211,7 +214,8 @@ function SciMLBase.__solve(cache::OptimizationCache{
stats = Optimization.OptimizationStats(; iterations = maxiters,
time = 0.0, fevals = maxiters, gevals = maxiters)
return SciMLBase.build_solution(
cache, cache.opt, res[2], cache.f(res[2], cache.p)[1], stats = stats, retcode = opt_ret)
cache, cache.opt, res[2], cache.f(res[2], cache.p)[1],
stats = stats, retcode = opt_ret)
else
_loss = function (θ)
x = cache.f(θ, cache.p)
Expand All @@ -226,16 +230,19 @@ function SciMLBase.__solve(cache::OptimizationCache{
n = length(cache.u0)

if cache.lb === nothing
optimizer, bounds= LBFGSB._opt_bounds(n, cache.opt.m, [-Inf for i in 1:n], [Inf for i in 1:n])
optimizer, bounds = LBFGSB._opt_bounds(
n, cache.opt.m, [-Inf for i in 1:n], [Inf for i in 1:n])
else
optimizer, bounds= LBFGSB._opt_bounds(n, cache.opt.m, solver_kwargs.lb, solver_kwargs.ub)
optimizer, bounds = LBFGSB._opt_bounds(
n, cache.opt.m, solver_kwargs.lb, solver_kwargs.ub)
end

solver_kwargs = Base.structdiff(solver_kwargs, (; lb = nothing, ub = nothing))

t0 = time()

res = optimizer(_loss, cache.f.grad, cache.u0, bounds; m = cache.opt.m, solver_kwargs...)
res = optimizer(
_loss, cache.f.grad, cache.u0, bounds; m = cache.opt.m, solver_kwargs...)

# Extract the task message from the result
stop_reason = task_message_to_string(optimizer.task)
Expand All @@ -247,6 +254,7 @@ function SciMLBase.__solve(cache::OptimizationCache{
stats = Optimization.OptimizationStats(; iterations = maxiters,
time = t1 - t0, fevals = maxiters, gevals = maxiters)

return SciMLBase.build_solution(cache, cache.opt, res[2], res[1], stats = stats, retcode = opt_ret)
return SciMLBase.build_solution(cache, cache.opt, res[2], res[1], stats = stats,
retcode = opt_ret, original = optimizer)
end
end
10 changes: 4 additions & 6 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ function check_pkg_version(pkg::String, ver::String;
pkg_info[pkg].version > VersionNumber(ver)
end


# RetCode handling for BBO and others.
using SciMLBase: ReturnCode

Expand All @@ -76,7 +75,7 @@ const STOP_REASON_MAP = Dict(
r"Delta fitness .* below tolerance .*" => ReturnCode.Success,
r"Fitness .* within tolerance .* of optimum" => ReturnCode.Success,
r"CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL" => ReturnCode.Success,
r"Unrecognized stop reason: CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH" => ReturnCode.Success,
r"^CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR\*EPSMCH\s*$" => ReturnCode.Success,
r"Terminated" => ReturnCode.Terminated,
r"MaxIters|MAXITERS_EXCEED|Max number of steps .* reached" => ReturnCode.MaxIters,
r"MaxTime|TIME_LIMIT" => ReturnCode.MaxTime,
Expand All @@ -102,11 +101,11 @@ const STOP_REASON_MAP = Dict(
function deduce_retcode(stop_reason::String)
for (pattern, retcode) in STOP_REASON_MAP
if occursin(pattern, stop_reason)
return retcode
return retcode
end
end
@warn "Unrecognized stop reason: $stop_reason. Defaulting to ReturnCode.Failure."
return ReturnCode.Failure
@warn "Unrecognized stop reason: $stop_reason. Defaulting to ReturnCode.Default."
return ReturnCode.Default
end

# Function to deduce ReturnCode from a Symbol
Expand Down Expand Up @@ -141,4 +140,3 @@ function deduce_retcode(retcode::Symbol)
return ReturnCode.Failure
end
end

7 changes: 7 additions & 0 deletions test/ADtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,15 @@ prob = OptimizationProblem(optf, x0)

sol = solve(prob, Optim.BFGS())
@test 10 * sol.objective < l1
@test sol.retcode == ReturnCode.Success

sol = solve(prob, Optim.Newton())
@test 10 * sol.objective < l1
@test sol.retcode == ReturnCode.Success

sol = solve(prob, Optim.KrylovTrustRegion())
@test 10 * sol.objective < l1
@test sol.retcode == ReturnCode.Success

optf = OptimizationFunction(rosenbrock, Optimization.AutoZygote())
optprob = Optimization.instantiate_function(optf, x0, Optimization.AutoZygote(), nothing)
Expand Down Expand Up @@ -403,10 +406,12 @@ for consf in [cons, con2_c]
prob1 = OptimizationProblem(optf1, [0.3, 0.5], lb = [0.2, 0.4], ub = [0.6, 0.8],
lcons = lcons, ucons = ucons)
sol1 = solve(prob1, Optim.IPNewton())
@test sol1.retcode == ReturnCode.Success
optf2 = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff(); cons = consf)
prob2 = OptimizationProblem(optf2, [0.3, 0.5], lb = [0.2, 0.4], ub = [0.6, 0.8],
lcons = lcons, ucons = ucons)
sol2 = solve(prob2, Optim.IPNewton())
@test sol2.retcode == ReturnCode.Success
@test sol1.objectivesol2.objective rtol=1e-4
@test sol1.u sol2.u
res = Array{Float64}(undef, length(lcons))
Expand All @@ -421,9 +426,11 @@ for consf in [cons, con2_c]
optf1 = OptimizationFunction(rosenbrock, Optimization.AutoFiniteDiff(); cons = consf)
prob1 = OptimizationProblem(optf1, [0.5, 0.5], lcons = lcons, ucons = ucons)
sol1 = solve(prob1, Optim.IPNewton())
@test sol1.retcode == ReturnCode.Success
optf2 = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff(); cons = consf)
prob2 = OptimizationProblem(optf2, [0.5, 0.5], lcons = lcons, ucons = ucons)
sol2 = solve(prob2, Optim.IPNewton())
@test sol2.retcode == ReturnCode.Success
@test sol1.objectivesol2.objective rtol=1e-4
@test sol1.usol2.u rtol=1e-4
res = Array{Float64}(undef, length(lcons))
Expand Down
7 changes: 5 additions & 2 deletions test/lbfgsb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ x0 = zeros(2)
rosenbrock(x, p = nothing) = (1 - x[1])^2 + 100 * (x[2] - x[1]^2)^2
l1 = rosenbrock(x0)

optf = OptimizationFunction(rosenbrock, AutoEnzyme())
optf = OptimizationFunction(rosenbrock, AutoForwardDiff())
prob = OptimizationProblem(optf, x0)
@time res = solve(prob, Optimization.LBFGS(), maxiters = 100)
@test res.retcode == Optimization.SciMLBase.ReturnCode.Success

prob = OptimizationProblem(optf, x0, lb = [-1.0, -1.0], ub = [1.0, 1.0])
prob = OptimizationProblem(optf, x0, lb = [-1.0, -1.0], ub = [1.0, 1.0])
@time res = solve(prob, Optimization.LBFGS(), maxiters = 100)
@test res.retcode == Optimization.SciMLBase.ReturnCode.Success

function con2_c(res, x, p)
res .= [x[1]^2 + x[2]^2, (x[2] * sin(x[1]) + x[1]) - 5]
Expand All @@ -22,3 +24,4 @@ prob = OptimizationProblem(optf, x0, lcons = [1.0, -Inf],
ucons = [1.0, 0.0], lb = [-1.0, -1.0],
ub = [1.0, 1.0])
@time res = solve(prob, Optimization.LBFGS(), maxiters = 100)
@test res.retcode == Optimization.SciMLBase.ReturnCode.MaxIters

0 comments on commit 0f30302

Please sign in to comment.