Optimization.jl icon indicating copy to clipboard operation
Optimization.jl copied to clipboard

Error with Ipopt through Nonconvex

Open IlyaOrson opened this issue 3 years ago • 11 comments

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

IlyaOrson avatar Apr 05 '22 17:04 IlyaOrson

Nonconvex had some breaking changes and we need to update a few things.

ChrisRackauckas avatar Apr 05 '22 21:04 ChrisRackauckas

Nonconvex had some breaking changes and we need to update a few things.

I don't recall any.

mohdibntarek avatar Apr 05 '22 21:04 mohdibntarek

Then why were there like 5 breaking releases? 😅 I think it was merged at like 0.2 or something of the sort.

ChrisRackauckas avatar Apr 05 '22 21:04 ChrisRackauckas

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.

ChrisRackauckas avatar Apr 05 '22 21:04 ChrisRackauckas

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!

mohdibntarek avatar Apr 05 '22 23:04 mohdibntarek

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())

jonasmac16 avatar Apr 25 '22 14:04 jonasmac16

@Vaibhavdixit02 now with the new subpackage stuff, can you check this?

ChrisRackauckas avatar May 02 '22 01:05 ChrisRackauckas

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?

Vaibhavdixit02 avatar May 02 '22 07:05 Vaibhavdixit02

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)

baggepinnen avatar Aug 19 '22 04:08 baggepinnen

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.

Vaibhavdixit02 avatar Aug 19 '22 08:08 Vaibhavdixit02

Can we make this throw before hitting the solver?

ChrisRackauckas avatar Aug 20 '22 03:08 ChrisRackauckas

The MOI wrappers are pretty good now, and there's higher level errors, so closing this.

ChrisRackauckas avatar Dec 12 '22 12:12 ChrisRackauckas