Optimization.jl
Optimization.jl copied to clipboard
Error with Ipopt through Nonconvex
The example from the documentation throws an error.
julia> using GalacticOptim, Nonconvex
julia> Nonconvex.@load Ipopt
[ Info: Attempting to load the package NonconvexIpopt.
[ Info: Loading succesful.
julia> rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
rosenbrock (generic function with 1 method)
julia> x0 = zeros(2)
2-element Vector{Float64}:
0.0
0.0
julia> p = [1.0, 100.0]
2-element Vector{Float64}:
1.0
100.0
julia> f = OptimizationFunction(rosenbrock)
(::OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}) (generic function with 1 method)
julia> prob = GalacticOptim.OptimizationProblem(f, x0, p, lb = [-1.0,-1.0], ub = [1.0,1.0])
OptimizationProblem. In-place: true
u0: 2-element Vector{Float64}:
0.0
0.0
julia> solve(prob, IpoptAlg())
ERROR: MethodError: objects of type Nothing are not callable
Stacktrace:
[1] rrule(f::GalacticOptim.NonconvexADWrapper{OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}}, θ::Vector{Float64})
@ GalacticOptim C:\Users\ilyao\.julia\packages\GalacticOptim\fow0r\src\solve\nonconvex\nonconvex.jl:16
[2] rrule(::Zygote.ZygoteRuleConfig{Zygote.Context}, ::GalacticOptim.NonconvexADWrapper{OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}}, ::Vector{Float64})
@ ChainRulesCore C:\Users\ilyao\.julia\packages\ChainRulesCore\RbX5a\src\rules.jl:134
[3] chain_rrule
@ C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\chainrules.jl:216 [inlined]
[4] macro expansion
@ C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\interface2.jl:0 [inlined]
[5] _pullback(ctx::Zygote.Context, f::GalacticOptim.NonconvexADWrapper{OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}}, args::Vector{Float64})
@ Zygote C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\interface2.jl:9
[6] _pullback
@ C:\Users\ilyao\.julia\packages\GalacticOptim\fow0r\src\solve\nonconvex\nonconvex.jl:69 [inlined]
[7] _pullback(ctx::Zygote.Context, f::GalacticOptim.var"#opt_f#264"{GalacticOptim.NonconvexADWrapper{OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}}}, args::Vector{Float64})
@ Zygote C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\interface2.jl:0
[8] _apply(::Function, ::Vararg{Any})
@ Core .\boot.jl:814
[9] adjoint
@ C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\lib\lib.jl:200 [inlined]
[10] _pullback
@ C:\Users\ilyao\.julia\packages\ZygoteRules\AIbCs\src\adjoint.jl:65 [inlined]
[11] _pullback
@ C:\Users\ilyao\.julia\packages\NonconvexCore\b8vFh\src\functions\functions.jl:170 [inlined]
[12] _pullback(::Zygote.Context, ::NonconvexCore.var"##_#8", ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::NonconvexCore.Objective{GalacticOptim.var"#opt_f#264"{GalacticOptim.NonconvexADWrapper{OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}}}, Base.RefValue{Float64}, Set{Symbol}}, ::Vector{Float64})
@ Zygote C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\interface2.jl:0
[13] _apply(::Function, ::Vararg{Any})
@ Core .\boot.jl:814
[14] adjoint
@ C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\lib\lib.jl:200 [inlined]
[15] _pullback
@ C:\Users\ilyao\.julia\packages\ZygoteRules\AIbCs\src\adjoint.jl:65 [inlined]
[16] _pullback
@ C:\Users\ilyao\.julia\packages\NonconvexCore\b8vFh\src\functions\functions.jl:170 [inlined]
[17] _pullback(ctx::Zygote.Context, f::NonconvexCore.Objective{GalacticOptim.var"#opt_f#264"{GalacticOptim.NonconvexADWrapper{OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}}}, Base.RefValue{Float64}, Set{Symbol}}, args::Vector{Float64})
@ Zygote C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\interface2.jl:0
[18] _pullback
@ C:\Users\ilyao\.julia\packages\NonconvexCore\b8vFh\src\models\vec_model.jl:90 [inlined]
[19] _pullback(ctx::Zygote.Context, f::NonconvexCore.var"#133#140"{Model{Vector{Any}}, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, args::Vector{Float64})
@ Zygote C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\interface2.jl:0
[20] _apply
@ .\boot.jl:814 [inlined]
[21] adjoint
@ C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\lib\lib.jl:200 [inlined]
[22] _pullback
@ C:\Users\ilyao\.julia\packages\ZygoteRules\AIbCs\src\adjoint.jl:65 [inlined]
[23] _pullback
@ C:\Users\ilyao\.julia\packages\NonconvexCore\b8vFh\src\functions\functions.jl:170 [inlined]
[24] _pullback(::Zygote.Context, ::NonconvexCore.var"##_#8", ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::NonconvexCore.Objective{NonconvexCore.var"#133#140"{Model{Vector{Any}}, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, Base.RefValue{Float64}, Set{Symbol}}, ::Vector{Float64})
@ Zygote C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\interface2.jl:0
[25] _apply(::Function, ::Vararg{Any})
@ Core .\boot.jl:814
[26] adjoint
@ C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\lib\lib.jl:200 [inlined]
[27] _pullback
@ C:\Users\ilyao\.julia\packages\ZygoteRules\AIbCs\src\adjoint.jl:65 [inlined]
[28] _pullback
@ C:\Users\ilyao\.julia\packages\NonconvexCore\b8vFh\src\functions\functions.jl:170 [inlined]
[29] _pullback
@ C:\Users\ilyao\.julia\packages\NonconvexCore\b8vFh\src\functions\counting_function.jl:9 [inlined]
[30] _pullback(ctx::Zygote.Context, f::NonconvexCore.CountingFunction{NonconvexCore.Objective{NonconvexCore.var"#133#140"{Model{Vector{Any}}, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, Base.RefValue{Float64}, Set{Symbol}}}, args::Vector{Float64})
@ Zygote C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\interface2.jl:0
[31] _pullback(f::Function, args::Vector{Float64})
@ Zygote C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\interface.jl:34
[32] pullback(f::Function, args::Vector{Float64})
@ Zygote C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\interface.jl:40
[33] gradient(f::Function, args::Vector{Float64})
@ Zygote C:\Users\ilyao\.julia\packages\Zygote\H6vD3\src\compiler\interface.jl:75
[34] (::NonconvexIpopt.var"#eval_grad_f#13"{NonconvexCore.CountingFunction{NonconvexCore.Objective{NonconvexCore.var"#133#140"{Model{Vector{Any}}, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, Base.RefValue{Float64}, Set{Symbol}}}})(x::Vector{Float64}, grad_f::Vector{Float64})
@ NonconvexIpopt C:\Users\ilyao\.julia\packages\NonconvexIpopt\jkxtN\src\ipopt.jl:135
[35] _Eval_Grad_F_CB(n::Int32, x_ptr::Ptr{Float64}, #unused#::Int32, grad_f::Ptr{Float64}, user_data::Ptr{Nothing})
@ Ipopt C:\Users\ilyao\.julia\packages\Ipopt\M2QE8\src\C_wrapper.jl:49
[36] IpoptSolve(prob::Ipopt.IpoptProblem)
@ Ipopt C:\Users\ilyao\.julia\packages\Ipopt\M2QE8\src\C_wrapper.jl:433
[37] optimize!(workspace::NonconvexIpopt.IpoptWorkspace{NonconvexCore.VecModel{Vector{Float64}}, Ipopt.IpoptProblem, Vector{Float64}, IpoptOptions{NamedTuple{(:hessian_approximation, :jac_c_constant, :jac_d_constant), Tuple{String, String, String}}}, Base.RefValue{Int64}})
@ NonconvexIpopt C:\Users\ilyao\.julia\packages\NonconvexIpopt\jkxtN\src\ipopt.jl:52
[38] #optimize#131
@ C:\Users\ilyao\.julia\packages\NonconvexCore\b8vFh\src\models\vec_model.jl:74 [inlined]
[39] optimize(::Model{Vector{Any}}, ::IpoptAlg, ::Vector{Float64}; kwargs::Base.Pairs{Symbol, IpoptOptions{NamedTuple{(:hessian_approximation, :jac_c_constant, :jac_d_constant), Tuple{String, String, String}}}, Tuple{Symbol}, NamedTuple{(:options,), Tuple{IpoptOptions{NamedTuple{(:hessian_approximation, :jac_c_constant, :jac_d_constant), Tuple{String, String, String}}}}}})
@ NonconvexCore C:\Users\ilyao\.julia\packages\NonconvexCore\b8vFh\src\common.jl:233
[40] __solve(prob::OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, opt::IpoptAlg; cb::Nothing, maxiters::Nothing, maxtime::Nothing, abstol::Nothing, reltol::Nothing, progress::Bool, surrogate_objective::Nothing, integer::Nothing, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ GalacticOptim C:\Users\ilyao\.julia\packages\GalacticOptim\fow0r\src\solve\nonconvex\nonconvex.jl:102
[41] __solve
@ C:\Users\ilyao\.julia\packages\GalacticOptim\fow0r\src\solve\nonconvex\nonconvex.jl:61 [inlined]
[42] #solve#480
@ C:\Users\ilyao\.julia\packages\SciMLBase\GW7GW\src\solve.jl:3 [inlined]
[43] solve(::OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, ::IpoptAlg)
@ SciMLBase C:\Users\ilyao\.julia\packages\SciMLBase\GW7GW\src\solve.jl:3
[44] top-level scope
@ REPL[9]:1
[45] top-level scope
@ C:\Users\ilyao\.julia\packages\Infiltrator\ieyX7\src\Infiltrator.jl:557
Nonconvex had some breaking changes and we need to update a few things.
Nonconvex had some breaking changes and we need to update a few things.
I don't recall any.
Then why were there like 5 breaking releases? 😅 I think it was merged at like 0.2 or something of the sort.
Interesting. It was more recent than I thought.
https://github.com/SciML/GalacticOptim.jl/runs/4966434743?check_suite_focus=true#step:6:53
I wonder why tests fail now then.
Then why were there like 5 breaking releases?
The current latest release of NonconvexIpopt is 0.1.4. I haven't made a single breaking release beside 0.1.0!
It looks like it is because you don't define an AD backend. Using ForwardDiff.jl, the following should work:
using GalacticOptim, Nonconvex
Nonconvex.@load Ipopt
using ForwardDiff
rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
x0 = zeros(2)
p = [1.0, 100.0]
f = OptimizationFunction(rosenbrock, GalacticOptim.AutoForwardDiff())
prob = GalacticOptim.OptimizationProblem(f, x0, p, lb = [-1.0,-1.0], ub = [1.0,1.0])
solve(prob, IpoptAlg())
@Vaibhavdixit02 now with the new subpackage stuff, can you check this?
It won't work out of the box well yet, there are still compat issues with some Nonconvex packages. But in case the aim is to use Ipopt you could just use it with MOI?
The same problem appears through MOI
using Optimization, OptimizationMOI, Ipopt
rosenbrock(u,p) = (p[1] - u[1])^2 + p[2] * (u[2] - u[1]^2)^2
u0 = zeros(2)
p = [1.0,100.0]
prob = OptimizationProblem(rosenbrock,u0,p)
solver = Ipopt.Optimizer()
sol = solve(prob,solver)
julia> sol = solve(prob,solver)
This is Ipopt version 3.14.4, running with linear solver MUMPS 5.4.1.
Number of nonzeros in equality constraint Jacobian...: 0
Number of nonzeros in inequality constraint Jacobian.: 0
Number of nonzeros in Lagrangian Hessian.............: 3
ERROR: MethodError: objects of type Nothing are not callable
Stacktrace:
[1] eval_objective_gradient(moiproblem::OptimizationMOI.MOIOptimizationProblem{Float64, OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}}, G::Vector{Float64}, x::Vector{Float64})
@ OptimizationMOI ~/.julia/packages/OptimizationMOI/OiRiY/src/OptimizationMOI.jl:68
[2] _eval_objective_gradient(model::Ipopt.Optimizer, grad::Vector{Float64}, x::Vector{Float64})
@ Ipopt ~/.julia/packages/Ipopt/rz6uf/src/MOI_wrapper.jl:883
[3] (::Ipopt.var"#eval_grad_f_cb#4"{Ipopt.Optimizer})(x::Vector{Float64}, grad_f::Vector{Float64})
@ Ipopt ~/.julia/packages/Ipopt/rz6uf/src/MOI_wrapper.jl:1116
[4] _Eval_Grad_F_CB(n::Int32, x_ptr::Ptr{Float64}, #unused#::Int32, grad_f::Ptr{Float64}, user_data::Ptr{Nothing})
@ Ipopt ~/.julia/packages/Ipopt/rz6uf/src/C_wrapper.jl:54
[5] IpoptSolve(prob::IpoptProblem)
@ Ipopt ~/.julia/packages/Ipopt/rz6uf/src/C_wrapper.jl:438
[6] optimize!(model::Ipopt.Optimizer)
@ Ipopt ~/.julia/packages/Ipopt/rz6uf/src/MOI_wrapper.jl:1254
[7] __solve(prob::OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Nothing, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, opt::Ipopt.Optimizer; maxiters::Nothing, maxtime::Nothing, abstol::Nothing, reltol::Nothing, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ OptimizationMOI ~/.julia/packages/OptimizationMOI/OiRiY/src/OptimizationMOI.jl:323
[8] __solve
@ ~/.julia/packages/OptimizationMOI/OiRiY/src/OptimizationMOI.jl:262 [inlined]
[9] #solve#516
@ ~/.julia/packages/SciMLBase/ov6DK/src/solve.jl:71 [inlined]
[10] solve(::OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(rosenbrock), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Nothing, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, ::Ipopt.Optimizer)
@ SciMLBase ~/.julia/packages/SciMLBase/ov6DK/src/solve.jl:70
[11] top-level scope
@ REPL[15]:1
but manually defining the AD backend like @jonasmac16 said solves it
optf = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff())
prob = OptimizationProblem(optf,u0,p)
solver = Ipopt.Optimizer()
sol = solve(prob,solver)
So the issue here is basically a gradient based optimizer being used without gradients defined for it, this is an example of #310. I think I didn't read the stacktrace properly when I last commented, sorry about that.
Can we make this throw before hitting the solver?
The MOI wrappers are pretty good now, and there's higher level errors, so closing this.