Note
You can download this example as a Jupyter notebook or start it in interactive mode.
Solve a model on a remote machine
In this example, we explain how linopy can handle model optimization on remote machines. What you need in order to run the example: * a running installation of paramiko on your local machine (use pip install paramiko
for example) * a remote server with an working installation of linopy, e.g. in a conda
environment. * a working ssh access to that machine
The basic idea that the workflow follows consists of the following steps most of which linopy takes over for you:
define a model on the local machine
save the model on the remote machine
load, solve and write out the model, all on the remote machine
copy the solved model to the local machine
load the solved model on the local machine
Therefore the initialization process happens locally and the solving remotely.
Create a model
First we are going to build the optimization model we want to solve in our local process.
[1]:
from linopy import Model
from numpy import arange
N = 10
m = Model()
coords = [arange(N), arange(N)]
x = m.add_variables(coords=coords, name='x')
y = m.add_variables(coords=coords, name='y')
m.add_constraints(x - y >= arange(N))
m.add_constraints(x + y >= 0)
m.add_objective((2 * x + y).sum())
m
[1]:
Linopy model
============
Variables:
----------
Dimensions: (dim_0: 10, dim_1: 10)
Coordinates:
* dim_0 (dim_0) int64 0 1 2 3 4 5 6 7 8 9
* dim_1 (dim_1) int64 0 1 2 3 4 5 6 7 8 9
Data:
x (dim_0, dim_1) int64 0 1 2 3 4 5 6 7 8 ... 92 93 94 95 96 97 98 99
y (dim_0, dim_1) int64 100 101 102 103 104 ... 195 196 197 198 199
Constraints:
------------
Dimensions: (dim_0: 10, dim_1: 10)
Coordinates:
* dim_0 (dim_0) int64 0 1 2 3 4 5 6 7 8 9
* dim_1 (dim_1) int64 0 1 2 3 4 5 6 7 8 9
Data:
con0 (dim_0, dim_1) int64 0 1 2 3 4 5 6 7 8 ... 92 93 94 95 96 97 98 99
con1 (dim_0, dim_1) int64 100 101 102 103 104 ... 195 196 197 198 199
Status:
-------
initialized
Initialize SSH connection
Now we have to set up the SSH connection. The SSH connection is handled by the RemoteHandler
class in of the linopy.remote
module. This is strongly relying on the paramiko
package. When initializing, you have two options:
Pass the standard arguments
host
,username
. If the SSH keys are stored in a default location, the keys are autodetected and theRemoteHandler
does not require thepassword
argument. Otherwise you also have to pass the password.Pass a working
paramiko.SSHClient
asclient
. This enables you to set up the SSH connection by others means supported byparamiko
.
In the following we use the first option.
[2]:
from linopy import RemoteHandler
host = "your.host.de"
username = "username"
handler = RemoteHandler(host, username=username)
Optionally: Activate a conda environment on the remote
The RemoteHandler
keeps an interactive shell in the background. You can execute any code in order to prepare the solving process (install linopy, activate an environment).
Assuming you have a conda environment linopy-env
that contains the linopy
package with dependencies, you can run
[3]:
handler.execute("conda activate linopy-env")
Solve the model on remote
Now the only thing you have to do is to pass the RemoteHandler
as an argument to the solve
function. Other keyword arguments like solver_name
and solver options are propagated to the remote machine.
[4]:
m.solve(remote=handler)
Set parameter Username
Academic license - for non-commercial use only - expires 2023-02-06
Read LP format model from file /tmp/linopy-problem-uh4gvjyp.lp
Reading time = 0.00 seconds
obj: 200 rows, 200 columns, 400 nonzeros
Gurobi Optimizer version 9.5.1 build v9.5.1rc2 (linux64)
Thread count: 12 physical cores, 24 logical processors, using up to 24 threads
Optimize a model with 200 rows, 200 columns and 400 nonzeros
Model fingerprint: 0xf2bcac49
Coefficient statistics:
Matrix range [1e+00, 1e+00]
Objective range [1e+00, 2e+00]
Bounds range [0e+00, 0e+00]
RHS range [1e+00, 9e+00]
Presolve removed 200 rows and 200 columns
Presolve time: 0.00s
Presolve: All rows and columns removed
Iteration Objective Primal Inf. Dual Inf. Time
0 2.2500000e+02 0.000000e+00 0.000000e+00 0s
Solved in 0 iterations and 0.00 seconds (0.00 work units)
Optimal objective 2.250000000e+02
[4]:
('ok', '')
[5]:
m.solution
[5]:
<xarray.Dataset> Dimensions: (dim_0: 10, dim_1: 10) Coordinates: * dim_0 (dim_0) int64 0 1 2 3 4 5 6 7 8 9 * dim_1 (dim_1) int64 0 1 2 3 4 5 6 7 8 9 Data variables: x (dim_0, dim_1) float64 0.0 0.0 0.0 0.0 0.0 ... 4.5 4.5 4.5 4.5 4.5 y (dim_0, dim_1) float64 0.0 0.0 0.0 0.0 0.0 ... -4.5 -4.5 -4.5 -4.5
[ ]: