Bug when using DSDP versus SCS optimiser with JuMP

Hi,
How do I resolve the error below generated when I run my code using the DSDP optimiser?

I get the right answer, without errors, when I run my code using the SCS optimiser instead. (This question is a follow-up to this one: How to define matrix objectives in JuMP models. ) Thanks for any help!

Code with DSDP: this gives error

c = [0, 1, 2]
Gs = [
    0 0 -0.5  0 0 1 0    0 -0.5 0 0 0  0    0 0 0;
    0 0    0 -1 0 0 1    0    0 1 0 0 -1    0 0 0;
    0 0    0  0 0 0 0 -0.5    0 0 1 0  0 -0.5 0 0;
]

Hs = [
      10  10 -1.5   0;
      10   0    0 0.5;
    -1.5   0    0   0;
       0 0.5    0 100
]

using JuMP, DSDP
model = Model(with_optimizer(DSDP.Optimizer))
@variable(model, x[1:3])
@variable(model, s[1:4, 1:4], PSD)
@objective(model, Min, c' * x)
@constraint(model, -Gs' * x + vec(s) .== vec(Hs))
optimize!(model)
# objective_value(model)

Error

ERROR: TODO
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] _setcoefficient!(::DSDP.Optimizer, ::Float64, ::Int64, ::Int64, ::Int64, ::Int64) at /Users/tdp/.julia/packages/DSDP/x4iAt/src/MOI_wrapper.jl:308
 [3] load_constraint(::DSDP.Optimizer, ::MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.EqualTo{Float64}}, ::MathOptInterface.ScalarAffineFunction{Float64}, ::MathOptInterface.EqualTo{Float64}) at /Users/tdp/.julia/packages/DSDP/x4iAt/src/MOI_wrapper.jl:335
 [4] load_constraints(::DSDP.Optimizer, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}, ::MathOptInterface.Utilities.IndexMap, ::Array{MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.EqualTo{Float64}},1}) at /Users/tdp/.julia/packages/MathOptInterface/C1XBe/src/Utilities/copy.jl:637
 [5] pass_constraints(::DSDP.Optimizer, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}, ::Bool, ::MathOptInterface.Utilities.IndexMap, ::Array{DataType,1}, ::Array{Array{#s112,1} where #s112<:(MathOptInterface.ConstraintIndex{MathOptInterface.SingleVariable,S} where S),1}, ::Array{DataType,1}, ::Array{Array{#s13,1} where #s13<:(MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables,S} where S),1}, ::typeof(MathOptInterface.Utilities.load_constraints), ::typeof(MathOptInterface.Utilities.load)) at /Users/tdp/.julia/packages/MathOptInterface/C1XBe/src/Utilities/copy.jl:265
 [6] allocate_load(::DSDP.Optimizer, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}, ::Bool) at /Users/tdp/.julia/packages/MathOptInterface/C1XBe/src/Utilities/copy.jl:705
 [7] #automatic_copy_to#109 at /Users/tdp/.julia/packages/MathOptInterface/C1XBe/src/Utilities/copy.jl:17 [inlined]
 [8] #automatic_copy_to at ./none:0 [inlined]
 [9] #copy_to#3 at /Users/tdp/.julia/packages/DSDP/x4iAt/src/MOI_wrapper.jl:201 [inlined]
 [10] #copy_to at ./none:0 [inlined]
 [11] attach_optimizer(::MathOptInterface.Utilities.CachingOptimizer{DSDP.Optimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at /Users/tdp/.julia/packages/MathOptInterface/C1XBe/src/Utilities/cachingoptimizer.jl:149
 [12] optimize!(::MathOptInterface.Utilities.CachingOptimizer{DSDP.Optimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at /Users/tdp/.julia/packages/MathOptInterface/C1XBe/src/Utilities/cachingoptimizer.jl:185
 [13] optimize!(::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{DSDP.Optimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}) at /Users/tdp/.julia/packages/MathOptInterface/C1XBe/src/Bridges/bridge_optimizer.jl:239
 [14] optimize!(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at /Users/tdp/.julia/packages/MathOptInterface/C1XBe/src/Utilities/cachingoptimizer.jl:189
 [15] #optimize!#78(::Bool, ::Bool, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(optimize!), ::Model, ::Nothing) at /Users/tdp/.julia/packages/JuMP/MsUSY/src/optimizer_interface.jl:141
 [16] optimize! at /Users/tdp/.julia/packages/JuMP/MsUSY/src/optimizer_interface.jl:111 [inlined] (repeats 2 times)
 [17] top-level scope at REPL[11]:1

Code with SCS: this works

c = [0, 1, 2]
Gs = [
    0 0 -0.5  0 0 1 0    0 -0.5 0 0 0  0    0 0 0;
    0 0    0 -1 0 0 1    0    0 1 0 0 -1    0 0 0;
    0 0    0  0 0 0 0 -0.5    0 0 1 0  0 -0.5 0 0;
]

Hs = [
      10  10 -1.5   0;
      10   0    0 0.5;
    -1.5   0    0   0;
       0 0.5    0 100
]

using JuMP, SCS
model = Model(with_optimizer(SCS.Optimizer))
@variable(model, x[1:3])
@variable(model, s[1:4, 1:4], PSD)
@objective(model, Min, c' * x)
@constraint(model, -Gs' * x + vec(s) .== vec(Hs))
optimize!(model)
objective_value(model)
# 2.8327599823409098

The “TODO” part of the error suggests that this isn’t a bug per se. It just needs to be implemented:

I’m not sure what it relates to though. Pull requests to add missing features are most welcome.

The DSDP wrapper is still a work in progress. IIRC, using SDP variables in linear constraint is not done yet hence the error you ger. PR welcome! :slight_smile: