Gurobi recording files enable a user to replay the exact model-building and solution process from one machine on another machine, independent of the underlying hardware. This can be helpful in identifying inconsistent solver behavior on a specific machine. Additionally, recording files show model alterations such as variable additions or coefficient modifications as they are performed before, after, or even during an optimization run.
Create a recording file
Although the following description is limited to the Python API, it applies to the other Gurobi APIs.
In order to activate the recording mechanism, the Record parameter must be set to 1 before the Gurobi environment is started. This can be done in two ways:
- Create a gurobi.env file containing the line Record 1 in the working directory of your Gurobi application. By default, Gurobi searches for this file in the current working directory and initializes an environment according to the parameter settings in the file.
- Directly set the Record parameter through the API. This is done by defining an empty environment, setting the Record parameter, starting the environment, then associating the newly created environment with a model:
Using the mip1 model as an example:
import gurobipy as gp
from gurobipy import GRB
with gp.Env(params={"Record": 1}) as e:
with gp.Model("mip1", env=e) as m:
x = m.addVar(vtype=GRB.BINARY, name="x")
y = m.addVar(vtype=GRB.BINARY, name="y")
z = m.addVar(vtype=GRB.BINARY, name="z")
m.setObjective(x + y + 2 * z, GRB.MAXIMIZE)
m.addConstr(x + 2 * y + 3 * z <= 4, "c0")
m.addConstr(x + y >= 1, "c1")
m.optimize()
the output confirms that Gurobi has successfully completed a recording file:
*** Start recording in file recording000.grbr
...
*** Recording complete - close file recording000.grbr
Gurobi will not overwrite an existing recording file in the current directory. For example, if a file named recording000.grbr already exists, Gurobi will create a new recording file named recording001.grbr.
Replay a recording file
To replay a Gurobi recording file, use the Gurobi command-line tool:
gurobi_cl recording000.grbr
This replays the model-building and optimization, including all API calls, exactly as it was performed on the original machine where the recording file was created.
Replaying the recording from the above mip1 example produces output similar to the following:
*Replay* Replay of file 'recording000.grbr'
*Replay* Recording captured Mon Feb 6 09:36:29 2023
*Replay* Recording captured with Gurobi version 10.0.1 (mac64[arm])
*Replay* Recording captured with Gurobi Python version 10.0.1
*Replay* Load new Gurobi environment
*Replay* Change core count (from 0/0 to 8/8)
*Replay* Ignore setting opaque parameter Username
*Replay* Ignore setting opaque parameter GURO_PAR_LICFILE
*Replay* Create new Gurobi model (0 rows, 0 cols)
*Replay* Ignore setting opaque parameter Username
*Replay* Update Gurobi model
*Replay* Change objective sense to -1
*Replay* Add 3 new variables
*Replay* Add 2 new constraints
*Replay* Change 3 objective coefficients
*Replay* Change objective constant to 0
*Replay* Discard Q matrix
*Replay* Update Gurobi model
*Replay* Optimize
Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (mac64[arm])
CPU model: Apple M1
Thread count: 8 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 2 rows, 3 columns and 5 nonzeros
Model fingerprint: 0x98886187
Variable types: 0 continuous, 3 integer (3 binary)
Coefficient statistics:
Matrix range [1e+00, 3e+00]
Objective range [1e+00, 2e+00]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 4e+00]
Found heuristic solution: objective 2.0000000
Presolve removed 2 rows and 3 columns
Presolve time: 0.00s
Presolve: All rows and columns removed
Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)
Thread count was 1 (of 8 available processors)
Solution count 2: 3 2
Optimal solution found (tolerance 1.00e-04)
Best objective 3.000000000000e+00, best bound 3.000000000000e+00, gap 0.0000%
*Replay* Free Gurobi model
*Replay* Free Gurobi environment
*Replay* Replay complete
*Replay* Gurobi API routine runtime: 0.01s
*Replay* Gurobi solve routine runtime: 0.01s
Note: The order of API calls in the recording is not exact. For example, in the original Python code, the three variables were created before the objective sense was set. However, in the recording, the objective sense is set before the variables are created. This difference is due to the fact that all model changes are processed by a Model.update() call, which does not necessarily preserve the original order of function calls. In this case, the model update is implicitly performed in the Model.optimize() call.
Note: The recording output explicitly shows that the Gurobi model and environment were freed. If the environments were not properly disposed at the end of the mip1 example script, the recording output would include the following:
*Replay* Environments leaked: 1
The time spent in API routines and the actual solve time are displayed at the end of the recording.
Record multiple optimization runs
It is possible to record multiple optimization runs.
- If the existing model is modified and re-solved, these API calls will be included in the recording file. The model and environment should be disposed only after all optimization runs are complete.
- If a new model is created and solved, simply re-use the same Gurobi environment to create the new model. E.g.:
with gp.Env(params={"Record": 1}) as e:
with gp.Model("m", env=e) as m:
# Formulate and solve m
with gp.Model("m2", env=e) as m2:
# Formulate and solve m2
Limitations
Recording files are currently not compatible with callbacks. Moreover, recording files may provide false results when working with concurrent and/or distributed optimization. In addition, recording won't capture calls to the Gurobi tuning tool.
Comments
0 comments
Article is closed for comments.