Changing time limit and cutoff in C++ API causes segfault with Gurobi 9.5Answered
I am the project manager for the MINLP solver SHOT (github.com/coin-or/shot) which uses Gurobi as a subsolver for solving MIP problems.
The current master branch at github.com/coin-or/shot works well with Gurobi 9.1, however, when I try to use it with 9.5.1 Gurobi segfaults when I try to update the time limit and/or objective cut-off value.
I read here https://support.gurobi.com/hc/en-us/articles/360039233191-How-do-I-change-parameters-in-a-callback- that it is not supported to change parameters in callbacks, and I guess this might have something to do with the problem.
If I comment away the lines
then everyting works as with Gurobi 9.1. Is this a bug in Gurobi 9.5?
I need to have the callbacks to control output and allow for external termination criteria, so deactivating the callbacks is not an option. But at the same time I also need to be able to update the time limit and cut-off values... Any suggestions?
To reproduce this (i.e. cause a segfault):
git clone https://www.github.com/coin-or/SHOT --recursive
cmake .. -DCMAKE_BUILD_TYPE=Debug -DHAS_IPOPT=off -DHAS_CBC=off -DHAS_GAMS=off -DHAS_CPLEX=off -DHAS_GUROBI=on -DGUROBI_DIR=/opt/gurobi951
If you comment away the two lines mentioned above it works.
when I try to update the time limit and/or objective cut-off value
When exactly are you trying to update the time limit and/or objective cut-off?
Do you change the TimeLimit and Cutoff parameter from within a callback? If yes, then it is very likely that you just got "lucky" in 9.1 and Gurobi did not run into a segfault. As you already mentioned, changing parameters in a callback is not supported and the behavior can be in worst cases arbitrary. From your code, to me it looks like you do not change any parameters in a callback, at least not in the MIPSolverGurobi.cpp file.
Are you able to reproduce this issue outside of SHOT, i.e., with Gurobi only? Does this segfault occur only for a particular model?
Thanks for your comments. No I do not change the parameter values inside the callback. But activating a callback in Gurobi makes it segfault when updating the parameters in my own code.
The SHOT solver works such that it solves a MIP model with Gurobi, then when the solution is returned by Gurobi, I add new (linear) constraints to the Gurobi model and resolve (I do not use lazy constraints here). These linear constraints express supporting hyperplanes of the nonlinear feasible set of the MINLP problem.
Before the resolves I also need to change the cutoff and time limits since I do additional things in between here as well that can change them. It is these steps that cause Gurobi to crash.
I cannot really reproduce this outside of SHOT as everything is so integrated unfortunately. But this also happens for a lot of models (most of them actually), so it is nothing unique with this specific one.
This is very interesting!
Just created an internal ticket to better track this.
We tracked down the source of this issue.
In SHOT, it was a callback (GurobiCallbackMultiTree) going out of scope and deleted from memory then when performing basic operations on the model (e.g. setting time limit) Gurobi checked if the callback still worked, causing a segfault (as the callback was deleted from memory but not NULL).
The issue was resolved by making the lifetime of the callback match that of the model (keeping them both until the object is destroyed).
The fix can be seen in this PR: https://github.com/coin-or/SHOT/pull/155
Please sign in to leave a comment.