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

Starting value in unsupported bridge errors instead of skipping #2327

Closed
odow opened this issue Oct 28, 2023 · 4 comments · Fixed by #2330
Closed

Starting value in unsupported bridge errors instead of skipping #2327

odow opened this issue Oct 28, 2023 · 4 comments · Fixed by #2330
Assignees

Comments

@odow
Copy link
Member

odow commented Oct 28, 2023

x-ref https://discourse.julialang.org/t/wram-start-of-hermitianpsdcone-in-jump/105491

julia> using JuMP, LinearAlgebra, COSMO, SCS

julia> ρs = map(LinearAlgebra.Hermitian, [[1 0; 0 0], [1 1; 1 1]/2])
2-element Vector{Hermitian{Float64, Matrix{Float64}}}:
 [1.0 0.0; 0.0 0.0]
 [0.5 0.5; 0.5 0.5]

julia> E0 = [0.5 0.0; 0.0 0.5]
2×2 Matrix{Float64}:
 0.5  0.0
 0.0  0.5

julia> model = Model(COSMO.Optimizer)
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: COSMO

julia> @variable(model, E1[i=1:2, j=1:2] in HermitianPSDCone(), start = E0[i,j])
2×2 Hermitian{GenericAffExpr{ComplexF64, VariableRef}, Matrix{GenericAffExpr{ComplexF64, VariableRef}}}:
 real(E1[1,1])                     real(E1[1,2]) + imag(E1[1,2]) im
 real(E1[1,2]) - imag(E1[1,2]) im  real(E1[2,2])

julia> @variable(model, E2[i=1:2, j=1:2] in HermitianPSDCone(), start = E0[i,j])
2×2 Hermitian{GenericAffExpr{ComplexF64, VariableRef}, Matrix{GenericAffExpr{ComplexF64, VariableRef}}}:
 real(E2[1,1])                     real(E2[1,2]) + imag(E2[1,2]) im
 real(E2[1,2]) - imag(E2[1,2]) im  real(E2[2,2])

julia> @constraint(model, E1 + E2 == LinearAlgebra.I(2))
[real(E1[1,1]) + real(E2[1,1]) - 1                                    real(E1[1,2]) + real(E2[1,2]) + imag(E1[1,2]) im + imag(E2[1,2]) im;
 real(E1[1,2]) + real(E2[1,2]) - imag(E1[1,2]) im - imag(E2[1,2]) im  real(E1[2,2]) + real(E2[2,2]) - 1]  Zeros()

julia> @objective(model, Max, real(LinearAlgebra.dot(ρs, [E1, E2])) / 2)
0.5 real(E1[1,1]) + 0.25 real(E2[1,1]) + 0.5 real(E2[1,2]) + 0.25 real(E2[2,2])

