scipopt / SCIP.jl

Julia interface to SCIP solver
MIT License
95 stars 24 forks source link

conshdlr.jl examples and ERROR: invalid SCIP stage <2>, SCIP_INVALIDCALL::SCIP_Retcode = -8 errors and their explanation? #219

Closed mavavilj closed 2 years ago

mavavilj commented 2 years ago

I'm trying some examples from https://github.com/scipopt/SCIP.jl/blob/master/test/conshdlr.jl and for example:

https://github.com/scipopt/SCIP.jl/blob/master/test/conshdlr.jl#L1

seems to produce:

[scip_solve.c:3409] ERROR: invalid SCIP stage <2> [scip_prob.c:704] ERROR: Error <-8> in function call [scip_general.c:325] ERROR: Error <-8> in function call

on https://github.com/scipopt/SCIP.jl/blob/master/test/conshdlr.jl#L11

I've lifted DummyConsHdlr(), DummyCons(), @SCIP_CALL manually from the sources.

I don't understand what these errors refer to. Or whether they're expected behavior for this problem.

Reproducible example, e.g.:

using JuMP
using SCIP

macro SCIP_CALL(ex)
    return :(@assert $(esc(ex)) == SCIP.SCIP_OKAY)
end

mutable struct DummyConsHdlr <: SCIP.AbstractConstraintHandler
    check_called::Int64
    enfo_called::Int64
    lock_called::Int64

    DummyConsHdlr() = new(0, 0, 0)
end

o = SCIP.Optimizer()
SCIP.set_parameter(o.inner, "display/verblevel", 0)

# add the constraint handler
ch = DummyConsHdlr()
SCIP.include_conshdlr(o.inner.scip[], o.inner.conshdlrs, ch; needs_constraints=false)

# solve the problem
@SCIP_CALL SCIP.SCIPsolve(o.inner.scip[])
rschwarz commented 2 years ago

I'm not sure what to say, because the actual test (from which you take the snipped) does currently pass (in the CI and locally). Does it also work for you? It seems that you're using a custom SCIP, compiled in debug mode.

Maybe the issue is that include_conshdlr is called multiple times with the same Optimizer, while the test uses a "fresh" instance?

mavavilj commented 2 years ago

I installed via:

pkg> add SCIP

