ds4dm / ecole

Extensible Combinatorial Optimization Learning Environments
https://www.ecole.ai
BSD 3-Clause "New" or "Revised" License
325 stars 68 forks source link

How Ecole handles CTRL-C #69

Open gasse opened 4 years ago

gasse commented 4 years ago

Describe the bug

At the moment, pressing CTL-C while Ecole is running results in either one the two following effects: 1) SCIP catches the signal and interrupts the solving process silently, resulting in the episode terminating early, without any error message. 2) Ecole catches the signal and terminates with an Exception.

I think behaviour 2) is OK: CTRL-C signals should stop everything. Behaviour 1) is ok if one runs SCIP in interactive mode via the console, and wants to resume the optimization process afterwards. But with Ecole, the behaviour does not make much sense. Also it is simply annoying, say I want to kill Ecole in a jupyter Notebook, or in console, I have to keep pressing CTRL-C until Python catches the signal in order for the current execution to terminate.

Setting

All settings.

To Reproduce

Run an MDP loop (while True: reset, then while not done: step). Press CTRL-C during the execution.

Expected behavior

A Python KeyboardInterruption.

Fix

A fix is to tell SCIP to not catch CTRL-C signals:

"misc/catchctrlc": False
AntoinePrv commented 4 years ago

Thank you for bringing this up.

Is this a SCIP parameter? What is the behaviour of SCIP if we change that value? Would it ignore CTRL-C and keep on optimizing? Or return a different retcode?

Given that libscip is written in C, I don't think it can interrupt easily, it needs to clear up some ressources (otherwise there may be a memory leak and potentially a corrupted state). Then in method like Model::solve etc. we can check if CTRL-C was detected by SCIP and raise the exception ourselves. Also we need to check this wrt. the ReverseControl.

AntoinePrv commented 3 years ago

Perhaps we could edit scip::call with the following behaviour:

// ... check return code same as before
if ( SCIPinterrupted(scip) ){
    throw KeyboardInteruptedException{};
}

And register that exception in Pybind as a KeyboardInterruption.

Now the question is, which SCIP function should we test for?