-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot dispose of environment programatically #36
Comments
Can you share the code to initialize Gurobi model? |
Great point. Let me investigate and get back to you! |
Here's is the code. You'll see that it follows your recommended approach I think. Gurobi's documentation however explains that |
It seems that your code does cleanup the environment when your PyOptInterface environment is destroyed. Maybe the Python garbage collector is just slow to run? I can try to test if forcing the garbage collector to run fixes the issue - although that would really just be a workaround... |
The model keeps a reference to env to avoid GC frees env too early:
In theory, I carry out a small experiment to validate my assumption.
GurobiEnv::~GurobiEnv()
{
fmt::print("Free GurobiEnv\n");
gurobi::GRBfreeenv(m_env);
}
import pyoptinterface as poi
from pyoptinterface import gurobi
def f():
env = gurobi.Env()
model = gurobi.Model(env)
return model
model = f()
del model I see the console outputs |
I'm not sure if that's quite right. As explained here
I think your example only works because a) there are no cyclical references and b) you happen to be using CPython. I think for your test to be correct you should turn off garbage collection (since Python says "do not depend on [it]") : import gc
import pyoptinterface as poi
from pyoptinterface import gurobi
gc.disable()
def f():
env = gurobi.Env()
model = gurobi.Model(env)
return model
model = f()
del model
input() # Adding this is important I think; obviously when the entire program exits all objects are destroyed. This ensures the program hangs |
dispose()
call on cleanup
(renamed the issue since I agree this is not a memory leak) |
You are right. Garbage collection does not guarantee that If you want to ensure from pyoptinterface import gurobi
def f():
env = gurobi.Env()
model = gurobi.Model(env)
return model
model = f()
del model._env
del model The problem is not "Cannot dispose of environment programatically" ( In this use case, you should pass a prepared |
Hmm I'm afraid I will try using your workaround for now although I think exposing the environment free methods would be important to avoid relying on the garbage collector (as Python warns not to do). |
We just tested your workaround ( |
The correct way to free model and environment correctly will be: from pyoptinterface import gurobi
def f():
env = gurobi.Env()
model = gurobi.Model(env)
return model
model = f()
env = model._env
del model
del env In this way, |
I'll check! I think you're right that the issue is that Afaik, I'll get back to you with the results of the test. If we can fix the broken status on Gurobi Compute server I'll be happy! |
I can confirm that the following fixes the issue. Gurobi Compute Server now shows "optimal" import gc
...
del model
gc.collect() Obviously, having to manually mess with the garbage collector to cleanup our environment is not ideal (nor recommended by Python). So, if you have time to expose |
Get it. |
Hi again,
Correct me if I'm wrong but it seems that there is no way to "cleanup" a PyOptInterface model.
Our team has an issue where we don't know how to end our Gurobi Compute Server run. We tried running
del model
but it doesn't work (the compute server continues to indicate that the model is "running"). Is it possible to either:.dispose()
method so we can manually cleanup our model..dispose()
function whenever a PyOptInterface model is deleted. For example by overriding the model's__del__
method.Thank you!!
Martin
The text was updated successfully, but these errors were encountered: