Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throw a better error when passing a vector as initial solution with a DictModel #128

Open
odow opened this issue Feb 24, 2022 · 5 comments

Comments

@odow
Copy link

odow commented Feb 24, 2022

@ccoffrin and I are interested in evaluating Nonconvex.jl to test out some different solvers and AD systems. However, we're stymied by conversions from JuMP to Nonconvex:

julia> using JuMP

julia> import Nonconvex

julia> Nonconvex.@load Ipopt
[ Info: Attempting to load the package NonconvexIpopt.
[ Info: Loading succesful.

julia> model = JuMP.Model();

julia> @variable(model, x >= 0)
x

julia> ncvx_model = DictModel(model)
DictModel(NonconvexCore.Objective{NonconvexCore.var"#168#171"{Vector{Symbol}, SparseArrays.SparseVector{Float64, Int64}}, Base.RefValue{Float64}, Set{Symbol}}(NonconvexCore.var"#168#171"{Vector{Symbol}, SparseArrays.SparseVector{Float64, Int64}}([:x], 1-element SparseArrays.SparseVector{Float64, Int64} with 0 stored entries), Base.RefValue{Float64}(1.0), Set{Symbol}()), NonconvexCore.VectorOfFunctions{Vector{NonconvexCore.EqConstraint}}(NonconvexCore.EqConstraint[]), NonconvexCore.VectorOfFunctions{Vector{NonconvexCore.IneqConstraint}}(NonconvexCore.IneqConstraint[]), NonconvexCore.VectorOfFunctions{Vector{NonconvexCore.SDConstraint}}(NonconvexCore.SDConstraint[]), OrderedDict{Any, Any}(:x => 0.0), OrderedDict{Any, Any}(:x => Inf), OrderedDict{Any, Any}(:x => 1.0), OrderedDict{Any, Any}(:x => false))

julia> optimize(ncvx_model, IpoptAlg(), [0.0]; options = IpoptOptions())
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.............:        0

ERROR: MethodError: no method matching flatten(::Vector{Float64}, ::Vector{Symbol})
Closest candidates are:
  flatten(::Vector{var"#s46"} where var"#s46"<:Real) at /Users/oscar/.julia/packages/NonconvexCore/YjDSM/src/models/flatten.jl:52
  flatten(::AbstractVector{T} where T) at /Users/oscar/.julia/packages/NonconvexCore/YjDSM/src/models/flatten.jl:54
  flatten(::AbstractArray) at /Users/oscar/.julia/packages/NonconvexCore/YjDSM/src/models/flatten.jl:65
  ...
Stacktrace:
  [1] macro expansion
    @ ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0 [inlined]
  [2] _pullback(::Zygote.Context, ::typeof(NonconvexCore.flatten), ::Vector{Float64}, ::Vector{Symbol})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:9
  [3] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/models/jump.jl:211 [inlined]
  [4] _pullback(ctx::Zygote.Context, f::NonconvexCore.var"#168#171"{Vector{Symbol}, SparseArrays.SparseVector{Float64, Int64}}, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
  [5] _apply(::Function, ::Vararg{Any, N} where N)
    @ Core ./boot.jl:804
  [6] adjoint
    @ ~/.julia/packages/Zygote/cCyLF/src/lib/lib.jl:200 [inlined]
  [7] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
  [8] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/functions/functions.jl:170 [inlined]
  [9] _pullback(::Zygote.Context, ::NonconvexCore.var"##_#8", ::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::NonconvexCore.Objective{NonconvexCore.var"#168#171"{Vector{Symbol}, SparseArrays.SparseVector{Float64, Int64}}, Base.RefValue{Float64}, Set{Symbol}}, ::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
 [10] _apply(::Function, ::Vararg{Any, N} where N)
    @ Core ./boot.jl:804
 [11] adjoint
    @ ~/.julia/packages/Zygote/cCyLF/src/lib/lib.jl:200 [inlined]
 [12] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
 [13] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/functions/functions.jl:170 [inlined]
 [14] _pullback(ctx::Zygote.Context, f::NonconvexCore.Objective{NonconvexCore.var"#168#171"{Vector{Symbol}, SparseArrays.SparseVector{Float64, Int64}}, Base.RefValue{Float64}, Set{Symbol}}, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
 [15] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/models/vec_model.jl:90 [inlined]
 [16] _pullback(ctx::Zygote.Context, f::NonconvexCore.var"#133#140"{DictModel, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
 [17] _apply
    @ ./boot.jl:804 [inlined]
 [18] adjoint
    @ ~/.julia/packages/Zygote/cCyLF/src/lib/lib.jl:200 [inlined]
 [19] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
 [20] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/functions/functions.jl:170 [inlined]
 [21] _pullback(::Zygote.Context, ::NonconvexCore.var"##_#8", ::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::NonconvexCore.Objective{NonconvexCore.var"#133#140"{DictModel, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, Base.RefValue{Float64}, Set{Symbol}}, ::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
 [22] _apply(::Function, ::Vararg{Any, N} where N)
    @ Core ./boot.jl:804
 [23] adjoint
    @ ~/.julia/packages/Zygote/cCyLF/src/lib/lib.jl:200 [inlined]
 [24] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
 [25] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/functions/functions.jl:170 [inlined]
 [26] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/functions/counting_function.jl:9 [inlined]
 [27] _pullback(ctx::Zygote.Context, f::NonconvexCore.CountingFunction{NonconvexCore.Objective{NonconvexCore.var"#133#140"{DictModel, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, Base.RefValue{Float64}, Set{Symbol}}}, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
 [28] _pullback(f::Function, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface.jl:34
 [29] pullback(f::Function, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface.jl:40
 [30] gradient(f::Function, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface.jl:75
 [31] (::NonconvexIpopt.var"#eval_grad_f#13"{NonconvexCore.CountingFunction{NonconvexCore.Objective{NonconvexCore.var"#133#140"{DictModel, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, Base.RefValue{Float64}, Set{Symbol}}}})(x::Vector{Float64}, grad_f::Vector{Float64})
    @ NonconvexIpopt ~/.julia/packages/NonconvexIpopt/4F7iF/src/ipopt.jl:135
 [32] _Eval_Grad_F_CB(n::Int32, x_ptr::Ptr{Float64}, #unused#::Int32, grad_f::Ptr{Float64}, user_data::Ptr{Nothing})
    @ Ipopt ~/.julia/packages/Ipopt/gZvYd/src/C_wrapper.jl:49
 [33] IpoptSolve(prob::Ipopt.IpoptProblem)
    @ Ipopt ~/.julia/packages/Ipopt/gZvYd/src/C_wrapper.jl:431
 [34] 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 ~/.julia/packages/NonconvexIpopt/4F7iF/src/ipopt.jl:52
 [35] #optimize#131
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/models/vec_model.jl:74 [inlined]
 [36] optimize(::DictModel, ::IpoptAlg, ::Vector{Float64}; kwargs::Base.Iterators.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 ~/.julia/packages/NonconvexCore/YjDSM/src/common.jl:233
 [37] top-level scope
    @ REPL[35]:1

(ncvx) pkg> st
      Status `/private/tmp/ncvx/Project.toml`
  [b6b21f68] Ipopt v0.9.1
  [4076af6c] JuMP v0.22.3
  [01bcebdf] Nonconvex v1.0.2
  [bf347577] NonconvexIpopt v0.1.3
  [c36e90e8] PowerModels v0.19.1
@mohamed82008
Copy link
Member

This should work:

using JuMP
import Nonconvex
Nonconvex.@load Ipopt

model = JuMP.Model();
@variable(model, x >= 0)

ncvx_model = DictModel(model)
optimize(ncvx_model, IpoptAlg(), Dict(:x => 0.0); options = IpoptOptions())

Note that the initial solution of a DictModel is a dictionary. You can get the default initial solution by calling init = NonconvexCore.getinit(ncvx_model)

@mohamed82008
Copy link
Member

Closing this issue. Please open more issues if you feel the need to.

@odow
Copy link
Author

odow commented Feb 24, 2022

Ah. I guess I got confused with the Zygote error since it didn't throw a method error passing the initial point as a vector.

@mohamed82008
Copy link
Member

It would be nice to throw a better error here.

@mohamed82008 mohamed82008 reopened this Feb 24, 2022
@mohamed82008 mohamed82008 changed the title Error in pullback for a trivial JuMP model Throw a better error when passing a vector as initial solution with a DictModel Feb 24, 2022
@ccoffrin
Copy link

Also I suggest adding some documentation of the existence of getinit. I did not find it in the documentation that is here, https://julianonconvex.github.io/Nonconvex.jl/stable/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants