Session boundaries#
One of the main purposes of an environment is to indicate when your program will start to use Gurobi, and when it is done. When Gurobi is running on your own machine, creating an environment will obtain a license, and disposing of the environment will release that license. When you are a client of a Gurobi Compute Server, starting an environment will start a job on the server (or place the job in the queue if the server is fully occupied). Disposing of the environment will end that job, allowing the next job in the queue to start. On Gurobi Instant Cloud, creating an environment will launch a cloud instance (if it hasn’t been launched already). Disposing of the environment will end that session, which may result in the cloud instance being shut down (depending on the policy you’ve set in your Instant Cloud configuration).
If your program repeatedly creates, solves, and destroys optimization models, we strongly recommend that you do so within a single Gurobi environment. Creating a Gurobi environment incurs overhead, ranging anywhere from a quick local license check all the way to spinning up a machine on the cloud. By reusing a single environment, you avoid paying this overhead multiple times.
We also recommend that you dispose of your environment as soon as your program is done using Gurobi. Doing so releases all resources associated with that session, which in many cases can make those resources available to other users. You should pay particular attention to this topic when using programming languages that perform garbage-collection. While it is true that environments will be disposed of eventually by automated garbage-collection, that will often happen much earlier if you dispose of them explicitly.
The actual steps for disposing of an environment will depend on the API you are using:
Call GRBfreemodel()
for each model, then
call GRBfreeenv()
for the Gurobi environment.
For example:
GRBenv *env = NULL;
GRBmodel *model = NULL;
int error = 0;
/* Create environment */
error = GRBloadenv(&env, "example.log");;
if (error) goto QUIT;
/* Create an empty model */
error = GRBnewmodel(env, &model, "example", 0, NULL, NULL, NULL, NULL, NULL);
if (error) goto QUIT;
/* Create and add variable, constraints, objective; solve model */
QUIT:
/* Clean up model and environment */
GRBfreemodel(model);
GRBfreeenv(env);
Call the delete
operator on all GRBModel
objects, and then on
the GRBEnv
object, when the objects are created on the heap with
new
. For example:
/* Create environment */
GRBEnv* env = new GRBEnv();
/* Create model */
GRBModel* model = new GRBModel(*env);
/* Create and add variable, constraints, objective; solve model */
/* Clean up model and environment */
delete model;
delete env;
Note that you can also create model and environment objects on the stack
(i.e. without new
). In this case, disposal is performed when the
corresponding object goes out of scope.
Call GRBModel.Dispose()
on all
GRBModel
objects, then call
GRBEnv.Dispose()
on the GRBEnv
object.
For example:
// Create environment
GRBEnv env = new GRBEnv("example.log");
// Create empty model
GRBModel model = new GRBModel(env);
// Create and add variable, constraints, objective; solve model
// Clean up model and environment
model.Dispose();
env.Dispose();
Call GRBModel.dispose()
on all
GRBModel
objects, then call
GRBEnv.dispose()
on the GRBEnv
object. For example:
// Create environment
GRBEnv env = new GRBEnv("example.log");
// Create empty model
GRBModel model = new GRBModel(env);
// Create and add variable, constraints, objective; solve model
// Clean up model and environment
model.dispose();
env.dispose();
Call Model.dispose()
on all Model
objects, Env.dispose()
on any Env
objects you created, or
disposeDefaultEnv()
if you used the
default environment instead.
However, we recommend to use context managers for environment and
model objects. This will guarantee that these objects are automatically
disposed of.
For example:
with gp.Env() as env:
with gp.Model(env=env) as model:
# construct, solve, and post-process `model`
Refer to Env class documentation
for more information.
A typical use pattern is also shown in the example
mip1_remote.py.
Note that the boundaries established by an environment are for a single thread. Gurobi environments are not thread-safe, so you can’t have more than one thread of control within a single environment. You can however have a single program that launches multiple threads, each with its own environment.