Skip to content

dsos_horn #96

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

Closed
blegat opened this issue Oct 13, 2019 · 3 comments
Closed

dsos_horn #96

blegat opened this issue Oct 13, 2019 · 3 comments

Comments

@blegat
Copy link
Contributor

blegat commented Oct 13, 2019

COSMO v0.5.0 is failing the dsos_horn test of SumOfSquares with:

dsos_horn: Error During Test at /home/blegat/.julia/dev/SumOfSquares/test/Tests/utilities.jl:47
  Got exception outside of a @test
  ArgumentError: column indices J[k] must satisfy 1 <= J[k] <= n
  Stacktrace:
   [1] sparse!(::Array{Int64,1}, ::Array{Int64,1}, ::Array{Float64,1}, ::Int64, ::Int64, ::typeof(+), ::Array{Int64,1}, ::Array{Int64,1}, ::Array{Int64,1}, ::Array{Float64,1}, ::Array{Int64,1}, ::Array{Int64,1}, ::Array{Float64,1}) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/SparseArrays/src/sparsematrix.jl:613
   [2] sparse(::Array{Int64,1}, ::Array{Int64,1}, ::Array{Float64,1}, ::Int64, ::Int64, ::Function) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/SparseArrays/src/sparsematrix.jl:525
   [3] sparse at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/SparseArrays/src/sparsematrix.jl:709 [inlined]
   [4] processconstraints(::Optimizer, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}, ::MathOptInterface.Utilities.IndexMap, ::Dict{Int64,UnitRange{Int64}}) at /home/blegat/.julia/packages/COSMO/Paq9I/src/MOIWrapper.jl:344
   [5] #copy_to#97(::Bool, ::typeof(MathOptInterface.copy_to), ::Optimizer, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}) at /home/blegat/.julia/packages/COSMO/Paq9I/src/MOIWrapper.jl:141
   [6] #copy_to at /home/blegat/.julia/dev/MathOptInterface/src/Utilities/cachingoptimizer.jl:0 [inlined]
   [7] attach_optimizer(::MathOptInterface.Utilities.CachingOptimizer{Optimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at /home/blegat/.julia/dev/MathOptInterface/src/Utilities/cachingoptimizer.jl:149
   [8] optimize!(::MathOptInterface.Utilities.CachingOptimizer{Optimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at /home/blegat/.julia/dev/MathOptInterface/src/Utilities/cachingoptimizer.jl:185
   [9] optimize!(::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{Optimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}) at /home/blegat/.julia/dev/MathOptInterface/src/Bridges/bridge_optimizer.jl:225
   [10] optimize!(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at /home/blegat/.julia/dev/MathOptInterface/src/Utilities/cachingoptimizer.jl:189
   [11] #optimize!#78(::Bool, ::Bool, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(optimize!), ::Model, ::Nothing) at /home/blegat/.julia/packages/JuMP/iGamg/src/optimizer_interface.jl:141
   [12] optimize! at /home/blegat/.julia/packages/JuMP/iGamg/src/optimizer_interface.jl:111 [inlined] (repeats 2 times)
   [13] horn_test(::OptimizerFactory, ::MathOptInterface.Test.TestConfig{Float64}, ::SumOfSquares.NonnegPolyInnerCone{SumOfSquares.DiagonallyDominantConeTriangle}) at /home/blegat/.julia/dev/SumOfSquares/test/Tests/horn.jl:40
   [14] dsos_horn_test(::OptimizerFactory, ::MathOptInterface.Test.TestConfig{Float64}) at /home/blegat/.julia/dev/SumOfSquares/test/Tests/horn.jl:67
   [15] macro expansion at /home/blegat/.julia/dev/SumOfSquares/test/Tests/utilities.jl:48 [inlined]
   [16] macro expansion at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/Test/src/Test.jl:1113 [inlined]
   [17] linear_test(::OptimizerFactory, ::MathOptInterface.Test.TestConfig{Float64}, ::Array{String,1}) at /home/blegat/.julia/dev/SumOfSquares/test/Tests/utilities.jl:48
   [18] linear_test(::OptimizerFactory, ::MathOptInterface.Test.TestConfig{Float64}) at /home/blegat/.julia/dev/SumOfSquares/test/Tests/utilities.jl:43
   [19] top-level scope at /home/blegat/.julia/dev/SumOfSquares/test/Solvers/cosmo_tests.jl:6
   [20] top-level scope at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/Test/src/Test.jl:1113
   [21] top-level scope at /home/blegat/.julia/dev/SumOfSquares/test/Solvers/cosmo_tests.jl:6
   [22] include at ./boot.jl:328 [inlined]
   [23] include_relative(::Module, ::String) at ./loading.jl:1094
   [24] include(::Module, ::String) at ./Base.jl:31
   [25] include(::String) at ./client.jl:431
   [26] top-level scope at REPL[42]:1
   [27] eval(::Module, ::Any) at ./boot.jl:330
   [28] eval_user_input(::Any, ::REPL.REPLBackend) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/REPL/src/REPL.jl:86
   [29] macro expansion at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/REPL/src/REPL.jl:118 [inlined]
   [30] (::getfield(REPL, Symbol("##26#27")){REPL.REPLBackend})() at ./task.jl:268

See https://github.com/JuliaOpt/SumOfSquares.jl/blob/master/test/Tests/horn.jl

@migarstka
Copy link
Member

migarstka commented Oct 14, 2019

Thanks Benoît.

This is strange behaviour. It seems to be an issue with delete(model, cref) or the way the COSMO-model is reset before the 2nd problem is solved. If you run the three problems in that script individually you get the expected result (without errors).

Does
Code1

model = _model(factory)
orthant = @set x[1]  0 && x[2]  0 && x[3]  0 && x[4]  0 && x[5]  0
cref = @constraint(model, sum(x) * x' * H * x in cone, domain = orthant)

create exactly the same MOI.model as
Code2

model = _model(factory)
cref = @constraint(model, x' * H * x in CopositiveInner(cone))
delete(model, cref)
orthant = @set x[1]  0 && x[2]  0 && x[3]  0 && x[4]  0 && x[5]  0
cref = @constraint(model, sum(x) * x' * H * x in cone, domain = orthant)

in terms of constraint indices, etc ?

Edit: Both examples yield very different IndexMaps here:
https://github.com/oxfordcontrol/COSMO.jl/blob/39fdf695c9de747141b1b3410c2927a4030ed446/src/MOIWrapper.jl#L158-179

For Code 1 I get idxmap.conmap:

Dict{MathOptInterface.ConstraintIndex,MathOptInterface.ConstraintIndex} with 17 entries:
  ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(4)     => ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(3)
  ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(6)     => ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(5)
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(16) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(14)
  ConstraintIndex{VectorAffineFunction{Float64},Zeros}(19)                => ConstraintIndex{VectorAffineFunction{Float64},Zeros}(17)
  ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(10)    => ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(9)
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(18) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(16)
  ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(7)     => ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(6)
  ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(11)    => ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(10)
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(13) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(11)
  ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(9)     => ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(8)
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(14) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(12)
  ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(5)     => ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(4)
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(15) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(13)
  ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(3)     => ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(2)
  ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(8)     => ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(7)
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(17) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(15)
  ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(2)     => ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}(1)

for Code 2 I get:

Dict{MathOptInterface.ConstraintIndex,MathOptInterface.ConstraintIndex} with 7 entries:
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(5) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(5)
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(6) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(6)
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(3) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(3)
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(4) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(4)
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(1) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(1)
  ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(2) => ConstraintIndex{VectorOfVariables,PositiveSemidefiniteConeTriangle}(2)
  ConstraintIndex{VectorAffineFunction{Float64},Zeros}(7)                => ConstraintIndex{VectorAffineFunction{Float64},Zeros}(7)

@blegat
Copy link
Contributor Author

blegat commented Oct 14, 2019

I think the only difference is that in the second case, the model will be emptied by the CachingOptimizer (instead of having a fresh new one) and the cache that will be copied to COSMO will have different indices (since it will have applied the deletion).

Both examples yield very different IndexMaps.

So the IndexMaps will be different indeed

migarstka added a commit that referenced this issue Nov 18, 2019
- The variable indices that appear as the column numbers in the
constraint matrix `A` have to be mapped through the `idxmap`
before assembling the matrix.
@migarstka
Copy link
Member

Fixed in f90cc62

The problem was that I didn't map the variable indices involved in the constraints through the idxmap. I am surprised that this case isn't covered anywhere in the MOI unit tests. We should probably add an appropriate test for this.

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

2 participants