jump-dev / ECOS.jl

A Julia interface to the ECOS conic optimization solver
https://github.com/embotech/ecos
Other
41 stars 17 forks source link

Segfault when there are zero variables and conic constraints #132

Closed chriscoey closed 2 years ago

chriscoey commented 2 years ago

occurs here: https://github.com/chriscoey/MOIPajarito.jl/blob/db762ebefb30719c30279a3ff6642ecf00bec3f6/src/optimize.jl#L392 you can run the MOIPajarito tests on that commit and it will quickly trigger the issue. it's reproducible locally and on github actions (https://github.com/chriscoey/MOIPajarito.jl/runs/4476038254?check_suite_focus=true#step:6:173) locally I see:

signal (11): Segmentation fault: 11
in expression starting at /Users/coey/.julia/dev/MOIPajarito/test/runtests.jl:38
julia(23641,0x10c62c600) malloc: Heap corruption detected, free list is damaged at 0x600003686af0
*** Incorrect guard value: 2240330
objc[23641]: Hash table corrupted. This is probably a memory error somewhere. (table at 0x7ff850d34898, buckets at 0x60000277f1e0 (32 bytes), 4 buckets, 1 entries, 0 tombstones, data 0x42028 0x42029 0x4202a 0x4202b)
julia(23641,0x10c62c600) malloc: *** set a breakpoint in malloc_error_break to debug
zsh: abort      ~/julia/julia
odow commented 2 years ago

What if you use a different solver? Can you get a minimal reproducible example? Are the constraints all VectorAffineFunction?

ECOS doesn't support these modifications natively, so this is likely a problem in MOI.

chriscoey commented 2 years ago

Hypatia does not fail - it still passes all the JuMP tests in MOIPajarito after the new conic model modification stuff. not sure how to get an MWE at this level. All constraints in the conic subproblem model are VAF. there is at most one VAF in Zeros, and then a number of VAF in cone constraints.

chriscoey commented 2 years ago

it's not just "_soc2" that ECOS segfaults on, but also "_soc3" and possibly others

odow commented 2 years ago

I can't reproduce the segfault on the latest MOIPajarito commit. Did you fix it?

julia> using JuMP, GLPK, ECOS, MOIPajarito, Test
[ Info: Precompiling MOIPajarito [bb71f62f-4cf1-45c2-9beb-f0885cb3eba8]

julia> oa_solver = MOI.OptimizerWithAttributes(
           GLPK.Optimizer,
           MOI.Silent() => true,
           "tol_int" => 1e-9,
           "tol_bnd" => 1e-9,
           "mip_gap" => 1e-9,
       )
MathOptInterface.OptimizerWithAttributes(GLPK.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.Silent() => true, MathOptInterface.RawOptimizerAttribute("tol_int") => 1.0e-9, MathOptInterface.RawOptimizerAttribute("tol_bnd") => 1.0e-9, MathOptInterface.RawOptimizerAttribute("mip_gap") => 1.0e-9])

julia> conic_solver = MOI.OptimizerWithAttributes(ECOS.Optimizer, MOI.Silent() => true)
MathOptInterface.OptimizerWithAttributes(ECOS.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.Silent() => true])

julia> opt = JuMP.optimizer_with_attributes(
               MOIPajarito.Optimizer,
               "verbose" => false,
               "use_iterative_method" => false,
               "oa_solver" => oa_solver,
               "conic_solver" => conic_solver,
               "iteration_limit" => 100,
               # "time_limit" => 5,
           )
MathOptInterface.OptimizerWithAttributes(MOIPajarito.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.RawOptimizerAttribute("verbose") => false, MathOptInterface.RawOptimizerAttribute("use_iterative_method") => false, MathOptInterface.RawOptimizerAttribute("oa_solver") => MathOptInterface.OptimizerWithAttributes(GLPK.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.Silent() => true, MathOptInterface.RawOptimizerAttribute("tol_int") => 1.0e-9, MathOptInterface.RawOptimizerAttribute("tol_bnd") => 1.0e-9, MathOptInterface.RawOptimizerAttribute("mip_gap") => 1.0e-9]), MathOptInterface.RawOptimizerAttribute("conic_solver") => MathOptInterface.OptimizerWithAttributes(ECOS.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.Silent() => true]), MathOptInterface.RawOptimizerAttribute("iteration_limit") => 100])

julia> TOL = 1e-4
0.0001

julia> m = JuMP.Model(opt)
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: Pajarito

julia> JuMP.@variable(m, x)
x

julia> JuMP.@variable(m, y)
y

julia> JuMP.@variable(m, z, Int)
z

julia> JuMP.@constraint(m, z <= 2.5)
z ≤ 2.5

julia> JuMP.@objective(m, Min, x + 2y)
x + 2 y

julia> JuMP.@constraint(m, [z, x, y] in JuMP.SecondOrderCone())
[z, x, y] ∈ MathOptInterface.SecondOrderCone(3)

julia> JuMP.set_integer(x)

julia> JuMP.optimize!(m)

julia> @test JuMP.termination_status(m) == MOI.OPTIMAL
Test Passed

julia> @test JuMP.primal_status(m) == MOI.FEASIBLE_POINT
Test Passed

julia> opt_obj = -1 - 2 * sqrt(3)
-4.464101615137754

julia> @test isapprox(JuMP.objective_value(m), opt_obj, atol = TOL)
Test Passed

julia> @test isapprox(JuMP.objective_bound(m), opt_obj, atol = TOL)
Test Passed

julia> @test isapprox(JuMP.value(x), -1, atol = TOL)
Test Passed

julia> @test isapprox(JuMP.value(y), -sqrt(3), atol = TOL)
Test Passed

julia> @test isapprox(JuMP.value(z), 2, atol = TOL)
Test Passed

julia> # TODO see https://github.com/jump-dev/MathOptInterface.jl/issues/1698
       JuMP.unset_integer(x)

julia> JuMP.optimize!(m)

julia> @test JuMP.termination_status(m) == MOI.OPTIMAL
Test Passed

julia> @test JuMP.primal_status(m) == MOI.FEASIBLE_POINT
Test Passed

julia> opt_obj = -2 * sqrt(5)
-4.47213595499958

julia> @test isapprox(JuMP.objective_value(m), opt_obj, atol = TOL)
Test Passed

julia> @test isapprox(JuMP.objective_bound(m), opt_obj, atol = TOL)
Test Passed

julia> @test isapprox(abs2(JuMP.value(x)) + abs2(JuMP.value(y)), 4, atol = TOL)
Test Passed

julia> @test isapprox(JuMP.value(z), 2, atol = TOL)
Test Passed
chriscoey commented 2 years ago

Locally ECOS still segfaults for me. See https://github.com/chriscoey/MOIPajarito.jl/actions/runs/1560878847 to see if it does on CI

odow commented 2 years ago

Okay, this is more helpful. I think I know the problem.

_soc1: Error During Test at /Users/oscar/.julia/dev/MOIPajarito/test/JuMP_tests.jl:34
  Got exception outside of a @test
  ECOS failed to construct problem.
  Stacktrace:
    [1] error(s::String)
      @ Base ./error.jl:33
    [2] _optimize!(dest::ECOS.Optimizer, src::MathOptInterface.Utilities.GenericModel{Float64, MathOptInterface.Utilities.ObjectiveContainer{Float64}, MathOptInterface.Utilities.VariablesContainer{Float64}, ECOS.ZerosOrNot{Float64, MathOptInterface.Utilities.MatrixOfConstraints{Float64, MathOptInterface.Utilities.MutableSparseMatrixCSC{Float64, Int64, MathOptInterface.Utilities.ZeroBasedIndexing}, Vector{Float64}, ECOS.Zeros{Float64}}, MathOptInterface.Utilities.MatrixOfConstraints{Float64, MathOptInterface.Utilities.MutableSparseMatrixCSC{Float64, Int64, MathOptInterface.Utilities.ZeroBasedIndexing}, Vector{Float64}, ECOS.Cones{Float64}}}})
      @ ECOS ~/.julia/packages/ECOS/oopWV/src/MOI_wrapper/MOI_wrapper.jl:250
    [3] optimize!
      @ ~/.julia/packages/ECOS/oopWV/src/MOI_wrapper/MOI_wrapper.jl:299 [inlined]
    [4] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{ECOS.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
      @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/eoIu0/src/Utilities/cachingoptimizer.jl:285
    [5] optimize! (repeats 2 times)
      @ ~/.julia/packages/MathOptInterface/eoIu0/src/Bridges/bridge_optimizer.jl:348 [inlined]
    [6] optimize!
      @ ~/.julia/packages/MathOptInterface/eoIu0/src/MathOptInterface.jl:81 [inlined]
    [7] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{ECOS.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
      @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/eoIu0/src/Utilities/cachingoptimizer.jl:285
    [8] optimize!(model::JuMP.Model, optimizer_factory::Nothing; bridge_constraints::Bool, ignore_optimize_hook::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
      @ JuMP ~/.julia/packages/JuMP/2IF9U/src/optimizer_interface.jl:195
    [9] optimize! (repeats 2 times)
      @ ~/.julia/packages/JuMP/2IF9U/src/optimizer_interface.jl:167 [inlined]
   [10] solve_subproblem(opt::MOIPajarito.Optimizer)
      @ MOIPajarito ~/.julia/dev/MOIPajarito/src/optimize.jl:385
   [11] run_iterative_method(opt::MOIPajarito.Optimizer)
      @ MOIPajarito ~/.julia/dev/MOIPajarito/src/optimize.jl:178
   [12] optimize(opt::MOIPajarito.Optimizer)
      @ MOIPajarito ~/.julia/dev/MOIPajarito/src/optimize.jl:142
   [13] optimize!
      @ ~/.julia/dev/MOIPajarito/src/MOI_wrapper.jl:212 [inlined]
   [14] optimize!
      @ ~/.julia/packages/MathOptInterface/eoIu0/src/MathOptInterface.jl:81 [inlined]
   [15] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MOIPajarito.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
      @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/eoIu0/src/Utilities/cachingoptimizer.jl:285
   [16] optimize!
      @ ~/.julia/packages/MathOptInterface/eoIu0/src/Bridges/bridge_optimizer.jl:348 [inlined]
   [17] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MOIPajarito.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
      @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/eoIu0/src/Utilities/cachingoptimizer.jl:294
   [18] optimize!(model::JuMP.Model, optimizer_factory::Nothing; bridge_constraints::Bool, ignore_optimize_hook::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
      @ JuMP ~/.julia/packages/JuMP/2IF9U/src/optimizer_interface.jl:195
   [19] optimize! (repeats 2 times)
      @ ~/.julia/packages/JuMP/2IF9U/src/optimizer_interface.jl:167 [inlined]
   [20] _soc1(opt::MathOptInterface.OptimizerWithAttributes)
      @ Main.TestJuMP ~/.julia/dev/MOIPajarito/test/JuMP_tests.jl:67
   [21] macro expansion
      @ ~/.julia/dev/MOIPajarito/test/JuMP_tests.jl:35 [inlined]
   [22] macro expansion
      @ /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1226 [inlined]
   [23] run_jump_tests(use_iter::Bool, oa_solver::MathOptInterface.OptimizerWithAttributes, conic_solver::MathOptInterface.OptimizerWithAttributes)
      @ Main.TestJuMP ~/.julia/dev/MOIPajarito/test/JuMP_tests.jl:34
   [24] macro expansion
      @ ~/.julia/dev/MOIPajarito/test/JuMP_tests.jl:15 [inlined]
   [25] macro expansion
      @ /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
   [26] runtests(oa_solver::MathOptInterface.OptimizerWithAttributes, conic_solver::MathOptInterface.OptimizerWithAttributes)
      @ Main.TestJuMP ~/.julia/dev/MOIPajarito/test/JuMP_tests.jl:15
   [27] macro expansion
      @ ~/.julia/dev/MOIPajarito/test/runtests.jl:39 [inlined]
   [28] macro expansion
      @ /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
   [29] macro expansion
      @ ~/.julia/dev/MOIPajarito/test/runtests.jl:39 [inlined]
   [30] macro expansion
      @ /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
   [31] top-level scope
      @ ~/.julia/dev/MOIPajarito/test/runtests.jl:36
   [32] include(fname::String)
      @ Base.MainInclude ./client.jl:444
   [33] top-level scope
      @ none:6
   [34] eval
      @ ./boot.jl:360 [inlined]
   [35] exec_options(opts::Base.JLOptions)
      @ Base ./client.jl:261
   [36] _start()
      @ Base ./client.jl:485

signal (11): Segmentation fault: 11
in expression starting at /Users/oscar/.julia/dev/MOIPajarito/test/runtests.jl:29
julia(87631,0x70000f739000) malloc: Incorrect checksum for freed object 0x7fe82d6b8168: probably modified after being freed.
Corrupt value: 0x2
julia(87631,0x70000f739000) malloc: *** set a breakpoint in malloc_error_break to debug

signal (6): Abort trap: 6
in expression starting at /Users/oscar/.julia/dev/MOIPajarito/test/runtests.jl:29
ERROR: Package MOIPajarito errored during testing (received signal: 11)
odow commented 2 years ago

Oh. I just realized. You're not running with https://github.com/jump-dev/MathOptInterface.jl/commit/9c3fd1044c1e06e04dea7625a7d47944b878d48c.

odow commented 2 years ago

Spoke too soon

(MOIPajarito) pkg> st
     Project MOIPajarito v0.0.0
      Status `~/.julia/dev/MOIPajarito/Project.toml`
  [4076af6c] JuMP v0.22.1
  [b8f27783] MathOptInterface v0.10.6 `https://github.com/jump-dev/MathOptInterface.jl.git#master`
  [37e2e46d] LinearAlgebra
  [de0858da] Printf
  [2f01184e] SparseArrays

(MOIPajarito) pkg> test
     Testing MOIPajarito
      Status `/private/var/folders/bg/dzq_hhvx1dxgy6gb5510pxj80000gn/T/jl_19b5je/Project.toml`
  [e2685f51] ECOS v0.14.0
  [60bf3e95] GLPK v0.15.2
  [b99e6be6] Hypatia v0.6.0
  [4076af6c] JuMP v0.22.1
  [bb71f62f] MOIPajarito v0.0.0 `~/.julia/dev/MOIPajarito`
  [b8f27783] MathOptInterface v0.10.6 `https://github.com/jump-dev/MathOptInterface.jl.git#master`
  [37e2e46d] LinearAlgebra `@stdlib/LinearAlgebra`
  [de0858da] Printf `@stdlib/Printf`
  [2f01184e] SparseArrays `@stdlib/SparseArrays`
  [8dfed614] Test `@stdlib/Test`
      Status `/private/var/folders/bg/dzq_hhvx1dxgy6gb5510pxj80000gn/T/jl_19b5je/Manifest.toml`
  [6e4b80f9] BenchmarkTools v1.2.1
  [b99e7846] BinaryProvider v0.5.10
  [fa961155] CEnum v0.4.1
  [49dc2e85] Calculus v0.5.1
  [d360d2e6] ChainRulesCore v1.11.1
  [9e997f8a] ChangesOfVariables v0.1.1
  [523fee87] CodecBzip2 v0.7.2
  [944b1d66] CodecZlib v0.7.0
  [861a8166] Combinatorics v1.0.2
  [bbf7d656] CommonSubexpressions v0.3.0
  [34da2185] Compat v3.40.0
  [864edb3b] DataStructures v0.18.10
  [163ba53b] DiffResults v1.0.3
  [b552c78f] DiffRules v1.5.0
  [ffbed154] DocStringExtensions v0.8.6
  [e2685f51] ECOS v0.14.0
  [f6369f11] ForwardDiff v0.10.23
  [60bf3e95] GLPK v0.15.2
  [14197337] GenericLinearAlgebra v0.2.7
  [b99e6be6] Hypatia v0.6.0
  [3587e190] InverseFunctions v0.1.2
  [92d709cd] IrrationalConstants v0.1.1
  [42fd0dbc] IterativeSolvers v0.9.2
  [692b3bcd] JLLWrappers v1.3.0
  [682c06a0] JSON v0.21.2
  [4076af6c] JuMP v0.22.1
  [7a12625a] LinearMaps v3.5.1
  [2ab3a3ac] LogExpFunctions v0.3.5
  [bb71f62f] MOIPajarito v0.0.0 `~/.julia/dev/MOIPajarito`
  [1914dd2f] MacroTools v0.5.9
  [b8f27783] MathOptInterface v0.10.6 `https://github.com/jump-dev/MathOptInterface.jl.git#master`
  [d8a4904e] MutableArithmetics v0.3.1
  [77ba4419] NaNMath v0.3.5
  [bac558e1] OrderedCollections v1.4.1
  [69de0a69] Parsers v2.1.2
  [3a141323] PolynomialRoots v1.0.0
  [21216c6a] Preferences v1.2.2
  [3cdcf5f2] RecipesBase v1.2.1
  [ae029012] Requires v1.1.3
  [276daf66] SpecialFunctions v1.8.1
  [90137ffa] StaticArrays v1.2.13
  [3bb67fe8] TranscodingStreams v0.9.6
  [6e34b625] Bzip2_jll v1.0.8+0
  [c2c64177] ECOS_jll v200.0.800+0
  [e8aa6df9] GLPK_jll v5.0.1+0
  [efe28fd5] OpenSpecFun_jll v0.5.5+0
  [0dad84c5] ArgTools `@stdlib/ArgTools`
  [56f22d72] Artifacts `@stdlib/Artifacts`
  [2a0f44e3] Base64 `@stdlib/Base64`
  [ade2ca70] Dates `@stdlib/Dates`
  [8bb1440f] DelimitedFiles `@stdlib/DelimitedFiles`
  [8ba89e20] Distributed `@stdlib/Distributed`
  [f43a241f] Downloads `@stdlib/Downloads`
  [b77e0a4c] InteractiveUtils `@stdlib/InteractiveUtils`
  [b27032c2] LibCURL `@stdlib/LibCURL`
  [76f85450] LibGit2 `@stdlib/LibGit2`
  [8f399da3] Libdl `@stdlib/Libdl`
  [37e2e46d] LinearAlgebra `@stdlib/LinearAlgebra`
  [56ddb016] Logging `@stdlib/Logging`
  [d6f4376e] Markdown `@stdlib/Markdown`
  [a63ad114] Mmap `@stdlib/Mmap`
  [ca575930] NetworkOptions `@stdlib/NetworkOptions`
  [44cfe95a] Pkg `@stdlib/Pkg`
  [de0858da] Printf `@stdlib/Printf`
  [9abbd945] Profile `@stdlib/Profile`
  [3fa0cd96] REPL `@stdlib/REPL`
  [9a3f8284] Random `@stdlib/Random`
  [ea8e919c] SHA `@stdlib/SHA`
  [9e88b42a] Serialization `@stdlib/Serialization`
  [1a1011a3] SharedArrays `@stdlib/SharedArrays`
  [6462fe0b] Sockets `@stdlib/Sockets`
  [2f01184e] SparseArrays `@stdlib/SparseArrays`
  [10745b16] Statistics `@stdlib/Statistics`
  [4607b0f0] SuiteSparse `@stdlib/SuiteSparse`
  [fa267f1f] TOML `@stdlib/TOML`
  [a4e569a6] Tar `@stdlib/Tar`
  [8dfed614] Test `@stdlib/Test`
  [cf7118a7] UUIDs `@stdlib/UUIDs`
  [4ec0a83e] Unicode `@stdlib/Unicode`
  [e66e0078] CompilerSupportLibraries_jll `@stdlib/CompilerSupportLibraries_jll`
  [781609d7] GMP_jll `@stdlib/GMP_jll`
  [deac9b47] LibCURL_jll `@stdlib/LibCURL_jll`
  [29816b5a] LibSSH2_jll `@stdlib/LibSSH2_jll`
  [c8ffd9c3] MbedTLS_jll `@stdlib/MbedTLS_jll`
  [14a3606d] MozillaCACerts_jll `@stdlib/MozillaCACerts_jll`
  [05823500] OpenLibm_jll `@stdlib/OpenLibm_jll`
  [83775a58] Zlib_jll `@stdlib/Zlib_jll`
  [8e850ede] nghttp2_jll `@stdlib/nghttp2_jll`
  [3f19e933] p7zip_jll `@stdlib/p7zip_jll`
     Testing Running tests...
starting Pajarito tests
starting JuMP tests
_soc1: Error During Test at /Users/oscar/.julia/dev/MOIPajarito/test/JuMP_tests.jl:34
  Got exception outside of a @test
  ECOS failed to construct problem.
  Stacktrace:
    [1] error(s::String)
      @ Base ./error.jl:33
    [2] _optimize!(dest::ECOS.Optimizer, src::MathOptInterface.Utilities.GenericModel{Float64, MathOptInterface.Utilities.ObjectiveContainer{Float64}, MathOptInterface.Utilities.VariablesContainer{Float64}, ECOS.ZerosOrNot{Float64, MathOptInterface.Utilities.MatrixOfConstraints{Float64, MathOptInterface.Utilities.MutableSparseMatrixCSC{Float64, Int64, MathOptInterface.Utilities.ZeroBasedIndexing}, Vector{Float64}, ECOS.Zeros{Float64}}, MathOptInterface.Utilities.MatrixOfConstraints{Float64, MathOptInterface.Utilities.MutableSparseMatrixCSC{Float64, Int64, MathOptInterface.Utilities.ZeroBasedIndexing}, Vector{Float64}, ECOS.Cones{Float64}}}})
      @ ECOS ~/.julia/packages/ECOS/oopWV/src/MOI_wrapper/MOI_wrapper.jl:250
    [3] optimize!
      @ ~/.julia/packages/ECOS/oopWV/src/MOI_wrapper/MOI_wrapper.jl:299 [inlined]
    [4] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{ECOS.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
      @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/FJ2EX/src/Utilities/cachingoptimizer.jl:285
    [5] optimize! (repeats 2 times)
      @ ~/.julia/packages/MathOptInterface/FJ2EX/src/Bridges/bridge_optimizer.jl:348 [inlined]
    [6] optimize!
      @ ~/.julia/packages/MathOptInterface/FJ2EX/src/MathOptInterface.jl:81 [inlined]
    [7] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{ECOS.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
      @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/FJ2EX/src/Utilities/cachingoptimizer.jl:285
    [8] optimize!(model::JuMP.Model, optimizer_factory::Nothing; bridge_constraints::Bool, ignore_optimize_hook::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
      @ JuMP ~/.julia/packages/JuMP/2IF9U/src/optimizer_interface.jl:195
    [9] optimize! (repeats 2 times)
      @ ~/.julia/packages/JuMP/2IF9U/src/optimizer_interface.jl:167 [inlined]
   [10] solve_subproblem(opt::MOIPajarito.Optimizer)
      @ MOIPajarito ~/.julia/dev/MOIPajarito/src/optimize.jl:385
   [11] run_iterative_method(opt::MOIPajarito.Optimizer)
      @ MOIPajarito ~/.julia/dev/MOIPajarito/src/optimize.jl:178
   [12] optimize(opt::MOIPajarito.Optimizer)
      @ MOIPajarito ~/.julia/dev/MOIPajarito/src/optimize.jl:142
   [13] optimize!
      @ ~/.julia/dev/MOIPajarito/src/MOI_wrapper.jl:212 [inlined]
   [14] optimize!
      @ ~/.julia/packages/MathOptInterface/FJ2EX/src/MathOptInterface.jl:81 [inlined]
   [15] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MOIPajarito.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
      @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/FJ2EX/src/Utilities/cachingoptimizer.jl:285
   [16] optimize!
      @ ~/.julia/packages/MathOptInterface/FJ2EX/src/Bridges/bridge_optimizer.jl:348 [inlined]
   [17] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MOIPajarito.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
      @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/FJ2EX/src/Utilities/cachingoptimizer.jl:294
   [18] optimize!(model::JuMP.Model, optimizer_factory::Nothing; bridge_constraints::Bool, ignore_optimize_hook::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
      @ JuMP ~/.julia/packages/JuMP/2IF9U/src/optimizer_interface.jl:195
   [19] optimize! (repeats 2 times)
      @ ~/.julia/packages/JuMP/2IF9U/src/optimizer_interface.jl:167 [inlined]
   [20] _soc1(opt::MathOptInterface.OptimizerWithAttributes)
      @ Main.TestJuMP ~/.julia/dev/MOIPajarito/test/JuMP_tests.jl:67
   [21] macro expansion
      @ ~/.julia/dev/MOIPajarito/test/JuMP_tests.jl:35 [inlined]
   [22] macro expansion
      @ /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1226 [inlined]
   [23] run_jump_tests(use_iter::Bool, oa_solver::MathOptInterface.OptimizerWithAttributes, conic_solver::MathOptInterface.OptimizerWithAttributes)
      @ Main.TestJuMP ~/.julia/dev/MOIPajarito/test/JuMP_tests.jl:34
   [24] macro expansion
      @ ~/.julia/dev/MOIPajarito/test/JuMP_tests.jl:15 [inlined]
   [25] macro expansion
      @ /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
   [26] runtests(oa_solver::MathOptInterface.OptimizerWithAttributes, conic_solver::MathOptInterface.OptimizerWithAttributes)
      @ Main.TestJuMP ~/.julia/dev/MOIPajarito/test/JuMP_tests.jl:15
   [27] macro expansion
      @ ~/.julia/dev/MOIPajarito/test/runtests.jl:39 [inlined]
   [28] macro expansion
      @ /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
   [29] macro expansion
      @ ~/.julia/dev/MOIPajarito/test/runtests.jl:39 [inlined]
   [30] macro expansion
      @ /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
   [31] top-level scope
      @ ~/.julia/dev/MOIPajarito/test/runtests.jl:36
   [32] include(fname::String)
      @ Base.MainInclude ./client.jl:444
   [33] top-level scope
      @ none:6
   [34] eval
      @ ./boot.jl:360 [inlined]
   [35] exec_options(opts::Base.JLOptions)
      @ Base ./client.jl:261
   [36] _start()
      @ Base ./client.jl:485

signal (11): Segmentation fault: 11
in expression starting at /Users/oscar/.julia/dev/MOIPajarito/test/runtests.jl:29
julia(88887,0x70000a875000) malloc: Incorrect checksum for freed object 0x7ff4968ff818: probably modified after being freed.
Corrupt value: 0x19b29
julia(88887,0x70000a875000) malloc: *** set a breakpoint in malloc_error_break to debug

signal (6): Abort trap: 6
in expression starting at /Users/oscar/.julia/dev/MOIPajarito/test/runtests.jl:29
ERROR: Package MOIPajarito errored during testing (received signal: 11)
odow commented 2 years ago

@chriscoey I dug a little deeper. ECOS is failing because it is getting passed a problem with 0 variables. We should throw a better error, but that suggests a bug in MOIPajarito?

chriscoey commented 2 years ago

Thanks. It is not necessarily an error for MOIPajarito to call the conic solver on a subproblem with 0 variables. For example, the MI-conic problem could have only integer variables, and so we want to check feasibility of an integral solution obtained by outer approximation by solving the conic subproblem with all variables fixed.

chriscoey commented 2 years ago

Hypatia is fine with solving problems with no variables - in fact in PajaritoExtras.jl, this is how we obtain cuts to separate infeasible points for some difficult cones, by just solving a separation problem with no primal variables.

odow commented 2 years ago

What is a problem with zero variables? You want to check the validity of the constant vector in a set of constraints? It seems like a lot of solvers would have trouble with that.

chriscoey commented 2 years ago

Yes it simply checks feasibility of a point. Primal-dual conic solvers should have no trouble with this. If the point is infeasible, the dual ray provides a separation oracle. Interestingly, for some cones (like weighted sum of squares), we do not have a primal separation oracle without optimization, so we actually need to use Hypatia to obtain a separating hyperplane.

odow commented 2 years ago

Primal-dual conic solvers should have no trouble with this

Should is the operative word. But ECOS does:

julia> using ECOS

julia> # min 
       # st  | 3.5 | + | | ∈ SOC
       #     | 0.0 |   | |
       inner = ECOS.ECOS_setup(
           0, # n
           2, # m
           0, # p
           0, # l
           1, # ncones
           Cint[2], # q,
           0, # nex
           Cdouble[], # Gpr,
           Cint[0, 0], # Gjc
           Cint[], # Gir
           Cdouble[], # Apr
           Cint[0, 0], # Ajc
           Cint[], # Air
           Cdouble[], # c
           Cdouble[3.5, 0.0], # h
           Cdouble[], # b
       )
Ptr{ECOS.pwork} @0x0000000000000000
chriscoey commented 2 years ago

I think we should report to ECOS if the issue is not caused by the ECOS.jl wrapper

chriscoey commented 2 years ago

I also think that an issue like this ought to be caught by an MOI.Test test, at least for primal-dual conic solvers. If for some reason a solver refuses to solve a problem with no variables, then an error message rather than a segfault would be nice.

odow commented 2 years ago

Here's what SCS does:

julia> using SCS
[ Info: Precompiling SCS [c946c3f1-0d1f-5ce8-9dea-7daa1f7e2d13]

julia> const MOI = SCS.MOI
MathOptInterface

julia> model = MOI.Utilities.Model{Float64}()
MOIU.Model{Float64}

julia> f = MOI.VectorAffineFunction(MOI.VectorAffineTerm{Float64}[], [1.0, 0.5, 0.5])
MathOptInterface.VectorAffineFunction{Float64}(MathOptInterface.VectorAffineTerm{Float64}[], [1.0, 0.5, 0.5])

julia> MOI.add_constraint(model, f, MOI.SecondOrderCone(3))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64}, MathOptInterface.SecondOrderCone}(1)

julia> scs = SCS.Optimizer()
SCS.Optimizer

julia> MOI.optimize!(scs, model)
ERROR: ArgumentError: The number of variables must be greater than 0
Stacktrace:
 [1] scs_solve(linear_solver::Type{SCS.DirectSolver}, m::Int64, n::Int64, A::MathOptInterface.Utilities.MutableSparseMatrixCSC{Float64, Int64, MathOptInterface.Utilities.ZeroBasedIndexing}, P::SparseArrays.SparseMatrixCSC{Float64, Int64}, b::Vector{Float64}, c::Vector{Float64}, z::Int64, l::Int64, bu::Vector{Float64}, bl::Vector{Float64}, q::Vector{Int64}, s::Vector{Int64}, ep::Int64, ed::Int64, p::Vector{Float64}, primal_sol::Vector{Float64}, dual_sol::Vector{Float64}, slack::Vector{Float64}; warm_start::Bool, options::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ SCS ~/.julia/packages/SCS/JCZYw/src/c_wrapper.jl:296
 [2] optimize!(dest::SCS.Optimizer, src::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.GenericModel{Float64, MathOptInterface.Utilities.ObjectiveContainer{Float64}, MathOptInterface.Utilities.VariablesContainer{Float64}, MathOptInterface.Utilities.MatrixOfConstraints{Float64, MathOptInterface.Utilities.MutableSparseMatrixCSC{Float64, Int64, MathOptInterface.Utilities.ZeroBasedIndexing}, SCS._SetConstants{Float64}, SCS._Cones{Float64}}}})
   @ SCS ~/.julia/packages/SCS/JCZYw/src/MOI_wrapper/MOI_wrapper.jl:341
 [3] optimize!(dest::SCS.Optimizer, src::MathOptInterface.Utilities.Model{Float64})
   @ SCS ~/.julia/packages/SCS/JCZYw/src/MOI_wrapper/MOI_wrapper.jl:400
 [4] top-level scope
   @ REPL[8]:1
odow commented 2 years ago

There are open issues like this: https://github.com/embotech/ecos/issues/199