Error "OPTIMIZATION_IN_PROGRESS" after call to GRBModel::terminate()
OngoingDear all,
I have the following problem using the C++ API of Gurobi. I want to write an abort-function which can be called by a signal handler. In this abort-function I want to stop the optimization and query some information (e.g. ObjBound, ObjVal, MIPGap) which will then be printed to the screen.
So, the first thing I do in the abort-function is call "model.terminate()". Then, I try to query the information. However, any call to GRBModel::get() results in an exception, specifically Error No. 10017 (OPTIMIZATION_IN_PROGRESS).
I already tried to "sleep" for a couple of seconds between the call to terminate() and get(). Also, I tried a long while-loop between those two calls, just to "wait" some time. But nothing helps.
Does anyone have an idea what could be the problem? Thank you!
Best, David
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Hi David,
model.terminate() is sending a request to terminate the optimization process as soon as possible. You should query the model status for the status GRB_INTERRUPTED before querying other attributes.
Are you calling this from within a callback? Then, I suggest only calling the terminate function in the callback and then querying the attributes outside of the callback when the optimization process is finished.
Cheers,
Matthias0 -
Hi Matthias,
sorry for not being precise in my previous post. Before querying any attributes, I do in fact query the status, and it is at that point where the exception gets raised. That is, querying the status results in the exception.
To answer your question, no I do not call this from a callback. The structure of my functions looks more or less as follows: I have a function "abort()" which gets called when a signal (e.g. SIGKILL) is caught:
void MIPSolver::abort()
{
model.terminate();
[some other stuff]
foo();
}And then in "foo()" I query the status.
void MIPSolver::foo() const
{
std::string status = "";
switch (model.get(GRB_IntAttr_Status))
{
case GRB_OPTIMAL:
status = "Optimal";
break;
case GRB_INFEASIBLE:
status = "Infeasible";
break;
case GRB_INF_OR_UNBD:
status = "Infeasible OR Unbounded";
break;
case GRB_UNBOUNDED:
status = "Unbounded";
break;
case GRB_TIME_LIMIT:
if(model.get(GRB_DoubleAttr_MIPGap) != GRB_INFINITY) {
status = "Feasible";
} else {
status = "Unknown";
}
break;
case GRB_INTERRUPTED: // interrupted by signal handler
if(model.get(GRB_DoubleAttr_MIPGap) != GRB_INFINITY) {
status = "Feasible";
} else {
status = "Unknown";
}
break;
default:
status = std::to_string(model.get(GRB_IntAttr_Status));
}
[some other stuff]
}The exception/error then happens at the switch-statement.
Thanks for your help!
Best,
David0 -
Hi David,
We will continue the discussion in an internal ticket.
Best regards,
Matthias0 -
Hi David,
Although you have called model.terminate(), the overall process might not have completed just yet, and thus making the Status unavailable to be retrieved (Error code = 10017).
Depending on the sleep time, having a sleep command could help, but it would not guarantee that the status can be retrieved by the moment sleep completes.
We would suggest checking the status in a loop that handles the exception thrown by Gurobi gracefully.
You might want to try a snippet as provided below. You probably don't want the verbose information in the exception handler.
Please let us know if this works. If not, could you share your code with us?
void MIPSolver::abort()
{
model.terminate();
[some other stuff]
foo();
}
void MIPSolver::foo() const
{
for(bool success = false; !success; ){
try{
std::string status = "";
switch (model.get(GRB_IntAttr_Status))
{
case GRB_OPTIMAL:
status = "Optimal";
break;
case GRB_INFEASIBLE:
status = "Infeasible";
break;
case GRB_INF_OR_UNBD:
status = "Infeasible OR Unbounded";
break;
case GRB_UNBOUNDED:
status = "Unbounded";
break;
case GRB_TIME_LIMIT:
if(model.get(GRB_DoubleAttr_MIPGap) != GRB_INFINITY) {
status = "Feasible";
} else {
status = "Unknown";
}
break;
case GRB_INTERRUPTED: // interrupted by signal handler
if(model.get(GRB_DoubleAttr_MIPGap) != GRB_INFINITY) {
status = "Feasible";
} else {
status = "Unknown";
}
break;
default:
status = std::to_string(model.get(GRB_IntAttr_Status));
}
success = true;
[some other stuff]
}
catch (GRBException e) {
cout << "Error code = " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
}
}
}Thank you!
Rodrigo
0
Post is closed for comments.
Comments
5 comments