Skip to content

Commit

Permalink
Support interrupting the MIP solver (#229)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Apr 18, 2024
1 parent f8052b4 commit 4cb5f8e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
7 changes: 5 additions & 2 deletions src/MOI_wrapper/MOI_callbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ function MOI.set(model::Optimizer, ::CallbackFunction, callback::Function)
model.has_generic_callback = true
_set_callback(model, (cb_data) -> begin
model.callback_state = _CB_GENERIC
callback(cb_data)
model.callback_state = _CB_NONE
try
callback(cb_data)
finally
model.callback_state = _CB_NONE
end
end)
return
end
Expand Down
4 changes: 3 additions & 1 deletion src/MOI_wrapper/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1402,7 +1402,9 @@ function _solve_mip_problem(model::Optimizer)
#
# This next bit is _very_ important! See the note associated with
# set_callback.
if model.callback_data.exception !== nothing
if model.callback_data.exception isa InterruptException
model.solver_status = GLP_ESTOP
elseif model.callback_data.exception !== nothing
throw(model.callback_data.exception)
end
finally
Expand Down
27 changes: 25 additions & 2 deletions test/MOI_callbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@

module TestCallbacks

using GLPK, Test, Random
using GLPK
using Random
using Test

const MOI = GLPK.MOI
import MathOptInterface as MOI

function runtests()
for name in names(@__MODULE__; all = true)
Expand Down Expand Up @@ -554,6 +556,27 @@ function test_issue_189(cache)
return
end

function test_no_cache_InterruptException()
model = GLPK.Optimizer()
MOI.set(model, MOI.Silent(), true)
x = MOI.add_variable(model)
MOI.add_constraint(model, 1.0 * x, MOI.GreaterThan(2.0))
MOI.add_constraint(model, x, MOI.Integer())
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
f = 1.0 * x
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
interrupt_thrown = false
function my_callback(cb_data)
interrupt_thrown = true
return throw(InterruptException())
end
MOI.set(model, GLPK.CallbackFunction(), my_callback)
MOI.optimize!(model)
@test interrupt_thrown
@test MOI.get(model, MOI.TerminationStatus()) == MOI.INTERRUPTED
return
end

end

TestCallbacks.runtests()

0 comments on commit 4cb5f8e

Please sign in to comment.