jump-dev / MosekTools.jl

A MathOptInterface.jl interface to the MOSEK solver
https://github.com/MOSEK/Mosek.jl
MIT License
29 stars 8 forks source link

Calling solve twice causes BoundsError #57

Open MFairley opened 3 years ago

MFairley commented 3 years ago

Here's a MWE

using Convex
using Mosek
using MosekTools
using SCS
W = [1, 0]
x = Variable()
y = Variable()
coeff = x * [1, 0] + y
obj = dot(W, coeff) - logisticloss(coeff)
problem = maximize(obj)

solve!(problem, () -> Mosek.Optimizer(QUIET=true), verbose=false, warmstart = true)
solve!(problem, () -> Mosek.Optimizer(QUIET=true), verbose=false, warmstart = true) # fails

# solve!(problem, () -> SCS.Optimizer(), verbose=false, warmstart = true) 
# solve!(problem, () -> SCS.Optimizer(), verbose=false, warmstart = true) # does not fail
ERROR: LoadError: BoundsError: attempt to access 0-element Array{Float64,1} at index [7]
Stacktrace:
 [1] getindex at ./array.jl:809 [inlined]
 [2] get at /Users/mfairley/.julia/packages/MosekTools/sppJY/src/attributes.jl:425 [inlined]
 [3] get(::MathOptInterface.Utilities.CachingOptimizer{MosekModel,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, ::MathOptInterface.ConstraintDual, ::MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.GreaterThan{Float64}}) at /Users/mfairley/.julia/packages/MathOptInterface/k7UUH/src/Utilities/cachingoptimizer.jl:605
 [4] get(::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MosekModel,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, ::MathOptInterface.ConstraintDual, ::MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.GreaterThan{Float64}}) at /Users/mfairley/.julia/packages/MathOptInterface/k7UUH/src/Bridges/bridge_optimizer.jl:922
 [5] _broadcast_getindex_evalf at ./broadcast.jl:648 [inlined]
 [6] _broadcast_getindex at ./broadcast.jl:621 [inlined]
 [7] getindex at ./broadcast.jl:575 [inlined]
 [8] copy at ./broadcast.jl:876 [inlined]
 [9] materialize at ./broadcast.jl:837 [inlined]
 [10] get(::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MosekModel,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, ::MathOptInterface.ConstraintDual, ::MathOptInterface.Bridges.Constraint.ScalarizeBridge{Float64,MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.GreaterThan{Float64}}) at /Users/mfairley/.julia/packages/MathOptInterface/k7UUH/src/Bridges/Constraint/scalarize.jl:104
 [11] (::MathOptInterface.Bridges.var"#54#55"{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MosekModel,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}},MathOptInterface.ConstraintDual})(::MathOptInterface.Bridges.Constraint.ScalarizeBridge{Float64,MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.GreaterThan{Float64}}) at /Users/mfairley/.julia/packages/MathOptInterface/k7UUH/src/Bridges/bridge_optimizer.jl:920
 [12] (::MathOptInterface.Bridges.var"#1#2"{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MosekModel,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}},MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64},MathOptInterface.Nonnegatives},MathOptInterface.Bridges.var"#54#55"{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MosekModel,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}},MathOptInterface.ConstraintDual}})() at /Users/mfairley/.julia/packages/MathOptInterface/k7UUH/src/Bridges/bridge_optimizer.jl:242
 [13] call_in_context(::MathOptInterface.Bridges.Variable.Map, ::Int64, ::MathOptInterface.Bridges.var"#1#2"{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MosekModel,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}},MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64},MathOptInterface.Nonnegatives},MathOptInterface.Bridges.var"#54#55"{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MosekModel,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}},MathOptInterface.ConstraintDual}}) at /Users/mfairley/.julia/packages/MathOptInterface/k7UUH/src/Bridges/Variable/map.jl:404
 [14] call_in_context at /Users/mfairley/.julia/packages/MathOptInterface/k7UUH/src/Bridges/Variable/map.jl:435 [inlined]
 [15] call_in_context at /Users/mfairley/.julia/packages/MathOptInterface/k7UUH/src/Bridges/bridge_optimizer.jl:241 [inlined]
 [16] get(::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MosekModel,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, ::MathOptInterface.ConstraintDual, ::MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64},MathOptInterface.Nonnegatives}) at /Users/mfairley/.julia/packages/MathOptInterface/k7UUH/src/Bridges/bridge_optimizer.jl:920
 [17] moi_populate_solution!(::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MosekModel,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, ::Problem{Float64}, ::OrderedCollections.OrderedDict{UInt64,Convex.AbstractVariable}, ::Dict{Convex.ConicConstr,Constraint}, ::Array{Convex.ConicConstr,1}, ::Dict{UInt64,Array{MathOptInterface.VariableIndex,1}}, ::Array{MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64},S} where S,1}) at /Users/mfairley/.julia/packages/Convex/aYxJA/src/solution.jl:303
 [18] solve!(::Problem{Float64}, ::MosekModel; check_vexity::Bool, verbose::Bool, warmstart::Bool, silent_solver::Bool) at /Users/mfairley/.julia/packages/Convex/aYxJA/src/solution.jl:249
 [19] solve!(::Problem{Float64}, ::var"#17#18"; kwargs::Base.Iterators.Pairs{Symbol,Bool,Tuple{Symbol,Symbol},NamedTuple{(:verbose, :warmstart),Tuple{Bool,Bool}}}) at /Users/mfairley/.julia/packages/Convex/aYxJA/src/solution.jl:192
 [20] top-level scope at /Users/mfairley/Projects/AdaptiveSurveillance/test/cvx_mwe_bug2.jl:16
 [21] include(::String) at ./client.jl:457
 [22] top-level scope at REPL[2]:1
