I am solving a MIP and have built a corresponding CPLEX IloModel. My implementation follows the following pseudo-code:
model = IloModel( env );
//Build optimization model
//Configure CPLEX Solver
//Solve model
//Do some solution-statistics
model.end();
Everything works fine, I get correct solutions, et cetera. Now, I would like to automate solving a lot of different instances sequentially.
However, here I ran into a problem: the bigger my instances, the longer freeing resources using model.end()
takes time. For my small instances (using up to 500mb of RAM) it already takes dozens of minutes, for medium sized instance (using up to 2 GB of RAM) it takes hours and I never measured how long it takes my large instances (using up to 32 GB of RAM), as I always manually killed the process after it did not finish over a whole nights wait. Therefore, freeing ressources takes significantly longer than building the model or solving it using my specified time-limits. While model.end()
runs, the CPU usage always stays at roughly 100%.
Is this expected behaviour? Have I missed something in implementing my model or how to free resources that it takes this excessive amount of time?
I really want to avoid automating solving multiple instances in sequence through killing the CPLEX solve process after a specified time threshold.
Thank you!
EDIT:
I can circumvent the problem by running env.end()
(which takes <1s even for large models) instead of model.end()
. As I do not reuse the environment for now, that is ok for me. However, I wonder what is happening here, from what I gathered from the docs, freeing the resources allocated for the model is a subprocess of freeing the whole environment.
I'm guessing, but did you terminate the solver before terminating the model? The solver is using the model and so it is notified about its changes. It could be that model.end()
is not optimized and as it is freeing constraints one by one, solver is notified about each particular change, it updates its own data structures etc.
In other words, I think that calling cplex.end()
before model.end()
may solve the issue.
If you can then it is always best to call env.end()
after each solve. As you noticed, it is faster: it is easier to free all the resources at once since there's no need to check whether a particular resource is still needed (e.g. a variable could be used by multiple models). It is also safer since new model starts from scratch and the risk of a memory leak is minimized.