AmplNLWriter : supports_constraint() is ambiguous in MathOptInterface

Hi there you beautiful people!

Complete Julia newbie here, so the problem I’m having may be trivial.
I’m trying to use Couenne optimizer with AmplNLWriter interface, but can’t make it work.
Here’s my hello-world level model (that works with Juniper for example).

using JuMP, AmplNLWriter
model = Model(with_optimizer(AmplNLWriter.Optimizer, "/usr/local/bin/couenne"))
@variable(model, 0 <= x <= 2 )
@variable(model, 0 <= y <= 30 )
@objective(model, Max, 5x + 3*y )
@constraint(model, 1x + 5y <= 3.0 )
status = optimize!(model)

I get an error when I try to run it:

ERROR: LoadError: MethodError: supports_constraint(::AmplNLWriter.InnerModel{Float64}, ::Type{MathOptInterface.SingleVariable}, ::Type{MathOptInterface.GreaterThan{Float64}}) is ambiguous. Candidates:
  supports_constraint(model::AmplNLWriter.InnerModel{#76#T}, ::Type{#s21} where #s21<:Union{MathOptInterface.SingleVariable, MathOptInterface.ScalarAffineFunction{#76#T}, MathOptInterface.ScalarQuadraticFunction{#76#T}}, ::Type{#s20} where #s20<:Union{MathOptInterface.Integer, MathOptInterface.ZeroOne, MathOptInterface.EqualTo{#76#T}, MathOptInterface.GreaterThan{#76#T}, MathOptInterface.Interval{#76#T}, MathOptInterface.LessThan{#76#T}}) where #76#T in AmplNLWriter at /home/dmitry/.julia/packages/MathOptInterface/A2UPd/src/Utilities/model.jl:1020
  supports_constraint(::MathOptInterface.Utilities.AbstractModel{T}, ::Type{MathOptInterface.SingleVariable}, ::Type{#s118} where #s118<:Union{MathOptInterface.Integer, MathOptInterface.ZeroOne, MathOptInterface.EqualTo{T}, MathOptInterface.GreaterThan{T}, MathOptInterface.Interval{T}, MathOptInterface.LessThan{T}, MathOptInterface.Semicontinuous{T}, MathOptInterface.Semiinteger{T}}) where T in MathOptInterface.Utilities at /home/dmitry/.julia/packages/MathOptInterface/A2UPd/src/Utilities/model.jl:489
Possible fix, define
  supports_constraint(::AmplNLWriter.InnerModel{T}, ::Type{MathOptInterface.SingleVariable}, ::Type{#s118} where #s118<:Union{MathOptInterface.Integer, MathOptInterface.ZeroOne, MathOptInterface.EqualTo{T}, MathOptInterface.GreaterThan{T}, MathOptInterface.Interval{T}, MathOptInterface.LessThan{T}, MathOptInterface.Semicontinuous{T}, MathOptInterface.Semiinteger{T}})
Stacktrace:
 [1] supports_constraint(::MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}, ::Type{MathOptInterface.SingleVariable}, ::Type{MathOptInterface.GreaterThan{Float64}}) at /home/dmitry/.julia/packages/AmplNLWriter/V1gW5/src/MOI_wrapper.jl:34
 [2] is_bridged(::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}}, ::Type{MathOptInterface.GreaterThan{Float64}}) at /home/dmitry/.julia/packages/MathOptInterface/A2UPd/src/Bridges/lazy_bridge_optimizer.jl:385
 [3] add_constrained_variable(::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}}, ::MathOptInterface.GreaterThan{Float64}) at /home/dmitry/.julia/packages/MathOptInterface/A2UPd/src/Bridges/bridge_optimizer.jl:1160
 [4] copy_single_variable(::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}}, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}, ::MathOptInterface.Utilities.IndexMap, ::Type{MathOptInterface.GreaterThan{Float64}}) at /home/dmitry/.julia/packages/MathOptInterface/A2UPd/src/Utilities/copy.jl:203
 [5] (::getfield(MathOptInterface.Utilities, Symbol("##115#123")){MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}},MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}},MathOptInterface.Utilities.IndexMap})(::Type) at ./none:0
 [6] iterate(::Base.Generator{Array{DataType,1},getfield(MathOptInterface.Utilities, Symbol("##115#123")){MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}},MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}},MathOptInterface.Utilities.IndexMap}}) at ./generator.jl:47
 [7] collect(::Base.Generator{Array{DataType,1},getfield(MathOptInterface.Utilities, Symbol("##115#123")){MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}},MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}},MathOptInterface.Utilities.IndexMap}}) at ./array.jl:606
 [8] default_copy_to(::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}}, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}, ::Bool) at /home/dmitry/.julia/packages/MathOptInterface/A2UPd/src/Utilities/copy.jl:325
 [9] #automatic_copy_to#97(::Bool, ::typeof(MathOptInterface.Utilities.automatic_copy_to), ::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}}, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}) at /home/dmitry/.julia/packages/MathOptInterface/A2UPd/src/Utilities/copy.jl:15
 [10] (::getfield(MathOptInterface.Utilities, Symbol("#kw##automatic_copy_to")))(::NamedTuple{(:copy_names,),Tuple{Bool}}, ::typeof(MathOptInterface.Utilities.automatic_copy_to), ::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}}, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}) at ./none:0
 [11] #copy_to#3(::Base.Iterators.Pairs{Symbol,Bool,Tuple{Symbol},NamedTuple{(:copy_names,),Tuple{Bool}}}, ::typeof(MathOptInterface.copy_to), ::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}}, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}) at /home/dmitry/.julia/packages/MathOptInterface/A2UPd/src/Bridges/bridge_optimizer.jl:254
 [12] (::getfield(MathOptInterface, Symbol("#kw##copy_to")))(::NamedTuple{(:copy_names,),Tuple{Bool}}, ::typeof(MathOptInterface.copy_to), ::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}}, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}) at ./none:0
 [13] attach_optimizer(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at /home/dmitry/.julia/packages/MathOptInterface/A2UPd/src/Utilities/cachingoptimizer.jl:149
 [14] optimize!(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at /home/dmitry/.julia/packages/MathOptInterface/A2UPd/src/Utilities/cachingoptimizer.jl:185
 [15] #optimize!#78(::Bool, ::Bool, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(optimize!), ::Model, ::Nothing) at /home/dmitry/.julia/packages/JuMP/MsUSY/src/optimizer_interface.jl:141
 [16] optimize!(::Model, ::Nothing) at /home/dmitry/.julia/packages/JuMP/MsUSY/src/optimizer_interface.jl:111 (repeats 2 times)
 [17] top-level scope at /home/dmitry/Documents/projects/practice/julia/optimization/src/optimus.jl:39
 [18] include at ./boot.jl:328 [inlined]
 [19] include_relative(::Module, ::String) at ./loading.jl:1094
 [20] include(::Module, ::String) at ./Base.jl:31
 [21] exec_options(::Base.JLOptions) at ./client.jl:295
 [22] _start() at ./client.jl:464
in expression starting at /home/dmitry/Documents/projects/practice/julia/optimization/src/optimus.jl:39

I tried it with Julia v1.2.0 and with v1.3.0-rc5, get same results.
Google has shown me a similar issue that was fixed for Julia v1.3, but I’m not sure how relevant that problem was.

Any help, comments are greatly appreciated. Thanks.

This should be fixed on the master branch thanks to https://github.com/JuliaOpt/AmplNLWriter.jl/pull/91. We should tag a new version.

Thanks a lot!
The error is gone after that fix. Although, Couenne doesn’t produce any result: when I try to printout results of the optimization

println(JuMP.termination_status(model))
println("Objective value: ", JuMP.objective_value(model))
println("x = ", JuMP.value(x))
println("y = ", JuMP.value(y))

I get this

OTHER_ERROR
Objective value: NaN
x = NaN
y = NaN

Even though Juniper gives normal result and Couenne does too if I run it with AMPL or as a standalone solver. Any ideas where I go from here?

What’s the result of AmplNLWriter.mpb_solution_attribute(model)?

gives an error

ERROR: LoadError: MethodError: no method matching mpb_solution_attribute(::Model)
Closest candidates are:
  mpb_solution_attribute(!Matched::MathOptInterface.Utilities.UniversalFallback{AmplNLWriter.InnerModel{Float64}}) at /home/dmitry/.julia/packages/AmplNLWriter/V1gW5/src/MOI_wrapper.jl:396
Stacktrace:
 [1] top-level scope at /home/dmitry/Documents/projects/practice/julia/optimization/src/optimus.jl:34
 [2] include at ./boot.jl:328 [inlined]
 [3] include_relative(::Module, ::String) at ./loading.jl:1094
 [4] include(::Module, ::String) at ./Base.jl:31
 [5] exec_options(::Base.JLOptions) at ./client.jl:295
 [6] _start() at ./client.jl:464
in expression starting at /home/dmitry/Documents/projects/practice/julia/optimization/src/optimus.jl:34

I guess I meant

AmplNLWriter.mpb_solution_attribute(backend(model).optimizer.model)
AmplNLWriter.mpb_solution_attribute(backend(model).optimizer.model)

gives no output.
If I print out that, like

println(AmplNLWriter.mpb_solution_attribute(backend(model).optimizer.model))

I get

AmplNLWriter.MPBSolution(:Error, NaN, Dict(MathOptInterface.VariableIndex(2) => NaN,MathOptInterface.VariableIndex(1) => NaN))

The solver errored for some reason. Can you post a log of the solve? Do you have write permission to ~/.julia?

I do have the permission.
How do I get the solve (solver?) log?

Couenne writes its output to a .sol file if executed as standalone solver. Is there a way to access its output / log when it’s used as a solver in JuMP?