in expression starting at /Users/mfairley/Projects/AdaptiveSurveillance/test/cvx_mwe_bug2.jl:16
blegat commented 3 years ago

Can you reduce it to an example using the MOI wrapper directly without Convex ? Otherwise, it may be an issue with Convex. Trying a simple example work:

julia> using MosekTools

julia> model = Mosek.Optimizer()
MosekModel

julia> const MOI = MosekTools.MOI
MathOptInterface

julia> x = MOI.SingleVariable(MOI.add_variable(model))
MathOptInterface.SingleVariable(MathOptInterface.VariableIndex(1))

julia> y = MOI.SingleVariable(MOI.add_variable(model))
MathOptInterface.SingleVariable(MathOptInterface.VariableIndex(2))

julia> cx = MOI.add_constraint(model, x, MOI.GreaterThan(0.0))
MathOptInterface.ConstraintIndex{MathOptInterface.SingleVariable,MathOptInterface.GreaterThan{Float64}}(1)

julia> cy = MOI.add_constraint(model, y, MOI.GreaterThan(0.0))
MathOptInterface.ConstraintIndex{MathOptInterface.SingleVariable,MathOptInterface.GreaterThan{Float64}}(2)

julia> c = MOI.add_constraint(model, 1.0x + 1.0y, MOI.LessThan(1.0))
MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.LessThan{Float64}}(1)

julia> MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)

julia> MOI.set(model, MOI.ObjectiveFunction{typeof(1.0x)}(), 1.0x)

julia> MOI.optimize!(model)
Problem
  Name                   :                 
  Objective sense        : min             
  Type                   : LO (linear optimization problem)
  Constraints            : 1               
  Cones                  : 0               
  Scalar variables       : 2               
  Matrix variables       : 0               
  Integer variables      : 0               

Optimizer started.
Presolve started.
Linear dependency checker started.
Linear dependency checker terminated.
Eliminator started.
Freed constraints in eliminator : 0
Eliminator terminated.
Eliminator started.
Freed constraints in eliminator : 0
Eliminator terminated.
Eliminator - tries                  : 2                 time                   : 0.00            
Lin. dep.  - tries                  : 1                 time                   : 0.00            
Lin. dep.  - number                 : 0               
Presolve terminated. Time: 0.00    
Optimizer terminated. Time: 0.00    

2-element Array{MosekTools.MosekSolution,1}:
 MosekTools.MosekSolution(Mosek.MSK_SOL_BAS, Mosek.MSK_SOL_STA_OPTIMAL, Mosek.MSK_PRO_STA_PRIM_AND_DUAL_FEAS, Mosek.Stakey[Mosek.MSK_SK_LOW, Mosek.MSK_SK_LOW], [0.0, 0.0], Array{Float64,1}[], [1.0, 0.0], [0.0, 0.0], Float64[], Mosek.Stakey[Mosek.MSK_SK_BAS], [0.0], [0.0], [0.0], [-0.0])
 MosekTools.MosekSolution(Mosek.MSK_SOL_ITR, Mosek.MSK_SOL_STA_OPTIMAL, Mosek.MSK_PRO_STA_PRIM_AND_DUAL_FEAS, Mosek.Stakey[Mosek.MSK_SK_LOW, Mosek.MSK_SK_LOW], [0.0, 0.0], Array{Float64,1}[], [1.0, 0.0], [0.0, 0.0], [0.0, 0.0], Mosek.Stakey[Mosek.MSK_SK_SUPBAS], [0.0], [0.0], [0.0], [-0.0])

julia> MOI.optimize!(model)
Problem
  Name                   :                 
  Objective sense        : min             
  Type                   : LO (linear optimization problem)
  Constraints            : 1               
  Cones                  : 0               
  Scalar variables       : 2               
  Matrix variables       : 0               
  Integer variables      : 0               

Optimizer started.
Optimizer terminated. Time: 0.00    

2-element Array{MosekTools.MosekSolution,1}:
 MosekTools.MosekSolution(Mosek.MSK_SOL_BAS, Mosek.MSK_SOL_STA_OPTIMAL, Mosek.MSK_PRO_STA_PRIM_AND_DUAL_FEAS, Mosek.Stakey[Mosek.MSK_SK_LOW, Mosek.MSK_SK_LOW], [0.0, 0.0], Array{Float64,1}[], [1.0, 0.0], [0.0, 0.0], Float64[], Mosek.Stakey[Mosek.MSK_SK_BAS], [0.0], [0.0], [0.0], [-0.0])
 MosekTools.MosekSolution(Mosek.MSK_SOL_ITR, Mosek.MSK_SOL_STA_OPTIMAL, Mosek.MSK_PRO_STA_PRIM_AND_DUAL_FEAS, Mosek.Stakey[Mosek.MSK_SK_LOW, Mosek.MSK_SK_LOW], [0.0, 0.0], Array{Float64,1}[], [1.0, 0.0], [0.0, 0.0], [0.0, 0.0], Mosek.Stakey[Mosek.MSK_SK_SUPBAS], [0.0], [0.0], [0.0], [-0.0])

julia> MOI.get(model, MOI.ConstraintDual(), cx)
1.0

julia> MOI.get(model, MOI.ConstraintDual(), cy)
0.0

julia> MOI.get(model, MOI.ConstraintDual(), c)
-0.0
blegat commented 3 years ago

Any update ?