julia> optimize!(model)
ERROR: MathOptInterface.UnsupportedAttribute{MathOptInterface.VariablePrimalStart}: Attribute MathOptInterface.VariablePrimalStart() is not supported by the model.
Stacktrace:
  [1] set(model::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{COSMO.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, attr::MathOptInterface.VariablePrimalStart, bridge::MathOptInterface.Bridges.Variable.HermitianToSymmetricPSDBridge{Float64}, value::Float64, #unused#::MathOptInterface.Bridges.IndexInVector)
    @ MathOptInterface.Bridges.Variable ~/.julia/packages/MathOptInterface/am39L/src/Bridges/Variable/bridge.jl:157
  [2] (::MathOptInterface.Bridges.var"#3#4"{typeof(MathOptInterface.set), MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{COSMO.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, MathOptInterface.VariablePrimalStart, Tuple{Float64, MathOptInterface.Bridges.IndexInVector}})(bridge::MathOptInterface.Bridges.Variable.HermitianToSymmetricPSDBridge{Float64})
    @ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/am39L/src/Bridges/bridge_optimizer.jl:335
  [3] (::MathOptInterface.Bridges.Variable.var"#23#24"{MathOptInterface.Bridges.Variable.Map, MathOptInterface.Bridges.var"#3#4"{typeof(MathOptInterface.set), MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{COSMO.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, MathOptInterface.VariablePrimalStart, Tuple{Float64, MathOptInterface.Bridges.IndexInVector}}, Int64})()
    @ MathOptInterface.Bridges.Variable ~/.julia/packages/MathOptInterface/am39L/src/Bridges/Variable/map.jl:494
  [4] call_in_context(map::MathOptInterface.Bridges.Variable.Map, bridge_index::Int64, f::MathOptInterface.Bridges.Variable.var"#23#24"{MathOptInterface.Bridges.Variable.Map, MathOptInterface.Bridges.var"#3#4"{typeof(MathOptInterface.set), MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{COSMO.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, MathOptInterface.VariablePrimalStart, Tuple{Float64, MathOptInterface.Bridges.IndexInVector}}, Int64})
    @ MathOptInterface.Bridges.Variable ~/.julia/packages/MathOptInterface/am39L/src/Bridges/Variable/map.jl:479
  [5] call_in_context
    @ ~/.julia/packages/MathOptInterface/am39L/src/Bridges/Variable/map.jl:494 [inlined]
  [6] call_in_context
    @ ~/.julia/packages/MathOptInterface/am39L/src/Bridges/bridge_optimizer.jl:296 [inlined]
  [7] call_in_context(::typeof(MathOptInterface.set), ::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{COSMO.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, ::MathOptInterface.VariableIndex, ::MathOptInterface.VariablePrimalStart, ::Float64, ::MathOptInterface.Bridges.IndexInVector)
    @ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/am39L/src/Bridges/bridge_optimizer.jl:332
  [8] set(b::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{COSMO.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, attr::MathOptInterface.VariablePrimalStart, index::MathOptInterface.VariableIndex, value::Float64)
    @ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/am39L/src/Bridges/bridge_optimizer.jl:1265
  [9] _pass_attribute(dest::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{COSMO.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, src::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}, index_map::MathOptInterface.Utilities.IndexMap, vis_src::Vector{MathOptInterface.VariableIndex}, attr::MathOptInterface.VariablePrimalStart)
    @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/am39L/src/Utilities/copy.jl:96
 [10] pass_attributes(dest::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{COSMO.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, src::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}, index_map::MathOptInterface.Utilities.IndexMap, vis_src::Vector{MathOptInterface.VariableIndex})
    @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/am39L/src/Utilities/copy.jl:81
 [11] default_copy_to(dest::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{COSMO.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, src::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}})
    @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/am39L/src/Utilities/copy.jl:503
 [12] copy_to
    @ ~/.julia/packages/MathOptInterface/am39L/src/Bridges/bridge_optimizer.jl:453 [inlined]
 [13] optimize!
    @ ~/.julia/packages/MathOptInterface/am39L/src/MathOptInterface.jl:84 [inlined]
 [14] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{COSMO.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
    @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/am39L/src/Utilities/cachingoptimizer.jl:316
 [15] optimize!(model::Model; ignore_optimize_hook::Bool, _differentiation_backend::MathOptInterface.Nonlinear.SparseReverseMode, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ JuMP ~/.julia/packages/JuMP/D44Aq/src/optimizer_interface.jl:448
 [16] optimize!(model::Model)
    @ JuMP ~/.julia/packages/JuMP/D44Aq/src/optimizer_interface.jl:409
 [17] top-level scope
    @ REPL[25]:1

julia> set_optimizer(model, SCS.Optimizer)

julia> optimize!(model)
------------------------------------------------------------------
	       SCS v3.2.3 - Splitting Conic Solver
	(c) Brendan O'Donoghue, Stanford University, 2012
------------------------------------------------------------------
problem:  variables n: 8, constraints m: 24
cones: 	  z: primal zero / dual free vars: 4
	  s: psd vars: 20, ssize: 2
settings: eps_abs: 1.0e-04, eps_rel: 1.0e-04, eps_infeas: 1.0e-07
	  alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
	  max_iters: 100000, normalize: 1, rho_x: 1.00e-06
	  acceleration_lookback: 10, acceleration_interval: 10
lin-sys:  sparse-direct-amd-qdldl
	  nnz(A): 24, nnz(P): 0
------------------------------------------------------------------
 iter | pri res | dua res |   gap   |   obj   |  scale  | time (s)
------------------------------------------------------------------
     0| 1.22e+00  3.85e-01  1.19e+00 -1.21e+00  1.00e-01  1.17e-04 
    50| 2.12e-06  4.80e-07  6.38e-07 -8.54e-01  1.00e-01  2.47e-04 
------------------------------------------------------------------
status:  solved
timings: total: 2.50e-04s = setup: 8.56e-05s + solve: 1.64e-04s
	 lin-sys: 2.02e-05s, cones: 1.03e-04s, accel: 2.92e-06s
------------------------------------------------------------------
objective = -0.853552
------------------------------------------------------------------
@blegat
Copy link
Member

blegat commented Oct 29, 2023

Related to #684 and #2117 (but this one can be done variable by variable)

Starting value in unsupported bridge errors instead of skipping

This might be due to #1993

@odow
Copy link
Member Author

odow commented Oct 30, 2023

Re-opening because I'd like to understand the root cause, not just fix the one bridge.

@odow
Copy link
Member Author

odow commented Oct 31, 2023

So this is because supports is a "I can for at least some, even if I can't for some right now." So I think we can fix this in MOI.

@odow
Copy link
Member Author

odow commented Oct 31, 2023

Closing as intentional for now (see #2333). We can revisit this later if there are complaints.

@odow odow closed this as completed Oct 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment