coin-or / coin-or/python-mip

Confusing Behaviour with disposing of Gurobi Environment

Open
#347 1 comment 1 reaction 0 assignees View on GitHub
bug gurobi
Dominant language
Linear Programming
Stars
600
Forks
108
PR merge metrics
No merged PRs in 30d

Description

**Describe the bug**
I have a single use Gurobi licence so I can't have more than one Gurobi environment running at the same time. However, I'm getting some confusing behaviour when trying to clean up the Gurobi environment after a run.

**To Reproduce**
So if I firstly run this:
```py
import gurobipy as gp
from itertools import product
from mip import Model

model = Model(solver_name='GUROBI')

x = model.add_var(name="X", lb=10, ub=80)
model.objective = x
status = model.optimize()

print(status)

# Create a new model
m = gp.Model()

# Create variables
x = m.addVar(vtype='B', name="x")

# Set objective function
m.setObjective(x, gp.GRB.MAXIMIZE)

# Solve it!
m.optimize()

print(f"Optimal objective value: {m.objVal}")
print(f"Solution values: x={x.X}, y={y.X}, z={z.X}")

gp.disposeDefaultEnv()
```
Then I get an error `GurobiError: Single-use license. Another Gurobi process with pid 3981 running.` when it tries to create a new model using `gp.Model()`.

So then I tried to dispose of the model using `del model` first like so:
```py
import gurobipy as gp
from itertools import product
from mip import Model

model = Model(solver_name='GUROBI')

x = model.add_var(name="X", lb=10, ub=80)
model.objective = x
status = model.optimize()

print(status)

del model

# Create a new model
m = gp.Model()

# Create variables
x = m.addVar(vtype='B', name="x")

# Set objective function
m.setObjective(x, gp.GRB.MAXIMIZE)

# Solve it!
m.optimize()

print(f"Optimal objective value: {m.objVal}")
print(f"Solution values: x={x.X}, y={y.X}, z={z.X}")

gp.disposeDefaultEnv()
```
However this produces the same error.

The thing that confuses me is that it works when I delete the solver directly like so:
```py
import gurobipy as gp
from itertools import product
from mip import Model

model = Model(solver_name='GUROBI')

x = model.add_var(name="X", lb=10, ub=80)
model.objective = x
status = model.optimize()

print(status)

del model.solver

# Create a new model
m = gp.Model()

# Create variables
x = m.addVar(vtype='B', name="x")

# Set objective function
m.setObjective(x, gp.GRB.MAXIMIZE)

# Solve it!
m.optimize()

print(f"Optimal objective value: {m.objVal}")
print(f"Solution values: x={x.X}, y={y.X}, z={z.X}")

gp.disposeDefaultEnv()
```
The thing I don't understand is that this line: https://github.com/coin-or/python-mip/blob/master/mip/model.py#L135-L136 implies that when we do `del model` then it should be doing `del model.solver` under the hood. So I don't understand why `del model.solver` works but `del model` doesn't.

Steps to reproduce the behavior **please include attached any files needed to reproduce the error**. We can only help you if we can reproduce the error ourselves and debug.

**Expected behavior**
I would expect both `del model` and `del model.solver` to clean up the Gurobi environment.

**Desktop (please complete the following information):**
- Operating System, version: Debian GNU/Linux 10 (buster)
- Python version: 3.8.12
- Python-MIP version (we recommend you to test with the latest version): 1.15.0

Let me know if you need any more information 😊

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.