Another example (https://github.com/scipopt/SCIP.jl/blob/master/test/conshdlr.jl#L21):

using JuMP
using SCIP

macro SCIP_CALL(ex)
    return :(@assert $(esc(ex)) == SCIP.SCIP_OKAY)
end

mutable struct DummyConsHdlr <: SCIP.AbstractConstraintHandler
    check_called::Int64
    enfo_called::Int64
    lock_called::Int64

    DummyConsHdlr() = new(0, 0, 0)
end

mutable struct DummyCons <: SCIP.AbstractConstraint{DummyConsHdlr} end

o = SCIP.Optimizer()
SCIP.set_parameter(o.inner, "display/verblevel", 0)

# add the constraint handler
ch = DummyConsHdlr()
SCIP.include_conshdlr(o.inner.scip[], o.inner.conshdlrs, ch; needs_constraints=true)

# add dummy constraint
cr = SCIP.add_constraint(o.inner, ch, DummyCons())

# solve the problem
@SCIP_CALL SCIP.SCIPsolve(o.inner.scip[])

gives:


ERROR: LoadError: MethodError: no method matching lock(::DummyConsHdlr, ::Ptr{Nothing}, ::SCIP.LibSCIP.SCIP_LockType, ::Int32, ::Int32)
Stacktrace:
 [1] _conslock(scip::Ptr{Nothing}, conshdlr::Ptr{Nothing}, cons::Ptr{Nothing}, locktype::SCIP.LibSCIP.SCIP_LockType, nlockspos::Int32, nlocksneg::Int32)
   @ SCIP ~/.julia/packages/SCIP/rCg3R/src/conshdlr.jl:254
 [2] SCIPsolve(scip::Ptr{Nothing})
   @ SCIP.LibSCIP ~/.julia/packages/SCIP/rCg3R/src/LibSCIP.jl:13547
 [3] top-level scope
   @ ~/coding/hellojl/hello.jl:29
in expression starting at /home/mavavilj/coding/hellojl/hello.jl:29
[scip_solve.c:3409] ERROR: invalid SCIP stage <2>
[scip_prob.c:704] ERROR: Error <-8> in function call
[scip_general.c:325] ERROR: Error <-8> in function call
...
rschwarz commented 2 years ago

I installed via: pkg> add SCIP

Does pkg> test SCIP work for you, then?

In a previous comment, you showed a failed assert, which led me to believe that a separate SCIP installation was used.

rschwarz commented 2 years ago

Note that multiple methods need to be implemented for constraint handlers. See the file conshdlr_support.jl for how this is done in the tests.

mavavilj commented 2 years ago

All tests pass.

Okay using the previous comment I produced:

using JuMP
using SCIP

macro SCIP_CALL(ex)
    return :(@assert $(esc(ex)) == SCIP.SCIP_OKAY)
end

# Define a minimal no-op constraint handler.
# Needs to be mutable for `pointer_from_objref` to work.
mutable struct DummyConsHdlr <: SCIP.AbstractConstraintHandler
    check_called::Int64
    enfo_called::Int64
    lock_called::Int64

    DummyConsHdlr() = new(0, 0, 0)
end

# Implement only the fundamental callbacks:
function SCIP.check(ch::DummyConsHdlr,
                    constraints::Array{Ptr{SCIP.SCIP_CONS}},
                    sol::Ptr{SCIP.SCIP_SOL},
                    checkintegrality::Bool,
                    checklprows::Bool,
                    printreason::Bool,
                    completely::Bool)
    ch.check_called += 1
    return SCIP.SCIP_FEASIBLE
end

function SCIP.enforce_lp_sol(ch::DummyConsHdlr,
                             constraints::Array{Ptr{SCIP.SCIP_CONS}},
                             nusefulconss::Cint,
                             solinfeasible::Bool)
    ch.enfo_called += 1
    return SCIP.SCIP_FEASIBLE
end

function SCIP.enforce_pseudo_sol(ch::DummyConsHdlr,
                                 constraints::Array{Ptr{SCIP.SCIP_CONS}},
                                 nusefulconss::Cint,
                                 solinfeasible::Bool,
                                 objinfeasible::Bool)
    ch.enfo_called += 1
    return SCIP.SCIP_FEASIBLE
end

function SCIP.lock(ch::DummyConsHdlr,
                   constraint::Ptr{SCIP.SCIP_CONS},
                   locktype::SCIP.SCIP_LOCKTYPE,
                   nlockspos::Cint,
                   nlocksneg::Cint)
    ch.lock_called += 1
end

# Corresponding, empty constraint (data) object
mutable struct DummyCons <: SCIP.AbstractConstraint{DummyConsHdlr} end

o = SCIP.Optimizer()
SCIP.set_parameter(o.inner, "display/verblevel", 0)

# add the constraint handler
ch = DummyConsHdlr()
SCIP.include_conshdlr(o.inner.scip[], o.inner.conshdlrs, ch; needs_constraints=true)

# add dummy constraint
cr = SCIP.add_constraint(o.inner, ch, DummyCons())

# solve the problem
@SCIP_CALL SCIP.SCIPsolve(o.inner.scip[])

and compiling this produces no errors. So perhaps this was some "half-implemented" problem. Not sure what exactly causes the problem though, because I'm SCIP newbie.

rschwarz commented 2 years ago

There's no documentation on constraint handlers specific to SCIP.jl, but it's recommended that users first get familiar with the concept in general. In particular, each plugin has a set of fundamental callbacks that need to be implemented.

mavavilj commented 2 years ago

Maybe the examples/tests could be better structured?