From 83f33ac8503731d1db65453114c4cd52d449310e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Schnabel?= Date: Tue, 15 Jul 2025 10:07:19 +0200 Subject: [PATCH 1/7] Adding GAMSPy transportation model example as Jupyter notebook --- GAMSPy_integration_example/requirements.txt | 5 + .../trnsport_cuopt.ipynb | 2122 +++++++++++++++++ 2 files changed, 2127 insertions(+) create mode 100644 GAMSPy_integration_example/requirements.txt create mode 100644 GAMSPy_integration_example/trnsport_cuopt.ipynb diff --git a/GAMSPy_integration_example/requirements.txt b/GAMSPy_integration_example/requirements.txt new file mode 100644 index 0000000..bed60df --- /dev/null +++ b/GAMSPy_integration_example/requirements.txt @@ -0,0 +1,5 @@ +cuopt-cu12==25.5.* +nvidia-cuda-runtime-cu12==12.8.* +nvidia-nvjitlink-cu12 +gamspy +jupyter \ No newline at end of file diff --git a/GAMSPy_integration_example/trnsport_cuopt.ipynb b/GAMSPy_integration_example/trnsport_cuopt.ipynb new file mode 100644 index 0000000..69f7e6b --- /dev/null +++ b/GAMSPy_integration_example/trnsport_cuopt.ipynb @@ -0,0 +1,2122 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Quick Start Guide\n", + "\n", + "## cuOpt specific setup\n", + "\n", + "- Activate Python virtual environment with CUDA runtime and GAMSPy installed\n", + " - Install CUDA runtime via `pip install --extra-index-url=https://pypi.nvidia.com cuopt-cu12==25.5.* nvidia-cuda-runtime-cu12==12.8.* nvidia-nvjitlink-cu12`\n", + " - Install GAMSPy via `pip install gamspy`\n", + " - Install Jupyter notebooks via `pip install jupyter`\n", + "- Download latest cuOpt solver link zip archive (`cuopt-link-release.zip`) from the [releases page](https://github.com/GAMS-dev/cuoptlink-builder/releases).\n", + "- Extract archive into GAMS system directory for GAMSPy: `unzip -o cuopt-link-release.zip -d $(gamspy show base)`\n", + "- Run this notebook from a GUI or command line via `jupyter nbconvert --to notebook --execute --inplace trnsport_cuopt.ipynb`\n", + "\n", + "The most relevant lines for the use of `cuopt` below are\n", + "```\n", + "gp.set_options({\"SOLVER_VALIDATION\": 0})\n", + "transport.solve(solver=\"cuopt\", output=sys.stdout)\n", + "```\n", + "\n", + "## Introduction\n", + "\n", + "This quick start guide is designed to provide you with a concise overview of GAMSPy and its key features. By the end of this guide, you'll have a solid understanding of how to create basic mathematical models using GAMSPy. For more advanced features, we recommend exploring our comprehensive [user guide](https://gamspy.readthedocs.io/en/latest/user/index.html) and the extensive [model library](https://gamspy.readthedocs.io/en/latest/user/model_library.html).\n", + "\n", + "While not mandatory, having a basic understanding of Python programming and familiarity with the [Pandas library](https://pandas.pydata.org/). will be helpful in following this tutorial.\n", + "\n", + "## A Transportation Problem\n", + "\n", + "In this guide, we'll delve into an example of the transportation problem. This classic scenario involves managing supplies from various plants to meet demands at multiple markets for a single commodity. Additionally, we have the unit costs associated with shipping the commodity from plants to markets. The fundamental economic question here is: \n", + "\n", + "> How can we optimize the shipment quantities between each plant and market to minimize the total transport cost?\n", + "\n", + "The problem's algebraic representation typically takes the following format:\n", + "\n", + "Indices (Sets):\n", + "\n", + "- $i$ = plants\n", + "- $j$ = markets\n", + "\n", + "Given Data (Parameters):\n", + "\n", + "- $a_i$ = supply of commodity at plant $i$ (in cases)\n", + "- $b_j$ = demand for commodity at market $j$ (in cases)\n", + "- $c_{ij}$ = cost per unit of shipment between plant $i$ and market $j$\n", + "\n", + "Decision Variables:\n", + "\n", + "- $x_{ij}$ = amount of commodity to ship from plant $i$ to market $j$ where $x_{ij} \\ge 0$ for all $i,j$\n", + "\n", + "Constraints:\n", + "\n", + "- Observe supply limit at plant $i$: $\\sum_j x_{ij} \\le a_i \\: \\forall i$\n", + "- Satisfy demand at market $j$: $\\sum_i x_{ij} \\ge b_j \\: \\forall j$\n", + "- Objective Function: Minimize $\\sum_i \\sum_j c_{ij} \\cdot x_{ij}$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data\n", + "\n", + "Before we dive into the optimization process, let's handle our data using the [Pandas library](https://pandas.pydata.org/). We'll begin by organizing the necessary information, which we will subsequently feed into our optimization model." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.115758Z", + "iopub.status.busy": "2025-07-14T13:42:59.115569Z", + "iopub.status.idle": "2025-07-14T13:42:59.277754Z", + "shell.execute_reply": "2025-07-14T13:42:59.277400Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
capacity
city
seattle350
san-diego600
\n", + "
" + ], + "text/plain": [ + " capacity\n", + "city \n", + "seattle 350\n", + "san-diego 600" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "capacities = pd.DataFrame(\n", + " [[\"seattle\", 350], [\"san-diego\", 600]], columns=[\"city\", \"capacity\"]\n", + ").set_index(\"city\")\n", + "\n", + "capacities" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.295572Z", + "iopub.status.busy": "2025-07-14T13:42:59.295411Z", + "iopub.status.idle": "2025-07-14T13:42:59.298803Z", + "shell.execute_reply": "2025-07-14T13:42:59.298562Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
demand
city
new-york325
chicago300
topeka275
\n", + "
" + ], + "text/plain": [ + " demand\n", + "city \n", + "new-york 325\n", + "chicago 300\n", + "topeka 275" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "demands = pd.DataFrame(\n", + " [[\"new-york\", 325], [\"chicago\", 300], [\"topeka\", 275]], columns=[\"city\", \"demand\"]\n", + ").set_index(\"city\")\n", + "\n", + "demands" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.299557Z", + "iopub.status.busy": "2025-07-14T13:42:59.299484Z", + "iopub.status.idle": "2025-07-14T13:42:59.303518Z", + "shell.execute_reply": "2025-07-14T13:42:59.303284Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
distance
fromto
seattlenew-york2.5
chicago1.7
topeka1.8
san-diegonew-york2.5
chicago1.8
topeka1.4
\n", + "
" + ], + "text/plain": [ + " distance\n", + "from to \n", + "seattle new-york 2.5\n", + " chicago 1.7\n", + " topeka 1.8\n", + "san-diego new-york 2.5\n", + " chicago 1.8\n", + " topeka 1.4" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "distances = pd.DataFrame(\n", + " [\n", + " [\"seattle\", \"new-york\", 2.5],\n", + " [\"seattle\", \"chicago\", 1.7],\n", + " [\"seattle\", \"topeka\", 1.8],\n", + " [\"san-diego\", \"new-york\", 2.5],\n", + " [\"san-diego\", \"chicago\", 1.8],\n", + " [\"san-diego\", \"topeka\", 1.4],\n", + " ],\n", + " columns=[\"from\", \"to\", \"distance\"],\n", + ").set_index([\"from\", \"to\"])\n", + "\n", + "distances" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.304235Z", + "iopub.status.busy": "2025-07-14T13:42:59.304104Z", + "iopub.status.idle": "2025-07-14T13:42:59.305565Z", + "shell.execute_reply": "2025-07-14T13:42:59.305329Z" + } + }, + "outputs": [], + "source": [ + "freight_cost = 90" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Symbol Declaration\n", + "\n", + "In line with our systematic breakdown of the transportation problem into sets, parameters, variables, and constraints, we will adopt a similar approach to define the problem as a GAMSPy `Model`. To do so, it is essential to import the `gamspy` library initially." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.306247Z", + "iopub.status.busy": "2025-07-14T13:42:59.306124Z", + "iopub.status.idle": "2025-07-14T13:42:59.373625Z", + "shell.execute_reply": "2025-07-14T13:42:59.373221Z" + } + }, + "outputs": [], + "source": [ + "from gamspy import Container, Set, Parameter, Variable, Equation, Model, Sum, Sense" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Container\n", + "\n", + "Before we proceed further, let's create a `Container` to encapsulate all the relevant information for our GAMSPy ``Model``. This ``Container`` acts as a centralized hub, gathering essential data, sets, parameters, variables, and constraints, providing a clear structure for our optimization problem." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.374745Z", + "iopub.status.busy": "2025-07-14T13:42:59.374669Z", + "iopub.status.idle": "2025-07-14T13:42:59.384854Z", + "shell.execute_reply": "2025-07-14T13:42:59.384606Z" + } + }, + "outputs": [], + "source": [ + "m = Container()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Sets\n", + "\n", + "Sets serve as the fundamental building blocks of a GAMSPy ``Model``, directly corresponding to the indices in the algebraic representations of models. In our transportation problem context, we have defined the following indices:\n", + "\n", + "- $i$ = plants\n", + "- $j$ = markets\n", + "\n", + "For detailed guidance on using sets, please refer to the [set section](https://gamspy.readthedocs.io/en/latest/user/basics/set.html) of our user guide.\n", + "\n", + "There a two ways to declare sets:\n", + "\n", + "1. Separate declaration and data assignment\n", + "2. Combine declaration and data assignment\n", + "\n", + "#### Separate declaration and data assignment\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.385698Z", + "iopub.status.busy": "2025-07-14T13:42:59.385621Z", + "iopub.status.idle": "2025-07-14T13:42:59.391776Z", + "shell.execute_reply": "2025-07-14T13:42:59.391565Z" + } + }, + "outputs": [], + "source": [ + "i = Set(container=m, name=\"i\", description=\"plants\")\n", + "i.setRecords(capacities.index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Combine declaration and data assignment\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.392505Z", + "iopub.status.busy": "2025-07-14T13:42:59.392432Z", + "iopub.status.idle": "2025-07-14T13:42:59.402906Z", + "shell.execute_reply": "2025-07-14T13:42:59.402676Z" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "j = Set(container=m, name=\"j\", description=\"markets\", records=demands.index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The effect of using the above `Set` statements is that we declared two sets, namely $i$ and $j$. Additionally, we provided descriptions to elaborate on their meaning, enhancing the readability of our ``Model``. Lastly, we assigned members to the sets, establishing a clear connection between the abstract sets and their real-world counterparts.\n", + "\n", + "$i$ = {Seattle, San Diego}\n", + "\n", + "$j$ = {New York, Chicago, Topeka}\n", + "\n", + "To verify the content of a set, you can use `.records`." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.403685Z", + "iopub.status.busy": "2025-07-14T13:42:59.403555Z", + "iopub.status.idle": "2025-07-14T13:42:59.406169Z", + "shell.execute_reply": "2025-07-14T13:42:59.406017Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
unielement_text
0seattle
1san-diego
\n", + "
" + ], + "text/plain": [ + " uni element_text\n", + "0 seattle \n", + "1 san-diego " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "i.records" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.406800Z", + "iopub.status.busy": "2025-07-14T13:42:59.406730Z", + "iopub.status.idle": "2025-07-14T13:42:59.408977Z", + "shell.execute_reply": "2025-07-14T13:42:59.408833Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
unielement_text
0new-york
1chicago
2topeka
\n", + "
" + ], + "text/plain": [ + " uni element_text\n", + "0 new-york \n", + "1 chicago \n", + "2 topeka " + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "j.records" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Parameters\n", + "\n", + "Declaring parameters involves using `Parameter`. Each parameter is assigned a name and a description. Note that parameter $a_i$ is indexed by $i$. To accommodate these indices, we include the `domain` attribute, pointing to the corresponding set.\n", + "\n", + "It is worth mentioning that, similar to sets, you have the flexibility to either combine or separate the declaration and data assignment steps. For convenience, we will proceed by combining the declaration and data assignment.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.409712Z", + "iopub.status.busy": "2025-07-14T13:42:59.409586Z", + "iopub.status.idle": "2025-07-14T13:42:59.414511Z", + "shell.execute_reply": "2025-07-14T13:42:59.414358Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cityvalue
0seattle350.0
1san-diego600.0
\n", + "
" + ], + "text/plain": [ + " city value\n", + "0 seattle 350.0\n", + "1 san-diego 600.0" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a = Parameter(\n", + " container=m, \n", + " name=\"a\",\n", + " domain=i,\n", + " description=\"supply of commodity at plant i (in cases)\",\n", + " records=capacities.reset_index(),\n", + ")\n", + "a.records" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.415161Z", + "iopub.status.busy": "2025-07-14T13:42:59.415088Z", + "iopub.status.idle": "2025-07-14T13:42:59.419943Z", + "shell.execute_reply": "2025-07-14T13:42:59.419765Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cityvalue
0new-york325.0
1chicago300.0
2topeka275.0
\n", + "
" + ], + "text/plain": [ + " city value\n", + "0 new-york 325.0\n", + "1 chicago 300.0\n", + "2 topeka 275.0" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b = Parameter(\n", + " container=m,\n", + " name=\"b\",\n", + " domain=j,\n", + " description=\"demand for commodity at market j (in cases)\",\n", + " records=demands.reset_index(),\n", + ")\n", + "b.records" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.420560Z", + "iopub.status.busy": "2025-07-14T13:42:59.420488Z", + "iopub.status.idle": "2025-07-14T13:42:59.422785Z", + "shell.execute_reply": "2025-07-14T13:42:59.422596Z" + } + }, + "outputs": [], + "source": [ + "c = Parameter(\n", + " container=m,\n", + " name=\"c\",\n", + " domain=[i, j],\n", + " description=\"cost per unit of shipment between plant i and market j\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The cost per unit of shipment between plant $i$ and market $j$ is derived from the distance between $i$ and $j$ and can be calculated as follows:\n", + "\n", + "$c_{ij} = \\frac{90 \\cdot d_{ij}}{1000}$,\n", + "\n", + "where $d_{ij}$ denotes the distance between $i$ and $j$.\n", + "\n", + "We have two options to calculate $c_{ij}$ and assign the data to the GAMSPy parameter:\n", + "\n", + "1. Python assignment - calculation in Python, e.g., using Pandas and `.setRecords()`\n", + "2. GAMSPy assignment - calculation in GAMSPy\n", + "\n", + "#### Python Assignment" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.423492Z", + "iopub.status.busy": "2025-07-14T13:42:59.423334Z", + "iopub.status.idle": "2025-07-14T13:42:59.426141Z", + "shell.execute_reply": "2025-07-14T13:42:59.425956Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
distance
fromto
seattlenew-york0.225
chicago0.153
topeka0.162
san-diegonew-york0.225
chicago0.162
topeka0.126
\n", + "
" + ], + "text/plain": [ + " distance\n", + "from to \n", + "seattle new-york 0.225\n", + " chicago 0.153\n", + " topeka 0.162\n", + "san-diego new-york 0.225\n", + " chicago 0.162\n", + " topeka 0.126" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cost = freight_cost * distances / 1000\n", + "cost" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.426713Z", + "iopub.status.busy": "2025-07-14T13:42:59.426642Z", + "iopub.status.idle": "2025-07-14T13:42:59.432248Z", + "shell.execute_reply": "2025-07-14T13:42:59.432069Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
fromtovalue
0seattlenew-york0.225
1seattlechicago0.153
2seattletopeka0.162
3san-diegonew-york0.225
4san-diegochicago0.162
5san-diegotopeka0.126
\n", + "
" + ], + "text/plain": [ + " from to value\n", + "0 seattle new-york 0.225\n", + "1 seattle chicago 0.153\n", + "2 seattle topeka 0.162\n", + "3 san-diego new-york 0.225\n", + "4 san-diego chicago 0.162\n", + "5 san-diego topeka 0.126" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c.setRecords(cost.reset_index())\n", + "c.records" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### GAMSPy Assignment\n", + "\n", + "For the direct assignment we need to declare a new ``Parameter`` denoting the distances between $i$ and $j$.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.433086Z", + "iopub.status.busy": "2025-07-14T13:42:59.432950Z", + "iopub.status.idle": "2025-07-14T13:42:59.438648Z", + "shell.execute_reply": "2025-07-14T13:42:59.438468Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
fromtovalue
0seattlenew-york2.5
1seattlechicago1.7
2seattletopeka1.8
3san-diegonew-york2.5
4san-diegochicago1.8
5san-diegotopeka1.4
\n", + "
" + ], + "text/plain": [ + " from to value\n", + "0 seattle new-york 2.5\n", + "1 seattle chicago 1.7\n", + "2 seattle topeka 1.8\n", + "3 san-diego new-york 2.5\n", + "4 san-diego chicago 1.8\n", + "5 san-diego topeka 1.4" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "d = Parameter(\n", + " container=m,\n", + " name=\"d\",\n", + " domain=[i, j],\n", + " description=\"distance between plant i and market j\",\n", + " records=distances.reset_index(),\n", + ")\n", + "d.records" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.439353Z", + "iopub.status.busy": "2025-07-14T13:42:59.439281Z", + "iopub.status.idle": "2025-07-14T13:42:59.443730Z", + "shell.execute_reply": "2025-07-14T13:42:59.443546Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ijvalue
0seattlenew-york0.225
1seattlechicago0.153
2seattletopeka0.162
3san-diegonew-york0.225
4san-diegochicago0.162
5san-diegotopeka0.126
\n", + "
" + ], + "text/plain": [ + " i j value\n", + "0 seattle new-york 0.225\n", + "1 seattle chicago 0.153\n", + "2 seattle topeka 0.162\n", + "3 san-diego new-york 0.225\n", + "4 san-diego chicago 0.162\n", + "5 san-diego topeka 0.126" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c[i, j] = freight_cost * d[i, j] / 1000\n", + "c.records" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Further information on the usage of parameters can be found in our [parameter section](https://gamspy.readthedocs.io/en/latest/user/basics/parameter.html) of the user guide." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Variables\n", + "\n", + "GAMSPy variables are declared using `Variable`. Each ``Variable`` is assigned a name, a domain if necessary, a type, and, optionally, a description." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.444452Z", + "iopub.status.busy": "2025-07-14T13:42:59.444380Z", + "iopub.status.idle": "2025-07-14T13:42:59.446722Z", + "shell.execute_reply": "2025-07-14T13:42:59.446534Z" + } + }, + "outputs": [], + "source": [ + "x = Variable(\n", + " container=m,\n", + " name=\"x\",\n", + " domain=[i, j],\n", + " type=\"Positive\",\n", + " description=\"amount of commodity to ship from plant i to market j\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This statement results in the declaration of a shipment variable for each (i,j) pair.\n", + "\n", + "More information on variables can be found in the [variable section](https://gamspy.readthedocs.io/en/latest/user/basics/variable.html) of our user guide." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Equations\n", + "A GAMSPy ``Equation`` must be declared and defined in two separate statements. The format of the declaration is the same as for other GAMSPy symbols. First comes the keyword, `Equation` in this case, followed by the name, domain and text. The transportation problem has two constraints:\n", + "\n", + "Supply: observe supply limit at plant $i$: $\\sum_j x_{ij} \\le a_i \\: \\forall i$\n", + "\n", + "Demand: satisfy demand at market $j$: $\\sum_i x_{ij} \\ge b_j \\: \\forall j$" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.447430Z", + "iopub.status.busy": "2025-07-14T13:42:59.447358Z", + "iopub.status.idle": "2025-07-14T13:42:59.450615Z", + "shell.execute_reply": "2025-07-14T13:42:59.450430Z" + } + }, + "outputs": [], + "source": [ + "supply = Equation(\n", + " container=m, name=\"supply\", domain=i, description=\"observe supply limit at plant i\"\n", + ")\n", + "demand = Equation(\n", + " container=m, name=\"demand\", domain=j, description=\"satisfy demand at market j\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The components of an ``Equation`` definition are:\n", + "1. The Python variable of the ``Equation`` being defined\n", + "2. The domain (optional)\n", + "3. Domain restricting conditions (optional)\n", + "4. A `=` sign\n", + "5. Left hand side expression\n", + "6. Relational operator (`==`, `<=`, `>=`)\n", + "7. The right hand side expression.\n", + "\n", + "The ``Equation`` definition for the supply constraint of the transportation problem is implemented as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.451313Z", + "iopub.status.busy": "2025-07-14T13:42:59.451228Z", + "iopub.status.idle": "2025-07-14T13:42:59.453729Z", + "shell.execute_reply": "2025-07-14T13:42:59.453541Z" + } + }, + "outputs": [], + "source": [ + "supply[i] = Sum(j, x[i, j]) <= a[i]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the same logic as above, we can define the demand equation as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.454429Z", + "iopub.status.busy": "2025-07-14T13:42:59.454310Z", + "iopub.status.idle": "2025-07-14T13:42:59.456770Z", + "shell.execute_reply": "2025-07-14T13:42:59.456589Z" + } + }, + "outputs": [], + "source": [ + "demand[j] = Sum(i, x[i, j]) >= b[j]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "More information on equations is given in the [equation section](https://gamspy.readthedocs.io/en/latest/user/basics/equation.html) of our user guide." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Objective\n", + "The objective function of a GAMSPy ``Model`` does not require a separate ``Equation`` declaration. You can assign the objective expression to a Python variable or use it directly in the ``Model()`` statement of the [next section](#model).\n" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.457438Z", + "iopub.status.busy": "2025-07-14T13:42:59.457369Z", + "iopub.status.idle": "2025-07-14T13:42:59.458773Z", + "shell.execute_reply": "2025-07-14T13:42:59.458596Z" + } + }, + "outputs": [], + "source": [ + "obj = Sum((i, j), c[i, j] * x[i, j])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model\n", + "\n", + "A GAMSPy `Model()` consolidates constraints, an objective function, a sense (minimize, maximize, and feasibility), and a problem type. It also possesses a name and is associated with a ``Container``.\n", + "\n", + "To define our transportation problem as a GAMSPy ``Model``, we assign it to a Python variable, link it to our ``Container`` (populated with symbols and data), name it \"transport\", specify the equations, set the problem type as linear program (LP), specify the sense of the objective function (``Sense.MIN``), and point to the objective expression.\n", + "\n", + "GAMSPy allows two alternatives to assign equations to a `Model`:\n", + "1. Using a list of equations,\n", + "2. Retrieving _all_ equations by calling `m.getEquations()`.\n", + "\n", + "### Using a List of Equations\n", + "Using a list of equations is especially useful if you want to define multiple GAMSPy ``Model``s with a subset of the equations in your ``Container``. For the transportation problem this can be done as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.459343Z", + "iopub.status.busy": "2025-07-14T13:42:59.459274Z", + "iopub.status.idle": "2025-07-14T13:42:59.461715Z", + "shell.execute_reply": "2025-07-14T13:42:59.461530Z" + } + }, + "outputs": [], + "source": [ + "transport = Model(\n", + " m,\n", + " name=\"transport\",\n", + " equations=[supply, demand],\n", + " problem=\"LP\",\n", + " sense=Sense.MIN,\n", + " objective=obj,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Retrieving all Equations\n", + "Using `m.getEquations()` is especially convenient if you want to include all equations of your ``Container`` to be associated with your model. For the transportation problem this can be done as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.462312Z", + "iopub.status.busy": "2025-07-14T13:42:59.462243Z", + "iopub.status.idle": "2025-07-14T13:42:59.464611Z", + "shell.execute_reply": "2025-07-14T13:42:59.464425Z" + } + }, + "outputs": [], + "source": [ + "transport_2 = Model(\n", + " m,\n", + " name=\"transport2\",\n", + " equations=m.getEquations(),\n", + " problem=\"LP\",\n", + " sense=Sense.MIN,\n", + " objective=obj,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "More information on the usage of a GAMSPy `Model` can be found in the [model section](https://gamspy.readthedocs.io/en/latest/user/basics/model.html) of our user guide." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solve\n", + "\n", + "Upon defining the GAMSPy ``Model``, it's ready for being solved. The ``solve()`` statement triggers the generation of the specific model instance, creates suitable data structures for the solver, and invokes the solver. To view solver output in the console, the ``sys`` library can be used, passing the ``output=sys.stdout`` attribute to ``transport.solve()``." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.465234Z", + "iopub.status.busy": "2025-07-14T13:42:59.465163Z", + "iopub.status.idle": "2025-07-14T13:42:59.649204Z", + "shell.execute_reply": "2025-07-14T13:42:59.649012Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Job _iryWq_R0QgaJ4suSj9QBhA.gms Start 07/14/25 15:42:59 50.1.0 12b75dde LEX-LEG x86 64bit/Linux\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Applying:\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " /home/gamsuser/andre/venvs/cu-opt/lib/python3.12/site-packages/gamspy_base/gmsprmun.txt\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " /home/gamsuser/andre/venvs/cu-opt/lib/python3.12/site-packages/gamspy_base/gamsconfig.yaml\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- GAMS Parameters defined\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " LP cuopt\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Input /tmp/tmpmdtq7_cf/_iryWq_R0QgaJ4suSj9QBhA.gms\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Output /tmp/tmpmdtq7_cf/_iryWq_R0QgaJ4suSj9QBhA.lst\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " ScrDir /tmp/tmpmdtq7_cf/tmpwqtczygk/\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " SysDir /home/gamsuser/andre/venvs/cu-opt/lib/python3.12/site-packages/gamspy_base/\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " LogOption 3\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Trace /tmp/tmpmdtq7_cf/_iryWq_R0QgaJ4suSj9QBhA.txt\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " License /home/gamsuser/andre/venvs/cu-opt/lib/python3.12/site-packages/gamspy_base/gamslice.txt\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " OptFile 0\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " OptDir /tmp/tmpmdtq7_cf/\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " LimRow 0\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " LimCol 0\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " TraceOpt 3\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " GDX /tmp/tmpmdtq7_cf/_iryWq_R0QgaJ4suSj9QBhAout.gdx\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " SolPrint 0\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " PreviousWork 1\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " gdxSymbols newOrChanged\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "System information: 12 physical cores and 62 Gb physical memory detected\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Starting compilation\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- _iryWq_R0QgaJ4suSj9QBhA.gms(71) 4 Mb\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Starting execution: elapsed 0:00:00.000\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Generating LP model transport\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- _iryWq_R0QgaJ4suSj9QBhA.gms(142) 4 Mb\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- 6 rows 7 columns 19 non-zeroes\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Range statistics (absolute non-zero finite values)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- RHS [min, max] : [ 2.750E+02, 6.000E+02] - Zero values observed as well\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Bound [min, max] : [ NA, NA] - Zero values observed as well\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Matrix [min, max] : [ 1.260E-01, 1.000E+00]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Executing CUOPT (Solvelink=2): elapsed 0:00:00.000\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Setting parameter log_file to /tmp/tmpmdtq7_cf/tmpwqtczygk/cuopt.dat\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Solving a problem with 5 constraints 6 variables (0 integers) and 12 nonzeros\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Objective offset -0.000000 scaling_factor 1.000000\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running concurrent\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dual simplex finished in 0.00 seconds\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Iter Primal Obj. Dual Obj. Gap Primal Res. Dual Res. Time\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 0 +0.00000000e+00 +0.00000000e+00 0.00e+00 5.21e+02 0.00e+00 0.010s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PDLP finished\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Concurrent time: 0.012s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Solved with dual simplex\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Status: Optimal Objective: 1.53675000e+02 Iterations: 4 Time: 0.012s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Reading solution for model transport\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Executing after solve: elapsed 0:00:00.177\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- _iryWq_R0QgaJ4suSj9QBhA.gms(143) 4 Mb\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- _iryWq_R0QgaJ4suSj9QBhA.gms(201) 4 Mb\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- GDX File /tmp/tmpmdtq7_cf/_iryWq_R0QgaJ4suSj9QBhAout.gdx\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "*** Status: Normal completion\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- Job _iryWq_R0QgaJ4suSj9QBhA.gms Stop 07/14/25 15:42:59 elapsed 0:00:00.177\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Solver StatusModel StatusObjectiveNum of EquationsNum of VariablesModel TypeSolverSolver Time
0NormalOptimalGlobal153.67567LPCUOPT0.0
\n", + "
" + ], + "text/plain": [ + " Solver Status Model Status Objective Num of Equations Num of Variables \\\n", + "0 Normal OptimalGlobal 153.675 6 7 \n", + "\n", + " Model Type Solver Solver Time \n", + "0 LP CUOPT 0.0 " + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import sys\n", + "import gamspy as gp\n", + "\n", + "gp.set_options({\"SOLVER_VALIDATION\": 0})\n", + "transport.solve(solver=\"cuopt\", output=sys.stdout)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Retrieving Results\n", + "### Variable Values\n", + "The values of the variables in the solution can be retrieved using using ``.records``. The level specifies the shipment quantities $x_{ij}$. Other variable attributes are the marginal values, lower and upper bounds, and the variable's scaling factor." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.650044Z", + "iopub.status.busy": "2025-07-14T13:42:59.649967Z", + "iopub.status.idle": "2025-07-14T13:42:59.654019Z", + "shell.execute_reply": "2025-07-14T13:42:59.653862Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
levelmarginallowerupperscale
ij
seattlenew-york50.00.00000.0inf1.0
chicago300.00.00000.0inf1.0
topeka0.00.01800.0inf1.0
san-diegonew-york275.00.00000.0inf1.0
chicago0.00.00450.0inf1.0
topeka275.00.00000.0inf1.0
\n", + "
" + ], + "text/plain": [ + " level marginal lower upper scale\n", + "i j \n", + "seattle new-york 50.0 0.0000 0.0 inf 1.0\n", + " chicago 300.0 0.0000 0.0 inf 1.0\n", + " topeka 0.0 0.0180 0.0 inf 1.0\n", + "san-diego new-york 275.0 0.0000 0.0 inf 1.0\n", + " chicago 0.0 0.0045 0.0 inf 1.0\n", + " topeka 275.0 0.0000 0.0 inf 1.0" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x.records.set_index([\"i\", \"j\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Objective Value\n", + "The optimal objective function value can be accessed by `.objective_value`." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-14T13:42:59.654734Z", + "iopub.status.busy": "2025-07-14T13:42:59.654667Z", + "iopub.status.idle": "2025-07-14T13:42:59.656292Z", + "shell.execute_reply": "2025-07-14T13:42:59.656146Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "153.675" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "transport.objective_value" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 6987ac5879cb2353f6b36fdda021219252e54d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Schnabel?= Date: Thu, 17 Jul 2025 10:35:13 +0200 Subject: [PATCH 2/7] Apply/implement suggestions from PR review by @rgsl888prabhu --- GAMSPy_integration_example/README.md | 7 + GAMSPy_integration_example/requirements.txt | 5 - .../trnsport_cuopt.ipynb | 588 ++++++++++++------ 3 files changed, 407 insertions(+), 193 deletions(-) create mode 100644 GAMSPy_integration_example/README.md delete mode 100644 GAMSPy_integration_example/requirements.txt diff --git a/GAMSPy_integration_example/README.md b/GAMSPy_integration_example/README.md new file mode 100644 index 0000000..efbe351 --- /dev/null +++ b/GAMSPy_integration_example/README.md @@ -0,0 +1,7 @@ +## GAMSPy cuOpt integration example notebook + +### How to run the notebook +- Setup and activate a Python environment in the `cuopt-examples` root directory e.g. with `python -m venv .venv` and `source .venv/bin/activate` +- Install requirements `pip install -r requirements.txt` +- Run this notebook from a GUI or update its cells in the command line via `jupyter nbconvert --to notebook --execute --inplace trnsport_cuopt.ipynb` +- The first cell takes care of installing cuOpt runtime, GAMSPy, and the solver link. Skips most parts when it's already there. diff --git a/GAMSPy_integration_example/requirements.txt b/GAMSPy_integration_example/requirements.txt deleted file mode 100644 index bed60df..0000000 --- a/GAMSPy_integration_example/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -cuopt-cu12==25.5.* -nvidia-cuda-runtime-cu12==12.8.* -nvidia-nvjitlink-cu12 -gamspy -jupyter \ No newline at end of file diff --git a/GAMSPy_integration_example/trnsport_cuopt.ipynb b/GAMSPy_integration_example/trnsport_cuopt.ipynb index 69f7e6b..2d6cc88 100644 --- a/GAMSPy_integration_example/trnsport_cuopt.ipynb +++ b/GAMSPy_integration_example/trnsport_cuopt.ipynb @@ -1,26 +1,234 @@ { "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T08:33:52.145801Z", + "iopub.status.busy": "2025-07-17T08:33:52.145494Z", + "iopub.status.idle": "2025-07-17T08:33:57.909182Z", + "shell.execute_reply": "2025-07-17T08:33:57.908917Z" + }, + "vscode": { + "languageId": "shellscript" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Looking in indexes: https://pypi.org/simple, https://pypi.nvidia.com\r\n", + "Requirement already satisfied: cuopt-cu12==25.5.* in ./.venv/lib/python3.12/site-packages (25.5.1)\r\n", + "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.8.* in ./.venv/lib/python3.12/site-packages (12.8.90)\r\n", + "Requirement already satisfied: nvidia-nvjitlink-cu12 in ./.venv/lib/python3.12/site-packages (12.9.86)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: cudf-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: cuopt-mps-parser==25.5.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.5.1)\r\n", + "Requirement already satisfied: cupy-cuda12x in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (13.5.1)\r\n", + "Requirement already satisfied: cuvs-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: libcuopt-cu12==25.5.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.5.1)\r\n", + "Requirement already satisfied: numba<0.61.0a0,>=0.59.1 in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (0.60.0)\r\n", + "Requirement already satisfied: numpy<3.0a0,>=1.23.5 in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (2.0.2)\r\n", + "Requirement already satisfied: pandas<2.2.3dev0,>=2.0 in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (2.2.2)\r\n", + "Requirement already satisfied: pylibraft-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: raft-dask-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: rapids-dask-dependency==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: rapids-logger==0.1.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (0.1.1)\r\n", + "Requirement already satisfied: rmm-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: cachetools in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (6.1.0)\r\n", + "Requirement already satisfied: cuda-python<13.0a0,>=12.6.2 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (12.9.0)\r\n", + "Requirement already satisfied: fsspec>=0.6.0 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (2025.7.0)\r\n", + "Requirement already satisfied: libcudf-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: numba-cuda<0.5.0a0,>=0.4.0 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (0.4.0)\r\n", + "Requirement already satisfied: nvtx>=0.2.1 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (0.2.12)\r\n", + "Requirement already satisfied: packaging in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (25.0)\r\n", + "Requirement already satisfied: pyarrow<20.0.0a0,>=14.0.0 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (19.0.1)\r\n", + "Requirement already satisfied: pylibcudf-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: pynvjitlink-cu12 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (0.7.0)\r\n", + "Requirement already satisfied: rich in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (14.0.0)\r\n", + "Requirement already satisfied: typing_extensions>=4.0.0 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (4.14.1)\r\n", + "Requirement already satisfied: libcuvs-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuvs-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: librmm-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: nvidia-cublas-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (12.9.1.4)\r\n", + "Requirement already satisfied: nvidia-curand-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (10.3.10.19)\r\n", + "Requirement already satisfied: nvidia-cusolver-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (11.7.5.82)\r\n", + "Requirement already satisfied: nvidia-cusparse-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (12.5.10.65)\r\n", + "Requirement already satisfied: nvidia-nvtx-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (12.9.79)\r\n", + "Requirement already satisfied: libraft-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from pylibraft-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: dask-cuda==25.4.* in ./.venv/lib/python3.12/site-packages (from raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: distributed-ucxx-cu12==0.43.* in ./.venv/lib/python3.12/site-packages (from raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (0.43.0)\r\n", + "Requirement already satisfied: ucx-py-cu12==0.43.* in ./.venv/lib/python3.12/site-packages (from raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (0.43.0)\r\n", + "Requirement already satisfied: dask==2025.2.0 in ./.venv/lib/python3.12/site-packages (from rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (2025.2.0)\r\n", + "Requirement already satisfied: distributed==2025.2.0 in ./.venv/lib/python3.12/site-packages (from rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (2025.2.0)\r\n", + "Requirement already satisfied: click>=8.1 in ./.venv/lib/python3.12/site-packages (from dask==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (8.1.8)\r\n", + "Requirement already satisfied: cloudpickle>=3.0.0 in ./.venv/lib/python3.12/site-packages (from dask==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (3.1.1)\r\n", + "Requirement already satisfied: partd>=1.4.0 in ./.venv/lib/python3.12/site-packages (from dask==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (1.4.2)\r\n", + "Requirement already satisfied: pyyaml>=5.3.1 in ./.venv/lib/python3.12/site-packages (from dask==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (6.0.2)\r\n", + "Requirement already satisfied: toolz>=0.10.0 in ./.venv/lib/python3.12/site-packages (from dask==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (1.0.0)\r\n", + "Requirement already satisfied: pynvml<13.0.0a0,>=12.0.0 in ./.venv/lib/python3.12/site-packages (from dask-cuda==25.4.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (12.0.0)\r\n", + "Requirement already satisfied: zict>=2.0.0 in ./.venv/lib/python3.12/site-packages (from dask-cuda==25.4.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (3.0.0)\r\n", + "Requirement already satisfied: jinja2>=2.10.3 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (3.1.6)\r\n", + "Requirement already satisfied: locket>=1.0.0 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (1.0.0)\r\n", + "Requirement already satisfied: msgpack>=1.0.2 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (1.1.1)\r\n", + "Requirement already satisfied: psutil>=5.8.0 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (7.0.0)\r\n", + "Requirement already satisfied: sortedcontainers>=2.0.5 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (2.4.0)\r\n", + "Requirement already satisfied: tblib>=1.6.0 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (3.1.0)\r\n", + "Requirement already satisfied: tornado>=6.2.0 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (6.5.1)\r\n", + "Requirement already satisfied: urllib3>=1.26.5 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (2.5.0)\r\n", + "Requirement already satisfied: ucxx-cu12==0.43.* in ./.venv/lib/python3.12/site-packages (from distributed-ucxx-cu12==0.43.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (0.43.0)\r\n", + "Requirement already satisfied: libkvikio-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from libcudf-cu12==25.4.*->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: nvidia-nvcomp-cu12==4.2.0.11 in ./.venv/lib/python3.12/site-packages (from libcudf-cu12==25.4.*->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (4.2.0.11)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: libucx-cu12<1.19,>=1.15.0 in ./.venv/lib/python3.12/site-packages (from ucx-py-cu12==0.43.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (1.18.1)\r\n", + "Requirement already satisfied: libucxx-cu12==0.43.* in ./.venv/lib/python3.12/site-packages (from ucxx-cu12==0.43.*->distributed-ucxx-cu12==0.43.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (0.43.0)\r\n", + "Requirement already satisfied: fastrlock>=0.5 in ./.venv/lib/python3.12/site-packages (from cupy-cuda12x->cuopt-cu12==25.5.*) (0.8.3)\r\n", + "Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in ./.venv/lib/python3.12/site-packages (from numba<0.61.0a0,>=0.59.1->cuopt-cu12==25.5.*) (0.43.0)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: python-dateutil>=2.8.2 in ./.venv/lib/python3.12/site-packages (from pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (2.9.0.post0)\r\n", + "Requirement already satisfied: pytz>=2020.1 in ./.venv/lib/python3.12/site-packages (from pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (2025.2)\r\n", + "Requirement already satisfied: tzdata>=2022.7 in ./.venv/lib/python3.12/site-packages (from pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (2025.2)\r\n", + "Requirement already satisfied: cuda-bindings~=12.9.0 in ./.venv/lib/python3.12/site-packages (from cuda-python<13.0a0,>=12.6.2->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (12.9.0)\r\n", + "Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (1.17.0)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: markdown-it-py>=2.2.0 in ./.venv/lib/python3.12/site-packages (from rich->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (3.0.0)\r\n", + "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in ./.venv/lib/python3.12/site-packages (from rich->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (2.19.2)\r\n", + "Requirement already satisfied: MarkupSafe>=2.0 in ./.venv/lib/python3.12/site-packages (from jinja2>=2.10.3->distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (3.0.2)\r\n", + "Requirement already satisfied: mdurl~=0.1 in ./.venv/lib/python3.12/site-packages (from markdown-it-py>=2.2.0->rich->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (0.1.2)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: nvidia-ml-py<13.0.0a0,>=12.0.0 in ./.venv/lib/python3.12/site-packages (from pynvml<13.0.0a0,>=12.0.0->dask-cuda==25.4.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (12.575.51)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: gamspy in ./.venv/lib/python3.12/site-packages (1.13.0)\r\n", + "Requirement already satisfied: gamsapi==50.2.0 in ./.venv/lib/python3.12/site-packages (from gamsapi[transfer]==50.2.0->gamspy) (50.2.0)\r\n", + "Requirement already satisfied: gamspy_base==50.2.0 in ./.venv/lib/python3.12/site-packages (from gamspy) (50.2.0)\r\n", + "Requirement already satisfied: pydantic>=2.0 in ./.venv/lib/python3.12/site-packages (from gamspy) (2.11.7)\r\n", + "Requirement already satisfied: certifi>=2022.09.14 in ./.venv/lib/python3.12/site-packages (from gamspy) (2025.7.14)\r\n", + "Requirement already satisfied: urllib3>=2.0.7 in ./.venv/lib/python3.12/site-packages (from gamspy) (2.5.0)\r\n", + "Requirement already satisfied: typer>=0.15.1 in ./.venv/lib/python3.12/site-packages (from gamspy) (0.16.0)\r\n", + "Requirement already satisfied: click<8.2.0 in ./.venv/lib/python3.12/site-packages (from gamspy) (8.1.8)\r\n", + "Requirement already satisfied: pandas<2.3,>=2.0 in ./.venv/lib/python3.12/site-packages (from gamsapi[transfer]==50.2.0->gamspy) (2.2.2)\r\n", + "Requirement already satisfied: scipy in ./.venv/lib/python3.12/site-packages (from gamsapi[transfer]==50.2.0->gamspy) (1.16.0)\r\n", + "Requirement already satisfied: annotated-types>=0.6.0 in ./.venv/lib/python3.12/site-packages (from pydantic>=2.0->gamspy) (0.7.0)\r\n", + "Requirement already satisfied: pydantic-core==2.33.2 in ./.venv/lib/python3.12/site-packages (from pydantic>=2.0->gamspy) (2.33.2)\r\n", + "Requirement already satisfied: typing-extensions>=4.12.2 in ./.venv/lib/python3.12/site-packages (from pydantic>=2.0->gamspy) (4.14.1)\r\n", + "Requirement already satisfied: typing-inspection>=0.4.0 in ./.venv/lib/python3.12/site-packages (from pydantic>=2.0->gamspy) (0.4.1)\r\n", + "Requirement already satisfied: shellingham>=1.3.0 in ./.venv/lib/python3.12/site-packages (from typer>=0.15.1->gamspy) (1.5.4)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: rich>=10.11.0 in ./.venv/lib/python3.12/site-packages (from typer>=0.15.1->gamspy) (14.0.0)\r\n", + "Requirement already satisfied: numpy>=1.26.0 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2.0.2)\r\n", + "Requirement already satisfied: python-dateutil>=2.8.2 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2.9.0.post0)\r\n", + "Requirement already satisfied: pytz>=2020.1 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2025.2)\r\n", + "Requirement already satisfied: tzdata>=2022.7 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2025.2)\r\n", + "Requirement already satisfied: markdown-it-py>=2.2.0 in ./.venv/lib/python3.12/site-packages (from rich>=10.11.0->typer>=0.15.1->gamspy) (3.0.0)\r\n", + "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in ./.venv/lib/python3.12/site-packages (from rich>=10.11.0->typer>=0.15.1->gamspy) (2.19.2)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: mdurl~=0.1 in ./.venv/lib/python3.12/site-packages (from markdown-it-py>=2.2.0->rich>=10.11.0->typer>=0.15.1->gamspy) (0.1.2)\r\n", + "Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (1.17.0)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "File ‘cuopt-link-release.zip’ already there; not retrieving.\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Archive: cuopt-link-release.zip\n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libcuopt.so " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmscuopt.out \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libgomp-5fc1ad8c.so.1.0.0 \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/librapids_logger.so \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libmps_parser.so \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmscuopt.run \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gamsconfig.yaml \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/optcuopt.def \n" + ] + }, + { + "data": { + "text/plain": [ + "CompletedProcess(args='unzip -o cuopt-link-release.zip -d /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base', returncode=0)" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "!pip install --extra-index-url=https://pypi.nvidia.com cuopt-cu12==25.5.* nvidia-cuda-runtime-cu12==12.8.* nvidia-nvjitlink-cu12\n", + "!pip install gamspy\n", + "import subprocess\n", + "import sys\n", + "# TODO: replace with stable binary URL of most recent link build archive from https://github.com/GAMS-dev/cuoptlink-builder/releases when cuoptlink-builder repository was made public!\n", + "!wget -nc -O cuopt-link-release.zip \"https://cloud.gams.com/s/s7daRy8WDMXK5cQ/download/gmscuopt.zip\"\n", + "gams_base_path = subprocess.check_output([sys.executable, '-m', 'gamspy', 'show', 'base']).decode('utf-8').strip()\n", + "subprocess.run(f\"unzip -o cuopt-link-release.zip -d {gams_base_path}\", shell=True, check=True)" + ] + }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# Quick Start Guide\n", - "\n", - "## cuOpt specific setup\n", - "\n", - "- Activate Python virtual environment with CUDA runtime and GAMSPy installed\n", - " - Install CUDA runtime via `pip install --extra-index-url=https://pypi.nvidia.com cuopt-cu12==25.5.* nvidia-cuda-runtime-cu12==12.8.* nvidia-nvjitlink-cu12`\n", - " - Install GAMSPy via `pip install gamspy`\n", - " - Install Jupyter notebooks via `pip install jupyter`\n", - "- Download latest cuOpt solver link zip archive (`cuopt-link-release.zip`) from the [releases page](https://github.com/GAMS-dev/cuoptlink-builder/releases).\n", - "- Extract archive into GAMS system directory for GAMSPy: `unzip -o cuopt-link-release.zip -d $(gamspy show base)`\n", - "- Run this notebook from a GUI or command line via `jupyter nbconvert --to notebook --execute --inplace trnsport_cuopt.ipynb`\n", - "\n", - "The most relevant lines for the use of `cuopt` below are\n", - "```\n", - "gp.set_options({\"SOLVER_VALIDATION\": 0})\n", - "transport.solve(solver=\"cuopt\", output=sys.stdout)\n", - "```\n", + "# GAMSPy model example\n", "\n", "## Introduction\n", "\n", @@ -69,13 +277,13 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.115758Z", - "iopub.status.busy": "2025-07-14T13:42:59.115569Z", - "iopub.status.idle": "2025-07-14T13:42:59.277754Z", - "shell.execute_reply": "2025-07-14T13:42:59.277400Z" + "iopub.execute_input": "2025-07-17T08:33:57.910163Z", + "iopub.status.busy": "2025-07-17T08:33:57.910077Z", + "iopub.status.idle": "2025-07-17T08:33:58.072963Z", + "shell.execute_reply": "2025-07-17T08:33:58.072753Z" } }, "outputs": [ @@ -127,7 +335,7 @@ "san-diego 600" ] }, - "execution_count": 1, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -144,13 +352,13 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.295572Z", - "iopub.status.busy": "2025-07-14T13:42:59.295411Z", - "iopub.status.idle": "2025-07-14T13:42:59.298803Z", - "shell.execute_reply": "2025-07-14T13:42:59.298562Z" + "iopub.execute_input": "2025-07-17T08:33:58.073814Z", + "iopub.status.busy": "2025-07-17T08:33:58.073704Z", + "iopub.status.idle": "2025-07-17T08:33:58.076510Z", + "shell.execute_reply": "2025-07-17T08:33:58.076338Z" } }, "outputs": [ @@ -207,7 +415,7 @@ "topeka 275" ] }, - "execution_count": 2, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -222,13 +430,13 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.299557Z", - "iopub.status.busy": "2025-07-14T13:42:59.299484Z", - "iopub.status.idle": "2025-07-14T13:42:59.303518Z", - "shell.execute_reply": "2025-07-14T13:42:59.303284Z" + "iopub.execute_input": "2025-07-17T08:33:58.077143Z", + "iopub.status.busy": "2025-07-17T08:33:58.077074Z", + "iopub.status.idle": "2025-07-17T08:33:58.080921Z", + "shell.execute_reply": "2025-07-17T08:33:58.080758Z" } }, "outputs": [ @@ -304,7 +512,7 @@ " topeka 1.4" ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -327,13 +535,13 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.304235Z", - "iopub.status.busy": "2025-07-14T13:42:59.304104Z", - "iopub.status.idle": "2025-07-14T13:42:59.305565Z", - "shell.execute_reply": "2025-07-14T13:42:59.305329Z" + "iopub.execute_input": "2025-07-17T08:33:58.081597Z", + "iopub.status.busy": "2025-07-17T08:33:58.081479Z", + "iopub.status.idle": "2025-07-17T08:33:58.082794Z", + "shell.execute_reply": "2025-07-17T08:33:58.082634Z" } }, "outputs": [], @@ -352,13 +560,13 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.306247Z", - "iopub.status.busy": "2025-07-14T13:42:59.306124Z", - "iopub.status.idle": "2025-07-14T13:42:59.373625Z", - "shell.execute_reply": "2025-07-14T13:42:59.373221Z" + "iopub.execute_input": "2025-07-17T08:33:58.083473Z", + "iopub.status.busy": "2025-07-17T08:33:58.083360Z", + "iopub.status.idle": "2025-07-17T08:33:58.150364Z", + "shell.execute_reply": "2025-07-17T08:33:58.150084Z" } }, "outputs": [], @@ -377,13 +585,13 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.374745Z", - "iopub.status.busy": "2025-07-14T13:42:59.374669Z", - "iopub.status.idle": "2025-07-14T13:42:59.384854Z", - "shell.execute_reply": "2025-07-14T13:42:59.384606Z" + "iopub.execute_input": "2025-07-17T08:33:58.151332Z", + "iopub.status.busy": "2025-07-17T08:33:58.151260Z", + "iopub.status.idle": "2025-07-17T08:33:58.159584Z", + "shell.execute_reply": "2025-07-17T08:33:58.159407Z" } }, "outputs": [], @@ -414,13 +622,13 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.385698Z", - "iopub.status.busy": "2025-07-14T13:42:59.385621Z", - "iopub.status.idle": "2025-07-14T13:42:59.391776Z", - "shell.execute_reply": "2025-07-14T13:42:59.391565Z" + "iopub.execute_input": "2025-07-17T08:33:58.160434Z", + "iopub.status.busy": "2025-07-17T08:33:58.160296Z", + "iopub.status.idle": "2025-07-17T08:33:58.166806Z", + "shell.execute_reply": "2025-07-17T08:33:58.166639Z" } }, "outputs": [], @@ -438,13 +646,13 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.392505Z", - "iopub.status.busy": "2025-07-14T13:42:59.392432Z", - "iopub.status.idle": "2025-07-14T13:42:59.402906Z", - "shell.execute_reply": "2025-07-14T13:42:59.402676Z" + "iopub.execute_input": "2025-07-17T08:33:58.167536Z", + "iopub.status.busy": "2025-07-17T08:33:58.167465Z", + "iopub.status.idle": "2025-07-17T08:33:58.177760Z", + "shell.execute_reply": "2025-07-17T08:33:58.177570Z" }, "tags": [] }, @@ -468,13 +676,13 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.403685Z", - "iopub.status.busy": "2025-07-14T13:42:59.403555Z", - "iopub.status.idle": "2025-07-14T13:42:59.406169Z", - "shell.execute_reply": "2025-07-14T13:42:59.406017Z" + "iopub.execute_input": "2025-07-17T08:33:58.178484Z", + "iopub.status.busy": "2025-07-17T08:33:58.178411Z", + "iopub.status.idle": "2025-07-17T08:33:58.180926Z", + "shell.execute_reply": "2025-07-17T08:33:58.180767Z" } }, "outputs": [ @@ -524,7 +732,7 @@ "1 san-diego " ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -535,13 +743,13 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.406800Z", - "iopub.status.busy": "2025-07-14T13:42:59.406730Z", - "iopub.status.idle": "2025-07-14T13:42:59.408977Z", - "shell.execute_reply": "2025-07-14T13:42:59.408833Z" + "iopub.execute_input": "2025-07-17T08:33:58.181703Z", + "iopub.status.busy": "2025-07-17T08:33:58.181543Z", + "iopub.status.idle": "2025-07-17T08:33:58.183963Z", + "shell.execute_reply": "2025-07-17T08:33:58.183801Z" } }, "outputs": [ @@ -597,7 +805,7 @@ "2 topeka " ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -619,13 +827,13 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.409712Z", - "iopub.status.busy": "2025-07-14T13:42:59.409586Z", - "iopub.status.idle": "2025-07-14T13:42:59.414511Z", - "shell.execute_reply": "2025-07-14T13:42:59.414358Z" + "iopub.execute_input": "2025-07-17T08:33:58.184751Z", + "iopub.status.busy": "2025-07-17T08:33:58.184596Z", + "iopub.status.idle": "2025-07-17T08:33:58.189606Z", + "shell.execute_reply": "2025-07-17T08:33:58.189439Z" } }, "outputs": [ @@ -675,7 +883,7 @@ "1 san-diego 600.0" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -693,13 +901,13 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.415161Z", - "iopub.status.busy": "2025-07-14T13:42:59.415088Z", - "iopub.status.idle": "2025-07-14T13:42:59.419943Z", - "shell.execute_reply": "2025-07-14T13:42:59.419765Z" + "iopub.execute_input": "2025-07-17T08:33:58.190341Z", + "iopub.status.busy": "2025-07-17T08:33:58.190220Z", + "iopub.status.idle": "2025-07-17T08:33:58.194950Z", + "shell.execute_reply": "2025-07-17T08:33:58.194796Z" } }, "outputs": [ @@ -755,7 +963,7 @@ "2 topeka 275.0" ] }, - "execution_count": 12, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -773,13 +981,13 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.420560Z", - "iopub.status.busy": "2025-07-14T13:42:59.420488Z", - "iopub.status.idle": "2025-07-14T13:42:59.422785Z", - "shell.execute_reply": "2025-07-14T13:42:59.422596Z" + "iopub.execute_input": "2025-07-17T08:33:58.195688Z", + "iopub.status.busy": "2025-07-17T08:33:58.195570Z", + "iopub.status.idle": "2025-07-17T08:33:58.197839Z", + "shell.execute_reply": "2025-07-17T08:33:58.197685Z" } }, "outputs": [], @@ -812,13 +1020,13 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.423492Z", - "iopub.status.busy": "2025-07-14T13:42:59.423334Z", - "iopub.status.idle": "2025-07-14T13:42:59.426141Z", - "shell.execute_reply": "2025-07-14T13:42:59.425956Z" + "iopub.execute_input": "2025-07-17T08:33:58.198576Z", + "iopub.status.busy": "2025-07-17T08:33:58.198459Z", + "iopub.status.idle": "2025-07-17T08:33:58.201186Z", + "shell.execute_reply": "2025-07-17T08:33:58.201022Z" } }, "outputs": [ @@ -894,7 +1102,7 @@ " topeka 0.126" ] }, - "execution_count": 14, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -906,13 +1114,13 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.426713Z", - "iopub.status.busy": "2025-07-14T13:42:59.426642Z", - "iopub.status.idle": "2025-07-14T13:42:59.432248Z", - "shell.execute_reply": "2025-07-14T13:42:59.432069Z" + "iopub.execute_input": "2025-07-17T08:33:58.201890Z", + "iopub.status.busy": "2025-07-17T08:33:58.201776Z", + "iopub.status.idle": "2025-07-17T08:33:58.207383Z", + "shell.execute_reply": "2025-07-17T08:33:58.207177Z" } }, "outputs": [ @@ -993,7 +1201,7 @@ "5 san-diego topeka 0.126" ] }, - "execution_count": 15, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -1014,13 +1222,13 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.433086Z", - "iopub.status.busy": "2025-07-14T13:42:59.432950Z", - "iopub.status.idle": "2025-07-14T13:42:59.438648Z", - "shell.execute_reply": "2025-07-14T13:42:59.438468Z" + "iopub.execute_input": "2025-07-17T08:33:58.208050Z", + "iopub.status.busy": "2025-07-17T08:33:58.207974Z", + "iopub.status.idle": "2025-07-17T08:33:58.213469Z", + "shell.execute_reply": "2025-07-17T08:33:58.213303Z" } }, "outputs": [ @@ -1101,7 +1309,7 @@ "5 san-diego topeka 1.4" ] }, - "execution_count": 16, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -1119,13 +1327,13 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.439353Z", - "iopub.status.busy": "2025-07-14T13:42:59.439281Z", - "iopub.status.idle": "2025-07-14T13:42:59.443730Z", - "shell.execute_reply": "2025-07-14T13:42:59.443546Z" + "iopub.execute_input": "2025-07-17T08:33:58.214063Z", + "iopub.status.busy": "2025-07-17T08:33:58.213988Z", + "iopub.status.idle": "2025-07-17T08:33:58.218574Z", + "shell.execute_reply": "2025-07-17T08:33:58.218386Z" } }, "outputs": [ @@ -1206,7 +1414,7 @@ "5 san-diego topeka 0.126" ] }, - "execution_count": 17, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -1234,13 +1442,13 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.444452Z", - "iopub.status.busy": "2025-07-14T13:42:59.444380Z", - "iopub.status.idle": "2025-07-14T13:42:59.446722Z", - "shell.execute_reply": "2025-07-14T13:42:59.446534Z" + "iopub.execute_input": "2025-07-17T08:33:58.219236Z", + "iopub.status.busy": "2025-07-17T08:33:58.219120Z", + "iopub.status.idle": "2025-07-17T08:33:58.221597Z", + "shell.execute_reply": "2025-07-17T08:33:58.221413Z" } }, "outputs": [], @@ -1277,13 +1485,13 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.447430Z", - "iopub.status.busy": "2025-07-14T13:42:59.447358Z", - "iopub.status.idle": "2025-07-14T13:42:59.450615Z", - "shell.execute_reply": "2025-07-14T13:42:59.450430Z" + "iopub.execute_input": "2025-07-17T08:33:58.222296Z", + "iopub.status.busy": "2025-07-17T08:33:58.222225Z", + "iopub.status.idle": "2025-07-17T08:33:58.225613Z", + "shell.execute_reply": "2025-07-17T08:33:58.225422Z" } }, "outputs": [], @@ -1314,13 +1522,13 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.451313Z", - "iopub.status.busy": "2025-07-14T13:42:59.451228Z", - "iopub.status.idle": "2025-07-14T13:42:59.453729Z", - "shell.execute_reply": "2025-07-14T13:42:59.453541Z" + "iopub.execute_input": "2025-07-17T08:33:58.226267Z", + "iopub.status.busy": "2025-07-17T08:33:58.226195Z", + "iopub.status.idle": "2025-07-17T08:33:58.228902Z", + "shell.execute_reply": "2025-07-17T08:33:58.228717Z" } }, "outputs": [], @@ -1337,13 +1545,13 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.454429Z", - "iopub.status.busy": "2025-07-14T13:42:59.454310Z", - "iopub.status.idle": "2025-07-14T13:42:59.456770Z", - "shell.execute_reply": "2025-07-14T13:42:59.456589Z" + "iopub.execute_input": "2025-07-17T08:33:58.229618Z", + "iopub.status.busy": "2025-07-17T08:33:58.229494Z", + "iopub.status.idle": "2025-07-17T08:33:58.232093Z", + "shell.execute_reply": "2025-07-17T08:33:58.231900Z" } }, "outputs": [], @@ -1368,13 +1576,13 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 23, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.457438Z", - "iopub.status.busy": "2025-07-14T13:42:59.457369Z", - "iopub.status.idle": "2025-07-14T13:42:59.458773Z", - "shell.execute_reply": "2025-07-14T13:42:59.458596Z" + "iopub.execute_input": "2025-07-17T08:33:58.232756Z", + "iopub.status.busy": "2025-07-17T08:33:58.232644Z", + "iopub.status.idle": "2025-07-17T08:33:58.234054Z", + "shell.execute_reply": "2025-07-17T08:33:58.233866Z" } }, "outputs": [], @@ -1402,13 +1610,13 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 24, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.459343Z", - "iopub.status.busy": "2025-07-14T13:42:59.459274Z", - "iopub.status.idle": "2025-07-14T13:42:59.461715Z", - "shell.execute_reply": "2025-07-14T13:42:59.461530Z" + "iopub.execute_input": "2025-07-17T08:33:58.234786Z", + "iopub.status.busy": "2025-07-17T08:33:58.234636Z", + "iopub.status.idle": "2025-07-17T08:33:58.237178Z", + "shell.execute_reply": "2025-07-17T08:33:58.237016Z" } }, "outputs": [], @@ -1433,13 +1641,13 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 25, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.462312Z", - "iopub.status.busy": "2025-07-14T13:42:59.462243Z", - "iopub.status.idle": "2025-07-14T13:42:59.464611Z", - "shell.execute_reply": "2025-07-14T13:42:59.464425Z" + "iopub.execute_input": "2025-07-17T08:33:58.237768Z", + "iopub.status.busy": "2025-07-17T08:33:58.237697Z", + "iopub.status.idle": "2025-07-17T08:33:58.239997Z", + "shell.execute_reply": "2025-07-17T08:33:58.239843Z" } }, "outputs": [], @@ -1467,18 +1675,22 @@ "source": [ "## Solve\n", "\n", - "Upon defining the GAMSPy ``Model``, it's ready for being solved. The ``solve()`` statement triggers the generation of the specific model instance, creates suitable data structures for the solver, and invokes the solver. To view solver output in the console, the ``sys`` library can be used, passing the ``output=sys.stdout`` attribute to ``transport.solve()``." + "Upon defining the GAMSPy ``Model``, it's ready for being solved. The ``solve()`` statement triggers the generation of the specific model instance, creates suitable data structures for the solver, and invokes the solver. To view solver output in the console, the ``sys`` library can be used, passing the ``output=sys.stdout`` attribute to ``transport.solve()``.\n", + "\n", + "**Note**: The following cell contains the two most important pieces to get a GAMSPy model being solved by NVIDIA cuOpt:\n", + "1. Disable solver validation via `gp.set_options({\"SOLVER_VALIDATION\": 0})` as the solver is manually \"plugged into\" GAMSPy\n", + "2. Choose cuOpt as solver with `transport.solve(solver=\"cuopt\", ...)`" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 26, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.465234Z", - "iopub.status.busy": "2025-07-14T13:42:59.465163Z", - "iopub.status.idle": "2025-07-14T13:42:59.649204Z", - "shell.execute_reply": "2025-07-14T13:42:59.649012Z" + "iopub.execute_input": "2025-07-17T08:33:58.240591Z", + "iopub.status.busy": "2025-07-17T08:33:58.240526Z", + "iopub.status.idle": "2025-07-17T08:33:58.428515Z", + "shell.execute_reply": "2025-07-17T08:33:58.428313Z" } }, "outputs": [ @@ -1486,7 +1698,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- Job _iryWq_R0QgaJ4suSj9QBhA.gms Start 07/14/25 15:42:59 50.1.0 12b75dde LEX-LEG x86 64bit/Linux\n" + "--- Job _tn9S3jlwQzattJUcoVv92g.gms Start 07/17/25 10:33:58 50.2.0 d60bb663 LEX-LEG x86 64bit/Linux\n" ] }, { @@ -1500,14 +1712,14 @@ "name": "stdout", "output_type": "stream", "text": [ - " /home/gamsuser/andre/venvs/cu-opt/lib/python3.12/site-packages/gamspy_base/gmsprmun.txt\n" + " /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmsprmun.txt\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - " /home/gamsuser/andre/venvs/cu-opt/lib/python3.12/site-packages/gamspy_base/gamsconfig.yaml\n" + " /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gamsconfig.yaml\n" ] }, { @@ -1528,28 +1740,28 @@ "name": "stdout", "output_type": "stream", "text": [ - " Input /tmp/tmpmdtq7_cf/_iryWq_R0QgaJ4suSj9QBhA.gms\n" + " Input /tmp/tmpbbq4gnul/_tn9S3jlwQzattJUcoVv92g.gms\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - " Output /tmp/tmpmdtq7_cf/_iryWq_R0QgaJ4suSj9QBhA.lst\n" + " Output /tmp/tmpbbq4gnul/_tn9S3jlwQzattJUcoVv92g.lst\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - " ScrDir /tmp/tmpmdtq7_cf/tmpwqtczygk/\n" + " ScrDir /tmp/tmpbbq4gnul/tmprfsw4u8c/\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - " SysDir /home/gamsuser/andre/venvs/cu-opt/lib/python3.12/site-packages/gamspy_base/\n" + " SysDir /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/\n" ] }, { @@ -1563,14 +1775,14 @@ "name": "stdout", "output_type": "stream", "text": [ - " Trace /tmp/tmpmdtq7_cf/_iryWq_R0QgaJ4suSj9QBhA.txt\n" + " Trace /tmp/tmpbbq4gnul/_tn9S3jlwQzattJUcoVv92g.txt\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - " License /home/gamsuser/andre/venvs/cu-opt/lib/python3.12/site-packages/gamspy_base/gamslice.txt\n" + " License /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gamslice.txt\n" ] }, { @@ -1584,7 +1796,7 @@ "name": "stdout", "output_type": "stream", "text": [ - " OptDir /tmp/tmpmdtq7_cf/\n" + " OptDir /tmp/tmpbbq4gnul/\n" ] }, { @@ -1612,7 +1824,7 @@ "name": "stdout", "output_type": "stream", "text": [ - " GDX /tmp/tmpmdtq7_cf/_iryWq_R0QgaJ4suSj9QBhAout.gdx\n" + " GDX /tmp/tmpbbq4gnul/_tn9S3jlwQzattJUcoVv92gout.gdx\n" ] }, { @@ -1654,7 +1866,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- _iryWq_R0QgaJ4suSj9QBhA.gms(71) 4 Mb\n" + "--- _tn9S3jlwQzattJUcoVv92g.gms(71) 4 Mb\n" ] }, { @@ -1675,7 +1887,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- _iryWq_R0QgaJ4suSj9QBhA.gms(142) 4 Mb\n" + "--- _tn9S3jlwQzattJUcoVv92g.gms(142) 4 Mb\n" ] }, { @@ -1717,14 +1929,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- Executing CUOPT (Solvelink=2): elapsed 0:00:00.000\n" + "--- Executing CUOPT (Solvelink=2): elapsed 0:00:00.001\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Setting parameter log_file to /tmp/tmpmdtq7_cf/tmpwqtczygk/cuopt.dat\n" + "Setting parameter log_file to /tmp/tmpbbq4gnul/tmprfsw4u8c/cuopt.dat\n" ] }, { @@ -1815,28 +2027,28 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- Executing after solve: elapsed 0:00:00.177\n" + "--- Executing after solve: elapsed 0:00:00.181\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "--- _iryWq_R0QgaJ4suSj9QBhA.gms(143) 4 Mb\n" + "--- _tn9S3jlwQzattJUcoVv92g.gms(143) 4 Mb\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "--- _iryWq_R0QgaJ4suSj9QBhA.gms(201) 4 Mb\n" + "--- _tn9S3jlwQzattJUcoVv92g.gms(201) 4 Mb\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "--- GDX File /tmp/tmpmdtq7_cf/_iryWq_R0QgaJ4suSj9QBhAout.gdx\n" + "--- GDX File /tmp/tmpbbq4gnul/_tn9S3jlwQzattJUcoVv92gout.gdx\n" ] }, { @@ -1850,7 +2062,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- Job _iryWq_R0QgaJ4suSj9QBhA.gms Stop 07/14/25 15:42:59 elapsed 0:00:00.177\n" + "--- Job _tn9S3jlwQzattJUcoVv92g.gms Stop 07/17/25 10:33:58 elapsed 0:00:00.181\n" ] }, { @@ -1908,7 +2120,7 @@ "0 LP CUOPT 0.0 " ] }, - "execution_count": 25, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -1932,13 +2144,13 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 27, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.650044Z", - "iopub.status.busy": "2025-07-14T13:42:59.649967Z", - "iopub.status.idle": "2025-07-14T13:42:59.654019Z", - "shell.execute_reply": "2025-07-14T13:42:59.653862Z" + "iopub.execute_input": "2025-07-17T08:33:58.429392Z", + "iopub.status.busy": "2025-07-17T08:33:58.429292Z", + "iopub.status.idle": "2025-07-17T08:33:58.434189Z", + "shell.execute_reply": "2025-07-17T08:33:58.434017Z" } }, "outputs": [ @@ -2046,7 +2258,7 @@ " topeka 275.0 0.0000 0.0 inf 1.0" ] }, - "execution_count": 26, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -2072,13 +2284,13 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 28, "metadata": { "execution": { - "iopub.execute_input": "2025-07-14T13:42:59.654734Z", - "iopub.status.busy": "2025-07-14T13:42:59.654667Z", - "iopub.status.idle": "2025-07-14T13:42:59.656292Z", - "shell.execute_reply": "2025-07-14T13:42:59.656146Z" + "iopub.execute_input": "2025-07-17T08:33:58.434873Z", + "iopub.status.busy": "2025-07-17T08:33:58.434803Z", + "iopub.status.idle": "2025-07-17T08:33:58.436417Z", + "shell.execute_reply": "2025-07-17T08:33:58.436250Z" } }, "outputs": [ @@ -2088,7 +2300,7 @@ "153.675" ] }, - "execution_count": 27, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -2100,7 +2312,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, From d72f9c43e15e3c23075a81b96879009039c1e41b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Schnabel?= Date: Thu, 17 Jul 2025 12:23:04 +0200 Subject: [PATCH 3/7] Updated URL for cuopt-link-release.zip archive --- .../trnsport_cuopt.ipynb | 870 ++++++++++++++---- 1 file changed, 709 insertions(+), 161 deletions(-) diff --git a/GAMSPy_integration_example/trnsport_cuopt.ipynb b/GAMSPy_integration_example/trnsport_cuopt.ipynb index 2d6cc88..8dd7e17 100644 --- a/GAMSPy_integration_example/trnsport_cuopt.ipynb +++ b/GAMSPy_integration_example/trnsport_cuopt.ipynb @@ -5,10 +5,10 @@ "execution_count": 1, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:52.145801Z", - "iopub.status.busy": "2025-07-17T08:33:52.145494Z", - "iopub.status.idle": "2025-07-17T08:33:57.909182Z", - "shell.execute_reply": "2025-07-17T08:33:57.908917Z" + "iopub.execute_input": "2025-07-17T10:21:15.883029Z", + "iopub.status.busy": "2025-07-17T10:21:15.882854Z", + "iopub.status.idle": "2025-07-17T10:21:40.914508Z", + "shell.execute_reply": "2025-07-17T10:21:40.914244Z" }, "vscode": { "languageId": "shellscript" @@ -22,13 +22,7 @@ "Looking in indexes: https://pypi.org/simple, https://pypi.nvidia.com\r\n", "Requirement already satisfied: cuopt-cu12==25.5.* in ./.venv/lib/python3.12/site-packages (25.5.1)\r\n", "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.8.* in ./.venv/lib/python3.12/site-packages (12.8.90)\r\n", - "Requirement already satisfied: nvidia-nvjitlink-cu12 in ./.venv/lib/python3.12/site-packages (12.9.86)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ + "Requirement already satisfied: nvidia-nvjitlink-cu12 in ./.venv/lib/python3.12/site-packages (12.9.86)\r\n", "Requirement already satisfied: cudf-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", "Requirement already satisfied: cuopt-mps-parser==25.5.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.5.1)\r\n", "Requirement already satisfied: cupy-cuda12x in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (13.5.1)\r\n", @@ -54,7 +48,13 @@ "Requirement already satisfied: pynvjitlink-cu12 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (0.7.0)\r\n", "Requirement already satisfied: rich in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (14.0.0)\r\n", "Requirement already satisfied: typing_extensions>=4.0.0 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (4.14.1)\r\n", - "Requirement already satisfied: libcuvs-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuvs-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", + "Requirement already satisfied: libcuvs-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuvs-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ "Requirement already satisfied: librmm-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", "Requirement already satisfied: nvidia-cublas-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (12.9.1.4)\r\n", "Requirement already satisfied: nvidia-curand-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (10.3.10.19)\r\n", @@ -62,13 +62,7 @@ "Requirement already satisfied: nvidia-cusparse-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (12.5.10.65)\r\n", "Requirement already satisfied: nvidia-nvtx-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (12.9.79)\r\n", "Requirement already satisfied: libraft-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from pylibraft-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: dask-cuda==25.4.* in ./.venv/lib/python3.12/site-packages (from raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ + "Requirement already satisfied: dask-cuda==25.4.* in ./.venv/lib/python3.12/site-packages (from raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", "Requirement already satisfied: distributed-ucxx-cu12==0.43.* in ./.venv/lib/python3.12/site-packages (from raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (0.43.0)\r\n", "Requirement already satisfied: ucx-py-cu12==0.43.* in ./.venv/lib/python3.12/site-packages (from raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (0.43.0)\r\n", "Requirement already satisfied: dask==2025.2.0 in ./.venv/lib/python3.12/site-packages (from rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (2025.2.0)\r\n", @@ -110,24 +104,24 @@ "Requirement already satisfied: python-dateutil>=2.8.2 in ./.venv/lib/python3.12/site-packages (from pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (2.9.0.post0)\r\n", "Requirement already satisfied: pytz>=2020.1 in ./.venv/lib/python3.12/site-packages (from pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (2025.2)\r\n", "Requirement already satisfied: tzdata>=2022.7 in ./.venv/lib/python3.12/site-packages (from pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (2025.2)\r\n", - "Requirement already satisfied: cuda-bindings~=12.9.0 in ./.venv/lib/python3.12/site-packages (from cuda-python<13.0a0,>=12.6.2->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (12.9.0)\r\n", - "Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (1.17.0)\r\n" + "Requirement already satisfied: cuda-bindings~=12.9.0 in ./.venv/lib/python3.12/site-packages (from cuda-python<13.0a0,>=12.6.2->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (12.9.0)\r\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ + "Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (1.17.0)\r\n", "Requirement already satisfied: markdown-it-py>=2.2.0 in ./.venv/lib/python3.12/site-packages (from rich->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (3.0.0)\r\n", "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in ./.venv/lib/python3.12/site-packages (from rich->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (2.19.2)\r\n", - "Requirement already satisfied: MarkupSafe>=2.0 in ./.venv/lib/python3.12/site-packages (from jinja2>=2.10.3->distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (3.0.2)\r\n", - "Requirement already satisfied: mdurl~=0.1 in ./.venv/lib/python3.12/site-packages (from markdown-it-py>=2.2.0->rich->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (0.1.2)\r\n" + "Requirement already satisfied: MarkupSafe>=2.0 in ./.venv/lib/python3.12/site-packages (from jinja2>=2.10.3->distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (3.0.2)\r\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ + "Requirement already satisfied: mdurl~=0.1 in ./.venv/lib/python3.12/site-packages (from markdown-it-py>=2.2.0->rich->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (0.1.2)\r\n", "Requirement already satisfied: nvidia-ml-py<13.0.0a0,>=12.0.0 in ./.venv/lib/python3.12/site-packages (from pynvml<13.0.0a0,>=12.0.0->dask-cuda==25.4.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (12.575.51)\r\n" ] }, @@ -135,7 +129,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "Requirement already satisfied: gamspy in ./.venv/lib/python3.12/site-packages (1.13.0)\r\n", + "Requirement already satisfied: gamspy in ./.venv/lib/python3.12/site-packages (1.13.0)\r\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ "Requirement already satisfied: gamsapi==50.2.0 in ./.venv/lib/python3.12/site-packages (from gamsapi[transfer]==50.2.0->gamspy) (50.2.0)\r\n", "Requirement already satisfied: gamspy_base==50.2.0 in ./.venv/lib/python3.12/site-packages (from gamspy) (50.2.0)\r\n", "Requirement already satisfied: pydantic>=2.0 in ./.venv/lib/python3.12/site-packages (from gamspy) (2.11.7)\r\n", @@ -149,27 +149,27 @@ "Requirement already satisfied: pydantic-core==2.33.2 in ./.venv/lib/python3.12/site-packages (from pydantic>=2.0->gamspy) (2.33.2)\r\n", "Requirement already satisfied: typing-extensions>=4.12.2 in ./.venv/lib/python3.12/site-packages (from pydantic>=2.0->gamspy) (4.14.1)\r\n", "Requirement already satisfied: typing-inspection>=0.4.0 in ./.venv/lib/python3.12/site-packages (from pydantic>=2.0->gamspy) (0.4.1)\r\n", - "Requirement already satisfied: shellingham>=1.3.0 in ./.venv/lib/python3.12/site-packages (from typer>=0.15.1->gamspy) (1.5.4)\r\n" + "Requirement already satisfied: shellingham>=1.3.0 in ./.venv/lib/python3.12/site-packages (from typer>=0.15.1->gamspy) (1.5.4)\r\n", + "Requirement already satisfied: rich>=10.11.0 in ./.venv/lib/python3.12/site-packages (from typer>=0.15.1->gamspy) (14.0.0)\r\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Requirement already satisfied: rich>=10.11.0 in ./.venv/lib/python3.12/site-packages (from typer>=0.15.1->gamspy) (14.0.0)\r\n", "Requirement already satisfied: numpy>=1.26.0 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2.0.2)\r\n", "Requirement already satisfied: python-dateutil>=2.8.2 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2.9.0.post0)\r\n", "Requirement already satisfied: pytz>=2020.1 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2025.2)\r\n", "Requirement already satisfied: tzdata>=2022.7 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2025.2)\r\n", "Requirement already satisfied: markdown-it-py>=2.2.0 in ./.venv/lib/python3.12/site-packages (from rich>=10.11.0->typer>=0.15.1->gamspy) (3.0.0)\r\n", - "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in ./.venv/lib/python3.12/site-packages (from rich>=10.11.0->typer>=0.15.1->gamspy) (2.19.2)\r\n" + "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in ./.venv/lib/python3.12/site-packages (from rich>=10.11.0->typer>=0.15.1->gamspy) (2.19.2)\r\n", + "Requirement already satisfied: mdurl~=0.1 in ./.venv/lib/python3.12/site-packages (from markdown-it-py>=2.2.0->rich>=10.11.0->typer>=0.15.1->gamspy) (0.1.2)\r\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Requirement already satisfied: mdurl~=0.1 in ./.venv/lib/python3.12/site-packages (from markdown-it-py>=2.2.0->rich>=10.11.0->typer>=0.15.1->gamspy) (0.1.2)\r\n", "Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (1.17.0)\r\n" ] }, @@ -177,7 +177,556 @@ "name": "stdout", "output_type": "stream", "text": [ - "File ‘cuopt-link-release.zip’ already there; not retrieving.\r\n" + "--2025-07-17 12:21:17-- https://github.com/GAMS-dev/cuoptlink-builder/releases/download/v0.0.1/cuopt-link-release.zip\r\n", + "Resolving github.com (github.com)... 140.82.121.3\r\n", + "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\r\n", + "HTTP request sent, awaiting response... " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "302 Found\r\n", + "Location: https://release-assets.githubusercontent.com/github-production-release-asset/1019451854/6023761c-9183-44e0-9c95-63a83ca98902?sp=r&sv=2018-11-09&sr=b&spr=https&se=2025-07-17T11%3A09%3A20Z&rscd=attachment%3B+filename%3Dcuopt-link-release.zip&rsct=application%2Foctet-stream&skoid=96c2d410-5711-43a1-aedd-ab1947aa7ab0&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skt=2025-07-17T10%3A09%3A16Z&ske=2025-07-17T11%3A09%3A20Z&sks=b&skv=2018-11-09&sig=GrgDPXO3FVyE%2BEOfo5Rs2KEw%2Fefmsi9nT5HONbwdOOo%3D&jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmVsZWFzZS1hc3NldHMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwia2V5Ijoia2V5MSIsImV4cCI6MTc1Mjc0Nzk3OCwibmJmIjoxNzUyNzQ3Njc4LCJwYXRoIjoicmVsZWFzZWFzc2V0cHJvZHVjdGlvbi5ibG9iLmNvcmUud2luZG93cy5uZXQifQ.64DdDTPBHy4pxV7_n7aWUb6LI6rpVSOc4_dnj0LaDC8&response-content-disposition=attachment%3B%20filename%3Dcuopt-link-release.zip&response-content-type=application%2Foctet-stream [following]\r\n", + "--2025-07-17 12:21:18-- https://release-assets.githubusercontent.com/github-production-release-asset/1019451854/6023761c-9183-44e0-9c95-63a83ca98902?sp=r&sv=2018-11-09&sr=b&spr=https&se=2025-07-17T11%3A09%3A20Z&rscd=attachment%3B+filename%3Dcuopt-link-release.zip&rsct=application%2Foctet-stream&skoid=96c2d410-5711-43a1-aedd-ab1947aa7ab0&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skt=2025-07-17T10%3A09%3A16Z&ske=2025-07-17T11%3A09%3A20Z&sks=b&skv=2018-11-09&sig=GrgDPXO3FVyE%2BEOfo5Rs2KEw%2Fefmsi9nT5HONbwdOOo%3D&jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmVsZWFzZS1hc3NldHMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwia2V5Ijoia2V5MSIsImV4cCI6MTc1Mjc0Nzk3OCwibmJmIjoxNzUyNzQ3Njc4LCJwYXRoIjoicmVsZWFzZWFzc2V0cHJvZHVjdGlvbi5ibG9iLmNvcmUud2luZG93cy5uZXQifQ.64DdDTPBHy4pxV7_n7aWUb6LI6rpVSOc4_dnj0LaDC8&response-content-disposition=attachment%3B%20filename%3Dcuopt-link-release.zip&response-content-type=application%2Foctet-stream\r\n", + "Resolving release-assets.githubusercontent.com (release-assets.githubusercontent.com)... 185.199.111.133, 185.199.109.133, 185.199.110.133, ...\r\n", + "Connecting to release-assets.githubusercontent.com (release-assets.githubusercontent.com)|185.199.111.133|:443... " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "connected.\r\n", + "HTTP request sent, awaiting response... " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "200 OK\r\n", + "Length: 449652025 (429M) [application/octet-stream]\r\n", + "Saving to: ‘cuopt-link-release.zip’\r\n", + "\r\n", + "\r", + "cuopt-link-release. 0%[ ] 0 --.-KB/s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 1%[ ] 4.54M 22.6MB/s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 2%[ ] 10.02M 16.3MB/s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 4%[ ] 20.02M 19.5MB/s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 6%[> ] 29.76M 24.3MB/s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 7%[> ] 30.33M 21.2MB/s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 7%[> ] 33.16M 20.3MB/s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 9%[> ] 40.02M 20.3MB/s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 11%[=> ] 50.00M 23.0MB/s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 12%[=> ] 52.23M 22.0MB/s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 13%[=> ] 60.02M 22.1MB/s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 16%[==> ] 70.02M 23.0MB/s eta 16s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 18%[==> ] 80.02M 23.3MB/s eta 16s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 20%[===> ] 90.02M 23.7MB/s eta 16s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 23%[===> ] 100.02M 23.9MB/s eta 14s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 25%[====> ] 110.02M 24.8MB/s eta 14s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 27%[====> ] 120.02M 25.0MB/s eta 14s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 30%[=====> ] 130.00M 26.6MB/s eta 12s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 32%[=====> ] 139.89M 28.2MB/s eta 12s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 33%[=====> ] 143.97M 28.1MB/s eta 12s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 34%[=====> ] 150.02M 27.5MB/s eta 12s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 37%[======> ] 160.01M 27.8MB/s eta 11s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 37%[======> ] 161.34M 25.7MB/s eta 11s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 39%[======> ] 167.96M 26.6MB/s eta 11s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 39%[======> ] 170.67M 24.9MB/s eta 11s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 41%[=======> ] 180.02M 25.3MB/s eta 11s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 44%[=======> ] 189.14M 27.1MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 44%[=======> ] 190.02M 25.0MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 46%[========> ] 199.94M 26.9MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 46%[========> ] 200.02M 24.5MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 48%[========> ] 210.02M 22.7MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 49%[========> ] 212.37M 22.9MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 50%[=========> ] 215.04M 21.4MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 50%[=========> ] 217.78M 21.5MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 51%[=========> ] 220.02M 19.5MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 53%[=========> ] 227.33M 19.2MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 53%[=========> ] 230.02M 19.3MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 55%[==========> ] 240.02M 18.6MB/s eta 9s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 58%[==========> ] 250.02M 19.5MB/s eta 8s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 60%[===========> ] 257.44M 20.1MB/s eta 8s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 60%[===========> ] 260.02M 18.7MB/s eta 8s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 62%[===========> ] 270.02M 18.3MB/s eta 8s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 65%[============> ] 280.02M 18.5MB/s eta 7s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 67%[============> ] 290.00M 18.5MB/s eta 7s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 68%[============> ] 294.19M 20.3MB/s eta 7s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 69%[============> ] 300.02M 20.5MB/s eta 7s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 72%[=============> ] 310.02M 21.7MB/s eta 5s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 74%[=============> ] 320.02M 23.1MB/s eta 5s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 76%[==============> ] 330.02M 23.0MB/s eta 5s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 78%[==============> ] 335.66M 24.6MB/s eta 5s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 78%[==============> ] 336.02M 22.1MB/s eta 4s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 79%[==============> ] 341.17M 23.4MB/s eta 4s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 81%[===============> ] 350.02M 23.8MB/s eta 4s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 82%[===============> ] 355.05M 22.8MB/s eta 4s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 83%[===============> ] 360.02M 23.5MB/s eta 3s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 86%[================> ] 370.02M 23.4MB/s eta 3s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 87%[================> ] 373.60M 22.0MB/s eta 3s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 88%[================> ] 377.65M 22.8MB/s eta 3s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 88%[================> ] 380.02M 21.6MB/s eta 2s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 90%[=================> ] 387.33M 23.1MB/s eta 2s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 90%[=================> ] 390.02M 21.4MB/s eta 2s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 93%[=================> ] 400.02M 21.5MB/s eta 2s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 95%[==================> ] 410.02M 21.6MB/s eta 1s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 97%[==================> ] 420.02M 22.7MB/s eta 1s " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\r", + "cuopt-link-release. 100%[===================>] 428.82M 25.3MB/s in 18s \r\n", + "\r\n", + "2025-07-17 12:21:36 (23.3 MB/s) - ‘cuopt-link-release.zip’ saved [449652025/449652025]\r\n", + "\r\n" ] }, { @@ -185,6 +734,12 @@ "output_type": "stream", "text": [ "Archive: cuopt-link-release.zip\n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/librapids_logger.so \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gamsconfig.yaml \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libgomp-5fc1ad8c.so.1.0.0 \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmscuopt.run \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmscuopt.out \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libmps_parser.so \n", " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libcuopt.so " ] }, @@ -193,12 +748,6 @@ "output_type": "stream", "text": [ "\n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmscuopt.out \n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libgomp-5fc1ad8c.so.1.0.0 \n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/librapids_logger.so \n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libmps_parser.so \n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmscuopt.run \n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gamsconfig.yaml \n", " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/optcuopt.def \n" ] }, @@ -218,8 +767,7 @@ "!pip install gamspy\n", "import subprocess\n", "import sys\n", - "# TODO: replace with stable binary URL of most recent link build archive from https://github.com/GAMS-dev/cuoptlink-builder/releases when cuoptlink-builder repository was made public!\n", - "!wget -nc -O cuopt-link-release.zip \"https://cloud.gams.com/s/s7daRy8WDMXK5cQ/download/gmscuopt.zip\"\n", + "!wget -nc -O cuopt-link-release.zip \"https://github.com/GAMS-dev/cuoptlink-builder/releases/download/v0.0.1/cuopt-link-release.zip\"\n", "gams_base_path = subprocess.check_output([sys.executable, '-m', 'gamspy', 'show', 'base']).decode('utf-8').strip()\n", "subprocess.run(f\"unzip -o cuopt-link-release.zip -d {gams_base_path}\", shell=True, check=True)" ] @@ -280,10 +828,10 @@ "execution_count": 2, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:57.910163Z", - "iopub.status.busy": "2025-07-17T08:33:57.910077Z", - "iopub.status.idle": "2025-07-17T08:33:58.072963Z", - "shell.execute_reply": "2025-07-17T08:33:58.072753Z" + "iopub.execute_input": "2025-07-17T10:21:40.915536Z", + "iopub.status.busy": "2025-07-17T10:21:40.915457Z", + "iopub.status.idle": "2025-07-17T10:21:41.083438Z", + "shell.execute_reply": "2025-07-17T10:21:41.083230Z" } }, "outputs": [ @@ -355,10 +903,10 @@ "execution_count": 3, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.073814Z", - "iopub.status.busy": "2025-07-17T08:33:58.073704Z", - "iopub.status.idle": "2025-07-17T08:33:58.076510Z", - "shell.execute_reply": "2025-07-17T08:33:58.076338Z" + "iopub.execute_input": "2025-07-17T10:21:41.084284Z", + "iopub.status.busy": "2025-07-17T10:21:41.084168Z", + "iopub.status.idle": "2025-07-17T10:21:41.086987Z", + "shell.execute_reply": "2025-07-17T10:21:41.086797Z" } }, "outputs": [ @@ -433,10 +981,10 @@ "execution_count": 4, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.077143Z", - "iopub.status.busy": "2025-07-17T08:33:58.077074Z", - "iopub.status.idle": "2025-07-17T08:33:58.080921Z", - "shell.execute_reply": "2025-07-17T08:33:58.080758Z" + "iopub.execute_input": "2025-07-17T10:21:41.087770Z", + "iopub.status.busy": "2025-07-17T10:21:41.087633Z", + "iopub.status.idle": "2025-07-17T10:21:41.091517Z", + "shell.execute_reply": "2025-07-17T10:21:41.091358Z" } }, "outputs": [ @@ -538,10 +1086,10 @@ "execution_count": 5, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.081597Z", - "iopub.status.busy": "2025-07-17T08:33:58.081479Z", - "iopub.status.idle": "2025-07-17T08:33:58.082794Z", - "shell.execute_reply": "2025-07-17T08:33:58.082634Z" + "iopub.execute_input": "2025-07-17T10:21:41.092111Z", + "iopub.status.busy": "2025-07-17T10:21:41.092042Z", + "iopub.status.idle": "2025-07-17T10:21:41.093337Z", + "shell.execute_reply": "2025-07-17T10:21:41.093174Z" } }, "outputs": [], @@ -563,10 +1111,10 @@ "execution_count": 6, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.083473Z", - "iopub.status.busy": "2025-07-17T08:33:58.083360Z", - "iopub.status.idle": "2025-07-17T08:33:58.150364Z", - "shell.execute_reply": "2025-07-17T08:33:58.150084Z" + "iopub.execute_input": "2025-07-17T10:21:41.093948Z", + "iopub.status.busy": "2025-07-17T10:21:41.093881Z", + "iopub.status.idle": "2025-07-17T10:21:41.163655Z", + "shell.execute_reply": "2025-07-17T10:21:41.163440Z" } }, "outputs": [], @@ -588,10 +1136,10 @@ "execution_count": 7, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.151332Z", - "iopub.status.busy": "2025-07-17T08:33:58.151260Z", - "iopub.status.idle": "2025-07-17T08:33:58.159584Z", - "shell.execute_reply": "2025-07-17T08:33:58.159407Z" + "iopub.execute_input": "2025-07-17T10:21:41.164784Z", + "iopub.status.busy": "2025-07-17T10:21:41.164605Z", + "iopub.status.idle": "2025-07-17T10:21:41.172679Z", + "shell.execute_reply": "2025-07-17T10:21:41.172515Z" } }, "outputs": [], @@ -625,10 +1173,10 @@ "execution_count": 8, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.160434Z", - "iopub.status.busy": "2025-07-17T08:33:58.160296Z", - "iopub.status.idle": "2025-07-17T08:33:58.166806Z", - "shell.execute_reply": "2025-07-17T08:33:58.166639Z" + "iopub.execute_input": "2025-07-17T10:21:41.173454Z", + "iopub.status.busy": "2025-07-17T10:21:41.173302Z", + "iopub.status.idle": "2025-07-17T10:21:41.179619Z", + "shell.execute_reply": "2025-07-17T10:21:41.179429Z" } }, "outputs": [], @@ -649,10 +1197,10 @@ "execution_count": 9, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.167536Z", - "iopub.status.busy": "2025-07-17T08:33:58.167465Z", - "iopub.status.idle": "2025-07-17T08:33:58.177760Z", - "shell.execute_reply": "2025-07-17T08:33:58.177570Z" + "iopub.execute_input": "2025-07-17T10:21:41.180411Z", + "iopub.status.busy": "2025-07-17T10:21:41.180278Z", + "iopub.status.idle": "2025-07-17T10:21:41.190480Z", + "shell.execute_reply": "2025-07-17T10:21:41.190323Z" }, "tags": [] }, @@ -679,10 +1227,10 @@ "execution_count": 10, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.178484Z", - "iopub.status.busy": "2025-07-17T08:33:58.178411Z", - "iopub.status.idle": "2025-07-17T08:33:58.180926Z", - "shell.execute_reply": "2025-07-17T08:33:58.180767Z" + "iopub.execute_input": "2025-07-17T10:21:41.191227Z", + "iopub.status.busy": "2025-07-17T10:21:41.191108Z", + "iopub.status.idle": "2025-07-17T10:21:41.193520Z", + "shell.execute_reply": "2025-07-17T10:21:41.193371Z" } }, "outputs": [ @@ -746,10 +1294,10 @@ "execution_count": 11, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.181703Z", - "iopub.status.busy": "2025-07-17T08:33:58.181543Z", - "iopub.status.idle": "2025-07-17T08:33:58.183963Z", - "shell.execute_reply": "2025-07-17T08:33:58.183801Z" + "iopub.execute_input": "2025-07-17T10:21:41.194209Z", + "iopub.status.busy": "2025-07-17T10:21:41.194141Z", + "iopub.status.idle": "2025-07-17T10:21:41.196323Z", + "shell.execute_reply": "2025-07-17T10:21:41.196172Z" } }, "outputs": [ @@ -830,10 +1378,10 @@ "execution_count": 12, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.184751Z", - "iopub.status.busy": "2025-07-17T08:33:58.184596Z", - "iopub.status.idle": "2025-07-17T08:33:58.189606Z", - "shell.execute_reply": "2025-07-17T08:33:58.189439Z" + "iopub.execute_input": "2025-07-17T10:21:41.196997Z", + "iopub.status.busy": "2025-07-17T10:21:41.196933Z", + "iopub.status.idle": "2025-07-17T10:21:41.201694Z", + "shell.execute_reply": "2025-07-17T10:21:41.201542Z" } }, "outputs": [ @@ -904,10 +1452,10 @@ "execution_count": 13, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.190341Z", - "iopub.status.busy": "2025-07-17T08:33:58.190220Z", - "iopub.status.idle": "2025-07-17T08:33:58.194950Z", - "shell.execute_reply": "2025-07-17T08:33:58.194796Z" + "iopub.execute_input": "2025-07-17T10:21:41.202335Z", + "iopub.status.busy": "2025-07-17T10:21:41.202270Z", + "iopub.status.idle": "2025-07-17T10:21:41.206850Z", + "shell.execute_reply": "2025-07-17T10:21:41.206694Z" } }, "outputs": [ @@ -984,10 +1532,10 @@ "execution_count": 14, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.195688Z", - "iopub.status.busy": "2025-07-17T08:33:58.195570Z", - "iopub.status.idle": "2025-07-17T08:33:58.197839Z", - "shell.execute_reply": "2025-07-17T08:33:58.197685Z" + "iopub.execute_input": "2025-07-17T10:21:41.207532Z", + "iopub.status.busy": "2025-07-17T10:21:41.207468Z", + "iopub.status.idle": "2025-07-17T10:21:41.209778Z", + "shell.execute_reply": "2025-07-17T10:21:41.209610Z" } }, "outputs": [], @@ -1023,10 +1571,10 @@ "execution_count": 15, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.198576Z", - "iopub.status.busy": "2025-07-17T08:33:58.198459Z", - "iopub.status.idle": "2025-07-17T08:33:58.201186Z", - "shell.execute_reply": "2025-07-17T08:33:58.201022Z" + "iopub.execute_input": "2025-07-17T10:21:41.210541Z", + "iopub.status.busy": "2025-07-17T10:21:41.210390Z", + "iopub.status.idle": "2025-07-17T10:21:41.213168Z", + "shell.execute_reply": "2025-07-17T10:21:41.213001Z" } }, "outputs": [ @@ -1117,10 +1665,10 @@ "execution_count": 16, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.201890Z", - "iopub.status.busy": "2025-07-17T08:33:58.201776Z", - "iopub.status.idle": "2025-07-17T08:33:58.207383Z", - "shell.execute_reply": "2025-07-17T08:33:58.207177Z" + "iopub.execute_input": "2025-07-17T10:21:41.213745Z", + "iopub.status.busy": "2025-07-17T10:21:41.213681Z", + "iopub.status.idle": "2025-07-17T10:21:41.218945Z", + "shell.execute_reply": "2025-07-17T10:21:41.218784Z" } }, "outputs": [ @@ -1225,10 +1773,10 @@ "execution_count": 17, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.208050Z", - "iopub.status.busy": "2025-07-17T08:33:58.207974Z", - "iopub.status.idle": "2025-07-17T08:33:58.213469Z", - "shell.execute_reply": "2025-07-17T08:33:58.213303Z" + "iopub.execute_input": "2025-07-17T10:21:41.219662Z", + "iopub.status.busy": "2025-07-17T10:21:41.219599Z", + "iopub.status.idle": "2025-07-17T10:21:41.225144Z", + "shell.execute_reply": "2025-07-17T10:21:41.224999Z" } }, "outputs": [ @@ -1330,10 +1878,10 @@ "execution_count": 18, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.214063Z", - "iopub.status.busy": "2025-07-17T08:33:58.213988Z", - "iopub.status.idle": "2025-07-17T08:33:58.218574Z", - "shell.execute_reply": "2025-07-17T08:33:58.218386Z" + "iopub.execute_input": "2025-07-17T10:21:41.225778Z", + "iopub.status.busy": "2025-07-17T10:21:41.225715Z", + "iopub.status.idle": "2025-07-17T10:21:41.230168Z", + "shell.execute_reply": "2025-07-17T10:21:41.229995Z" } }, "outputs": [ @@ -1445,10 +1993,10 @@ "execution_count": 19, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.219236Z", - "iopub.status.busy": "2025-07-17T08:33:58.219120Z", - "iopub.status.idle": "2025-07-17T08:33:58.221597Z", - "shell.execute_reply": "2025-07-17T08:33:58.221413Z" + "iopub.execute_input": "2025-07-17T10:21:41.230884Z", + "iopub.status.busy": "2025-07-17T10:21:41.230819Z", + "iopub.status.idle": "2025-07-17T10:21:41.233170Z", + "shell.execute_reply": "2025-07-17T10:21:41.233016Z" } }, "outputs": [], @@ -1488,10 +2036,10 @@ "execution_count": 20, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.222296Z", - "iopub.status.busy": "2025-07-17T08:33:58.222225Z", - "iopub.status.idle": "2025-07-17T08:33:58.225613Z", - "shell.execute_reply": "2025-07-17T08:33:58.225422Z" + "iopub.execute_input": "2025-07-17T10:21:41.233875Z", + "iopub.status.busy": "2025-07-17T10:21:41.233798Z", + "iopub.status.idle": "2025-07-17T10:21:41.237181Z", + "shell.execute_reply": "2025-07-17T10:21:41.237005Z" } }, "outputs": [], @@ -1525,10 +2073,10 @@ "execution_count": 21, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.226267Z", - "iopub.status.busy": "2025-07-17T08:33:58.226195Z", - "iopub.status.idle": "2025-07-17T08:33:58.228902Z", - "shell.execute_reply": "2025-07-17T08:33:58.228717Z" + "iopub.execute_input": "2025-07-17T10:21:41.237863Z", + "iopub.status.busy": "2025-07-17T10:21:41.237785Z", + "iopub.status.idle": "2025-07-17T10:21:41.240437Z", + "shell.execute_reply": "2025-07-17T10:21:41.240285Z" } }, "outputs": [], @@ -1548,10 +2096,10 @@ "execution_count": 22, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.229618Z", - "iopub.status.busy": "2025-07-17T08:33:58.229494Z", - "iopub.status.idle": "2025-07-17T08:33:58.232093Z", - "shell.execute_reply": "2025-07-17T08:33:58.231900Z" + "iopub.execute_input": "2025-07-17T10:21:41.241111Z", + "iopub.status.busy": "2025-07-17T10:21:41.241033Z", + "iopub.status.idle": "2025-07-17T10:21:41.243421Z", + "shell.execute_reply": "2025-07-17T10:21:41.243270Z" } }, "outputs": [], @@ -1579,10 +2127,10 @@ "execution_count": 23, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.232756Z", - "iopub.status.busy": "2025-07-17T08:33:58.232644Z", - "iopub.status.idle": "2025-07-17T08:33:58.234054Z", - "shell.execute_reply": "2025-07-17T08:33:58.233866Z" + "iopub.execute_input": "2025-07-17T10:21:41.244117Z", + "iopub.status.busy": "2025-07-17T10:21:41.244038Z", + "iopub.status.idle": "2025-07-17T10:21:41.245432Z", + "shell.execute_reply": "2025-07-17T10:21:41.245247Z" } }, "outputs": [], @@ -1613,10 +2161,10 @@ "execution_count": 24, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.234786Z", - "iopub.status.busy": "2025-07-17T08:33:58.234636Z", - "iopub.status.idle": "2025-07-17T08:33:58.237178Z", - "shell.execute_reply": "2025-07-17T08:33:58.237016Z" + "iopub.execute_input": "2025-07-17T10:21:41.246093Z", + "iopub.status.busy": "2025-07-17T10:21:41.246032Z", + "iopub.status.idle": "2025-07-17T10:21:41.248358Z", + "shell.execute_reply": "2025-07-17T10:21:41.248217Z" } }, "outputs": [], @@ -1644,10 +2192,10 @@ "execution_count": 25, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.237768Z", - "iopub.status.busy": "2025-07-17T08:33:58.237697Z", - "iopub.status.idle": "2025-07-17T08:33:58.239997Z", - "shell.execute_reply": "2025-07-17T08:33:58.239843Z" + "iopub.execute_input": "2025-07-17T10:21:41.248970Z", + "iopub.status.busy": "2025-07-17T10:21:41.248907Z", + "iopub.status.idle": "2025-07-17T10:21:41.251180Z", + "shell.execute_reply": "2025-07-17T10:21:41.251016Z" } }, "outputs": [], @@ -1687,10 +2235,10 @@ "execution_count": 26, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.240591Z", - "iopub.status.busy": "2025-07-17T08:33:58.240526Z", - "iopub.status.idle": "2025-07-17T08:33:58.428515Z", - "shell.execute_reply": "2025-07-17T08:33:58.428313Z" + "iopub.execute_input": "2025-07-17T10:21:41.251912Z", + "iopub.status.busy": "2025-07-17T10:21:41.251772Z", + "iopub.status.idle": "2025-07-17T10:21:41.453729Z", + "shell.execute_reply": "2025-07-17T10:21:41.453525Z" } }, "outputs": [ @@ -1698,7 +2246,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- Job _tn9S3jlwQzattJUcoVv92g.gms Start 07/17/25 10:33:58 50.2.0 d60bb663 LEX-LEG x86 64bit/Linux\n" + "--- Job _B03rB9R3R9SbAJSrApt6kQ.gms Start 07/17/25 12:21:41 50.2.0 d60bb663 LEX-LEG x86 64bit/Linux\n" ] }, { @@ -1740,21 +2288,21 @@ "name": "stdout", "output_type": "stream", "text": [ - " Input /tmp/tmpbbq4gnul/_tn9S3jlwQzattJUcoVv92g.gms\n" + " Input /tmp/tmpz1ajkw_x/_B03rB9R3R9SbAJSrApt6kQ.gms\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - " Output /tmp/tmpbbq4gnul/_tn9S3jlwQzattJUcoVv92g.lst\n" + " Output /tmp/tmpz1ajkw_x/_B03rB9R3R9SbAJSrApt6kQ.lst\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - " ScrDir /tmp/tmpbbq4gnul/tmprfsw4u8c/\n" + " ScrDir /tmp/tmpz1ajkw_x/tmpe0l7t8w9/\n" ] }, { @@ -1775,7 +2323,7 @@ "name": "stdout", "output_type": "stream", "text": [ - " Trace /tmp/tmpbbq4gnul/_tn9S3jlwQzattJUcoVv92g.txt\n" + " Trace /tmp/tmpz1ajkw_x/_B03rB9R3R9SbAJSrApt6kQ.txt\n" ] }, { @@ -1796,7 +2344,7 @@ "name": "stdout", "output_type": "stream", "text": [ - " OptDir /tmp/tmpbbq4gnul/\n" + " OptDir /tmp/tmpz1ajkw_x/\n" ] }, { @@ -1824,7 +2372,7 @@ "name": "stdout", "output_type": "stream", "text": [ - " GDX /tmp/tmpbbq4gnul/_tn9S3jlwQzattJUcoVv92gout.gdx\n" + " GDX /tmp/tmpz1ajkw_x/_B03rB9R3R9SbAJSrApt6kQout.gdx\n" ] }, { @@ -1866,7 +2414,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- _tn9S3jlwQzattJUcoVv92g.gms(71) 4 Mb\n" + "--- _B03rB9R3R9SbAJSrApt6kQ.gms(71) 4 Mb\n" ] }, { @@ -1887,7 +2435,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- _tn9S3jlwQzattJUcoVv92g.gms(142) 4 Mb\n" + "--- _B03rB9R3R9SbAJSrApt6kQ.gms(142) 4 Mb\n" ] }, { @@ -1929,14 +2477,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- Executing CUOPT (Solvelink=2): elapsed 0:00:00.001\n" + "--- Executing CUOPT (Solvelink=2): elapsed 0:00:00.000\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Setting parameter log_file to /tmp/tmpbbq4gnul/tmprfsw4u8c/cuopt.dat\n" + "Setting parameter log_file to /tmp/tmpz1ajkw_x/tmpe0l7t8w9/cuopt.dat\n" ] }, { @@ -2027,28 +2575,28 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- Executing after solve: elapsed 0:00:00.181\n" + "--- Executing after solve: elapsed 0:00:00.194\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "--- _tn9S3jlwQzattJUcoVv92g.gms(143) 4 Mb\n" + "--- _B03rB9R3R9SbAJSrApt6kQ.gms(143) 4 Mb\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "--- _tn9S3jlwQzattJUcoVv92g.gms(201) 4 Mb\n" + "--- _B03rB9R3R9SbAJSrApt6kQ.gms(201) 4 Mb\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "--- GDX File /tmp/tmpbbq4gnul/_tn9S3jlwQzattJUcoVv92gout.gdx\n" + "--- GDX File /tmp/tmpz1ajkw_x/_B03rB9R3R9SbAJSrApt6kQout.gdx\n" ] }, { @@ -2062,7 +2610,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "--- Job _tn9S3jlwQzattJUcoVv92g.gms Stop 07/17/25 10:33:58 elapsed 0:00:00.181\n" + "--- Job _B03rB9R3R9SbAJSrApt6kQ.gms Stop 07/17/25 12:21:41 elapsed 0:00:00.194\n" ] }, { @@ -2147,10 +2695,10 @@ "execution_count": 27, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.429392Z", - "iopub.status.busy": "2025-07-17T08:33:58.429292Z", - "iopub.status.idle": "2025-07-17T08:33:58.434189Z", - "shell.execute_reply": "2025-07-17T08:33:58.434017Z" + "iopub.execute_input": "2025-07-17T10:21:41.454555Z", + "iopub.status.busy": "2025-07-17T10:21:41.454455Z", + "iopub.status.idle": "2025-07-17T10:21:41.458669Z", + "shell.execute_reply": "2025-07-17T10:21:41.458521Z" } }, "outputs": [ @@ -2287,10 +2835,10 @@ "execution_count": 28, "metadata": { "execution": { - "iopub.execute_input": "2025-07-17T08:33:58.434873Z", - "iopub.status.busy": "2025-07-17T08:33:58.434803Z", - "iopub.status.idle": "2025-07-17T08:33:58.436417Z", - "shell.execute_reply": "2025-07-17T08:33:58.436250Z" + "iopub.execute_input": "2025-07-17T10:21:41.459304Z", + "iopub.status.busy": "2025-07-17T10:21:41.459237Z", + "iopub.status.idle": "2025-07-17T10:21:41.460707Z", + "shell.execute_reply": "2025-07-17T10:21:41.460556Z" } }, "outputs": [ From 32972b3cc9c5cecbfcd3e1ef55d309220277d0e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Schnabel?= Date: Thu, 17 Jul 2025 17:32:03 +0200 Subject: [PATCH 4/7] Make setup steps in first cell less verbose --- .../trnsport_cuopt.ipynb | 4124 ++++++----------- 1 file changed, 1545 insertions(+), 2579 deletions(-) diff --git a/GAMSPy_integration_example/trnsport_cuopt.ipynb b/GAMSPy_integration_example/trnsport_cuopt.ipynb index 8dd7e17..b7591d8 100644 --- a/GAMSPy_integration_example/trnsport_cuopt.ipynb +++ b/GAMSPy_integration_example/trnsport_cuopt.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 30, "metadata": { "execution": { "iopub.execute_input": "2025-07-17T10:21:15.883029Z", @@ -19,2598 +19,1564 @@ "name": "stdout", "output_type": "stream", "text": [ - "Looking in indexes: https://pypi.org/simple, https://pypi.nvidia.com\r\n", - "Requirement already satisfied: cuopt-cu12==25.5.* in ./.venv/lib/python3.12/site-packages (25.5.1)\r\n", - "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.8.* in ./.venv/lib/python3.12/site-packages (12.8.90)\r\n", - "Requirement already satisfied: nvidia-nvjitlink-cu12 in ./.venv/lib/python3.12/site-packages (12.9.86)\r\n", - "Requirement already satisfied: cudf-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: cuopt-mps-parser==25.5.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.5.1)\r\n", - "Requirement already satisfied: cupy-cuda12x in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (13.5.1)\r\n", - "Requirement already satisfied: cuvs-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: libcuopt-cu12==25.5.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.5.1)\r\n", - "Requirement already satisfied: numba<0.61.0a0,>=0.59.1 in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (0.60.0)\r\n", - "Requirement already satisfied: numpy<3.0a0,>=1.23.5 in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (2.0.2)\r\n", - "Requirement already satisfied: pandas<2.2.3dev0,>=2.0 in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (2.2.2)\r\n", - "Requirement already satisfied: pylibraft-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: raft-dask-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: rapids-dask-dependency==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: rapids-logger==0.1.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (0.1.1)\r\n", - "Requirement already satisfied: rmm-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: cachetools in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (6.1.0)\r\n", - "Requirement already satisfied: cuda-python<13.0a0,>=12.6.2 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (12.9.0)\r\n", - "Requirement already satisfied: fsspec>=0.6.0 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (2025.7.0)\r\n", - "Requirement already satisfied: libcudf-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: numba-cuda<0.5.0a0,>=0.4.0 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (0.4.0)\r\n", - "Requirement already satisfied: nvtx>=0.2.1 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (0.2.12)\r\n", - "Requirement already satisfied: packaging in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (25.0)\r\n", - "Requirement already satisfied: pyarrow<20.0.0a0,>=14.0.0 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (19.0.1)\r\n", - "Requirement already satisfied: pylibcudf-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: pynvjitlink-cu12 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (0.7.0)\r\n", - "Requirement already satisfied: rich in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (14.0.0)\r\n", - "Requirement already satisfied: typing_extensions>=4.0.0 in ./.venv/lib/python3.12/site-packages (from cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (4.14.1)\r\n", - "Requirement already satisfied: libcuvs-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from cuvs-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: librmm-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: nvidia-cublas-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (12.9.1.4)\r\n", - "Requirement already satisfied: nvidia-curand-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (10.3.10.19)\r\n", - "Requirement already satisfied: nvidia-cusolver-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (11.7.5.82)\r\n", - "Requirement already satisfied: nvidia-cusparse-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (12.5.10.65)\r\n", - "Requirement already satisfied: nvidia-nvtx-cu12 in ./.venv/lib/python3.12/site-packages (from libcuopt-cu12==25.5.*->cuopt-cu12==25.5.*) (12.9.79)\r\n", - "Requirement already satisfied: libraft-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from pylibraft-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: dask-cuda==25.4.* in ./.venv/lib/python3.12/site-packages (from raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: distributed-ucxx-cu12==0.43.* in ./.venv/lib/python3.12/site-packages (from raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (0.43.0)\r\n", - "Requirement already satisfied: ucx-py-cu12==0.43.* in ./.venv/lib/python3.12/site-packages (from raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (0.43.0)\r\n", - "Requirement already satisfied: dask==2025.2.0 in ./.venv/lib/python3.12/site-packages (from rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (2025.2.0)\r\n", - "Requirement already satisfied: distributed==2025.2.0 in ./.venv/lib/python3.12/site-packages (from rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (2025.2.0)\r\n", - "Requirement already satisfied: click>=8.1 in ./.venv/lib/python3.12/site-packages (from dask==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (8.1.8)\r\n", - "Requirement already satisfied: cloudpickle>=3.0.0 in ./.venv/lib/python3.12/site-packages (from dask==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (3.1.1)\r\n", - "Requirement already satisfied: partd>=1.4.0 in ./.venv/lib/python3.12/site-packages (from dask==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (1.4.2)\r\n", - "Requirement already satisfied: pyyaml>=5.3.1 in ./.venv/lib/python3.12/site-packages (from dask==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (6.0.2)\r\n", - "Requirement already satisfied: toolz>=0.10.0 in ./.venv/lib/python3.12/site-packages (from dask==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (1.0.0)\r\n", - "Requirement already satisfied: pynvml<13.0.0a0,>=12.0.0 in ./.venv/lib/python3.12/site-packages (from dask-cuda==25.4.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (12.0.0)\r\n", - "Requirement already satisfied: zict>=2.0.0 in ./.venv/lib/python3.12/site-packages (from dask-cuda==25.4.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (3.0.0)\r\n", - "Requirement already satisfied: jinja2>=2.10.3 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (3.1.6)\r\n", - "Requirement already satisfied: locket>=1.0.0 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (1.0.0)\r\n", - "Requirement already satisfied: msgpack>=1.0.2 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (1.1.1)\r\n", - "Requirement already satisfied: psutil>=5.8.0 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (7.0.0)\r\n", - "Requirement already satisfied: sortedcontainers>=2.0.5 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (2.4.0)\r\n", - "Requirement already satisfied: tblib>=1.6.0 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (3.1.0)\r\n", - "Requirement already satisfied: tornado>=6.2.0 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (6.5.1)\r\n", - "Requirement already satisfied: urllib3>=1.26.5 in ./.venv/lib/python3.12/site-packages (from distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (2.5.0)\r\n", - "Requirement already satisfied: ucxx-cu12==0.43.* in ./.venv/lib/python3.12/site-packages (from distributed-ucxx-cu12==0.43.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (0.43.0)\r\n", - "Requirement already satisfied: libkvikio-cu12==25.4.* in ./.venv/lib/python3.12/site-packages (from libcudf-cu12==25.4.*->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (25.4.0)\r\n", - "Requirement already satisfied: nvidia-nvcomp-cu12==4.2.0.11 in ./.venv/lib/python3.12/site-packages (from libcudf-cu12==25.4.*->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (4.2.0.11)\r\n" + "Archive: cuopt-link-release.zip\n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/librapids_logger.so \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gamsconfig.yaml \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libgomp-5fc1ad8c.so.1.0.0 \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmscuopt.run \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmscuopt.out \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libmps_parser.so \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libcuopt.so \n", + " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/optcuopt.def \n" ] }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: libucx-cu12<1.19,>=1.15.0 in ./.venv/lib/python3.12/site-packages (from ucx-py-cu12==0.43.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (1.18.1)\r\n", - "Requirement already satisfied: libucxx-cu12==0.43.* in ./.venv/lib/python3.12/site-packages (from ucxx-cu12==0.43.*->distributed-ucxx-cu12==0.43.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (0.43.0)\r\n", - "Requirement already satisfied: fastrlock>=0.5 in ./.venv/lib/python3.12/site-packages (from cupy-cuda12x->cuopt-cu12==25.5.*) (0.8.3)\r\n", - "Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in ./.venv/lib/python3.12/site-packages (from numba<0.61.0a0,>=0.59.1->cuopt-cu12==25.5.*) (0.43.0)\r\n" - ] - }, + "data": { + "text/plain": [ + "CompletedProcess(args='unzip -o cuopt-link-release.zip -d /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base', returncode=0)" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "!pip install -q --extra-index-url=https://pypi.nvidia.com cuopt-cu12==25.5.* nvidia-cuda-runtime-cu12==12.8.* nvidia-nvjitlink-cu12\n", + "!pip install -q gamspy\n", + "import subprocess\n", + "import sys\n", + "!wget -nc -nv -O cuopt-link-release.zip \"https://github.com/GAMS-dev/cuoptlink-builder/releases/download/v0.0.1/cuopt-link-release.zip\"\n", + "gams_base_path = subprocess.check_output([sys.executable, '-m', 'gamspy', 'show', 'base']).decode('utf-8').strip()\n", + "subprocess.run(f\"unzip -o cuopt-link-release.zip -d {gams_base_path}\", shell=True, check=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GAMSPy model example\n", + "\n", + "## Introduction\n", + "\n", + "This quick start guide is designed to provide you with a concise overview of GAMSPy and its key features. By the end of this guide, you'll have a solid understanding of how to create basic mathematical models using GAMSPy. For more advanced features, we recommend exploring our comprehensive [user guide](https://gamspy.readthedocs.io/en/latest/user/index.html) and the extensive [model library](https://gamspy.readthedocs.io/en/latest/user/model_library.html).\n", + "\n", + "While not mandatory, having a basic understanding of Python programming and familiarity with the [Pandas library](https://pandas.pydata.org/). will be helpful in following this tutorial.\n", + "\n", + "## A Transportation Problem\n", + "\n", + "In this guide, we'll delve into an example of the transportation problem. This classic scenario involves managing supplies from various plants to meet demands at multiple markets for a single commodity. Additionally, we have the unit costs associated with shipping the commodity from plants to markets. The fundamental economic question here is: \n", + "\n", + "> How can we optimize the shipment quantities between each plant and market to minimize the total transport cost?\n", + "\n", + "The problem's algebraic representation typically takes the following format:\n", + "\n", + "Indices (Sets):\n", + "\n", + "- $i$ = plants\n", + "- $j$ = markets\n", + "\n", + "Given Data (Parameters):\n", + "\n", + "- $a_i$ = supply of commodity at plant $i$ (in cases)\n", + "- $b_j$ = demand for commodity at market $j$ (in cases)\n", + "- $c_{ij}$ = cost per unit of shipment between plant $i$ and market $j$\n", + "\n", + "Decision Variables:\n", + "\n", + "- $x_{ij}$ = amount of commodity to ship from plant $i$ to market $j$ where $x_{ij} \\ge 0$ for all $i,j$\n", + "\n", + "Constraints:\n", + "\n", + "- Observe supply limit at plant $i$: $\\sum_j x_{ij} \\le a_i \\: \\forall i$\n", + "- Satisfy demand at market $j$: $\\sum_i x_{ij} \\ge b_j \\: \\forall j$\n", + "- Objective Function: Minimize $\\sum_i \\sum_j c_{ij} \\cdot x_{ij}$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data\n", + "\n", + "Before we dive into the optimization process, let's handle our data using the [Pandas library](https://pandas.pydata.org/). We'll begin by organizing the necessary information, which we will subsequently feed into our optimization model." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:40.915536Z", + "iopub.status.busy": "2025-07-17T10:21:40.915457Z", + "iopub.status.idle": "2025-07-17T10:21:41.083438Z", + "shell.execute_reply": "2025-07-17T10:21:41.083230Z" + } + }, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: python-dateutil>=2.8.2 in ./.venv/lib/python3.12/site-packages (from pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (2.9.0.post0)\r\n", - "Requirement already satisfied: pytz>=2020.1 in ./.venv/lib/python3.12/site-packages (from pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (2025.2)\r\n", - "Requirement already satisfied: tzdata>=2022.7 in ./.venv/lib/python3.12/site-packages (from pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (2025.2)\r\n", - "Requirement already satisfied: cuda-bindings~=12.9.0 in ./.venv/lib/python3.12/site-packages (from cuda-python<13.0a0,>=12.6.2->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (12.9.0)\r\n" - ] - }, + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
capacity
city
seattle350
san-diego600
\n", + "
" + ], + "text/plain": [ + " capacity\n", + "city \n", + "seattle 350\n", + "san-diego 600" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "capacities = pd.DataFrame(\n", + " [[\"seattle\", 350], [\"san-diego\", 600]], columns=[\"city\", \"capacity\"]\n", + ").set_index(\"city\")\n", + "\n", + "capacities" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.084284Z", + "iopub.status.busy": "2025-07-17T10:21:41.084168Z", + "iopub.status.idle": "2025-07-17T10:21:41.086987Z", + "shell.execute_reply": "2025-07-17T10:21:41.086797Z" + } + }, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas<2.2.3dev0,>=2.0->cuopt-cu12==25.5.*) (1.17.0)\r\n", - "Requirement already satisfied: markdown-it-py>=2.2.0 in ./.venv/lib/python3.12/site-packages (from rich->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (3.0.0)\r\n", - "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in ./.venv/lib/python3.12/site-packages (from rich->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (2.19.2)\r\n", - "Requirement already satisfied: MarkupSafe>=2.0 in ./.venv/lib/python3.12/site-packages (from jinja2>=2.10.3->distributed==2025.2.0->rapids-dask-dependency==25.4.*->cuopt-cu12==25.5.*) (3.0.2)\r\n" - ] - }, + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
demand
city
new-york325
chicago300
topeka275
\n", + "
" + ], + "text/plain": [ + " demand\n", + "city \n", + "new-york 325\n", + "chicago 300\n", + "topeka 275" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "demands = pd.DataFrame(\n", + " [[\"new-york\", 325], [\"chicago\", 300], [\"topeka\", 275]], columns=[\"city\", \"demand\"]\n", + ").set_index(\"city\")\n", + "\n", + "demands" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.087770Z", + "iopub.status.busy": "2025-07-17T10:21:41.087633Z", + "iopub.status.idle": "2025-07-17T10:21:41.091517Z", + "shell.execute_reply": "2025-07-17T10:21:41.091358Z" + } + }, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: mdurl~=0.1 in ./.venv/lib/python3.12/site-packages (from markdown-it-py>=2.2.0->rich->cudf-cu12==25.4.*->cuopt-cu12==25.5.*) (0.1.2)\r\n", - "Requirement already satisfied: nvidia-ml-py<13.0.0a0,>=12.0.0 in ./.venv/lib/python3.12/site-packages (from pynvml<13.0.0a0,>=12.0.0->dask-cuda==25.4.*->raft-dask-cu12==25.4.*->cuopt-cu12==25.5.*) (12.575.51)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: gamspy in ./.venv/lib/python3.12/site-packages (1.13.0)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: gamsapi==50.2.0 in ./.venv/lib/python3.12/site-packages (from gamsapi[transfer]==50.2.0->gamspy) (50.2.0)\r\n", - "Requirement already satisfied: gamspy_base==50.2.0 in ./.venv/lib/python3.12/site-packages (from gamspy) (50.2.0)\r\n", - "Requirement already satisfied: pydantic>=2.0 in ./.venv/lib/python3.12/site-packages (from gamspy) (2.11.7)\r\n", - "Requirement already satisfied: certifi>=2022.09.14 in ./.venv/lib/python3.12/site-packages (from gamspy) (2025.7.14)\r\n", - "Requirement already satisfied: urllib3>=2.0.7 in ./.venv/lib/python3.12/site-packages (from gamspy) (2.5.0)\r\n", - "Requirement already satisfied: typer>=0.15.1 in ./.venv/lib/python3.12/site-packages (from gamspy) (0.16.0)\r\n", - "Requirement already satisfied: click<8.2.0 in ./.venv/lib/python3.12/site-packages (from gamspy) (8.1.8)\r\n", - "Requirement already satisfied: pandas<2.3,>=2.0 in ./.venv/lib/python3.12/site-packages (from gamsapi[transfer]==50.2.0->gamspy) (2.2.2)\r\n", - "Requirement already satisfied: scipy in ./.venv/lib/python3.12/site-packages (from gamsapi[transfer]==50.2.0->gamspy) (1.16.0)\r\n", - "Requirement already satisfied: annotated-types>=0.6.0 in ./.venv/lib/python3.12/site-packages (from pydantic>=2.0->gamspy) (0.7.0)\r\n", - "Requirement already satisfied: pydantic-core==2.33.2 in ./.venv/lib/python3.12/site-packages (from pydantic>=2.0->gamspy) (2.33.2)\r\n", - "Requirement already satisfied: typing-extensions>=4.12.2 in ./.venv/lib/python3.12/site-packages (from pydantic>=2.0->gamspy) (4.14.1)\r\n", - "Requirement already satisfied: typing-inspection>=0.4.0 in ./.venv/lib/python3.12/site-packages (from pydantic>=2.0->gamspy) (0.4.1)\r\n", - "Requirement already satisfied: shellingham>=1.3.0 in ./.venv/lib/python3.12/site-packages (from typer>=0.15.1->gamspy) (1.5.4)\r\n", - "Requirement already satisfied: rich>=10.11.0 in ./.venv/lib/python3.12/site-packages (from typer>=0.15.1->gamspy) (14.0.0)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: numpy>=1.26.0 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2.0.2)\r\n", - "Requirement already satisfied: python-dateutil>=2.8.2 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2.9.0.post0)\r\n", - "Requirement already satisfied: pytz>=2020.1 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2025.2)\r\n", - "Requirement already satisfied: tzdata>=2022.7 in ./.venv/lib/python3.12/site-packages (from pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (2025.2)\r\n", - "Requirement already satisfied: markdown-it-py>=2.2.0 in ./.venv/lib/python3.12/site-packages (from rich>=10.11.0->typer>=0.15.1->gamspy) (3.0.0)\r\n", - "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in ./.venv/lib/python3.12/site-packages (from rich>=10.11.0->typer>=0.15.1->gamspy) (2.19.2)\r\n", - "Requirement already satisfied: mdurl~=0.1 in ./.venv/lib/python3.12/site-packages (from markdown-it-py>=2.2.0->rich>=10.11.0->typer>=0.15.1->gamspy) (0.1.2)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas<2.3,>=2.0->gamsapi[transfer]==50.2.0->gamspy) (1.17.0)\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--2025-07-17 12:21:17-- https://github.com/GAMS-dev/cuoptlink-builder/releases/download/v0.0.1/cuopt-link-release.zip\r\n", - "Resolving github.com (github.com)... 140.82.121.3\r\n", - "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\r\n", - "HTTP request sent, awaiting response... " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "302 Found\r\n", - "Location: https://release-assets.githubusercontent.com/github-production-release-asset/1019451854/6023761c-9183-44e0-9c95-63a83ca98902?sp=r&sv=2018-11-09&sr=b&spr=https&se=2025-07-17T11%3A09%3A20Z&rscd=attachment%3B+filename%3Dcuopt-link-release.zip&rsct=application%2Foctet-stream&skoid=96c2d410-5711-43a1-aedd-ab1947aa7ab0&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skt=2025-07-17T10%3A09%3A16Z&ske=2025-07-17T11%3A09%3A20Z&sks=b&skv=2018-11-09&sig=GrgDPXO3FVyE%2BEOfo5Rs2KEw%2Fefmsi9nT5HONbwdOOo%3D&jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmVsZWFzZS1hc3NldHMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwia2V5Ijoia2V5MSIsImV4cCI6MTc1Mjc0Nzk3OCwibmJmIjoxNzUyNzQ3Njc4LCJwYXRoIjoicmVsZWFzZWFzc2V0cHJvZHVjdGlvbi5ibG9iLmNvcmUud2luZG93cy5uZXQifQ.64DdDTPBHy4pxV7_n7aWUb6LI6rpVSOc4_dnj0LaDC8&response-content-disposition=attachment%3B%20filename%3Dcuopt-link-release.zip&response-content-type=application%2Foctet-stream [following]\r\n", - "--2025-07-17 12:21:18-- https://release-assets.githubusercontent.com/github-production-release-asset/1019451854/6023761c-9183-44e0-9c95-63a83ca98902?sp=r&sv=2018-11-09&sr=b&spr=https&se=2025-07-17T11%3A09%3A20Z&rscd=attachment%3B+filename%3Dcuopt-link-release.zip&rsct=application%2Foctet-stream&skoid=96c2d410-5711-43a1-aedd-ab1947aa7ab0&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skt=2025-07-17T10%3A09%3A16Z&ske=2025-07-17T11%3A09%3A20Z&sks=b&skv=2018-11-09&sig=GrgDPXO3FVyE%2BEOfo5Rs2KEw%2Fefmsi9nT5HONbwdOOo%3D&jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmVsZWFzZS1hc3NldHMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwia2V5Ijoia2V5MSIsImV4cCI6MTc1Mjc0Nzk3OCwibmJmIjoxNzUyNzQ3Njc4LCJwYXRoIjoicmVsZWFzZWFzc2V0cHJvZHVjdGlvbi5ibG9iLmNvcmUud2luZG93cy5uZXQifQ.64DdDTPBHy4pxV7_n7aWUb6LI6rpVSOc4_dnj0LaDC8&response-content-disposition=attachment%3B%20filename%3Dcuopt-link-release.zip&response-content-type=application%2Foctet-stream\r\n", - "Resolving release-assets.githubusercontent.com (release-assets.githubusercontent.com)... 185.199.111.133, 185.199.109.133, 185.199.110.133, ...\r\n", - "Connecting to release-assets.githubusercontent.com (release-assets.githubusercontent.com)|185.199.111.133|:443... " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "connected.\r\n", - "HTTP request sent, awaiting response... " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "200 OK\r\n", - "Length: 449652025 (429M) [application/octet-stream]\r\n", - "Saving to: ‘cuopt-link-release.zip’\r\n", - "\r\n", - "\r", - "cuopt-link-release. 0%[ ] 0 --.-KB/s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 1%[ ] 4.54M 22.6MB/s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 2%[ ] 10.02M 16.3MB/s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 4%[ ] 20.02M 19.5MB/s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 6%[> ] 29.76M 24.3MB/s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 7%[> ] 30.33M 21.2MB/s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 7%[> ] 33.16M 20.3MB/s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 9%[> ] 40.02M 20.3MB/s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 11%[=> ] 50.00M 23.0MB/s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 12%[=> ] 52.23M 22.0MB/s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 13%[=> ] 60.02M 22.1MB/s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 16%[==> ] 70.02M 23.0MB/s eta 16s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 18%[==> ] 80.02M 23.3MB/s eta 16s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 20%[===> ] 90.02M 23.7MB/s eta 16s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 23%[===> ] 100.02M 23.9MB/s eta 14s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 25%[====> ] 110.02M 24.8MB/s eta 14s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 27%[====> ] 120.02M 25.0MB/s eta 14s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 30%[=====> ] 130.00M 26.6MB/s eta 12s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 32%[=====> ] 139.89M 28.2MB/s eta 12s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 33%[=====> ] 143.97M 28.1MB/s eta 12s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 34%[=====> ] 150.02M 27.5MB/s eta 12s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 37%[======> ] 160.01M 27.8MB/s eta 11s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 37%[======> ] 161.34M 25.7MB/s eta 11s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 39%[======> ] 167.96M 26.6MB/s eta 11s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 39%[======> ] 170.67M 24.9MB/s eta 11s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 41%[=======> ] 180.02M 25.3MB/s eta 11s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 44%[=======> ] 189.14M 27.1MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 44%[=======> ] 190.02M 25.0MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 46%[========> ] 199.94M 26.9MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 46%[========> ] 200.02M 24.5MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 48%[========> ] 210.02M 22.7MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 49%[========> ] 212.37M 22.9MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 50%[=========> ] 215.04M 21.4MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 50%[=========> ] 217.78M 21.5MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 51%[=========> ] 220.02M 19.5MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 53%[=========> ] 227.33M 19.2MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 53%[=========> ] 230.02M 19.3MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 55%[==========> ] 240.02M 18.6MB/s eta 9s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 58%[==========> ] 250.02M 19.5MB/s eta 8s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 60%[===========> ] 257.44M 20.1MB/s eta 8s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 60%[===========> ] 260.02M 18.7MB/s eta 8s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 62%[===========> ] 270.02M 18.3MB/s eta 8s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 65%[============> ] 280.02M 18.5MB/s eta 7s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 67%[============> ] 290.00M 18.5MB/s eta 7s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 68%[============> ] 294.19M 20.3MB/s eta 7s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 69%[============> ] 300.02M 20.5MB/s eta 7s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 72%[=============> ] 310.02M 21.7MB/s eta 5s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 74%[=============> ] 320.02M 23.1MB/s eta 5s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 76%[==============> ] 330.02M 23.0MB/s eta 5s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 78%[==============> ] 335.66M 24.6MB/s eta 5s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 78%[==============> ] 336.02M 22.1MB/s eta 4s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 79%[==============> ] 341.17M 23.4MB/s eta 4s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 81%[===============> ] 350.02M 23.8MB/s eta 4s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 82%[===============> ] 355.05M 22.8MB/s eta 4s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 83%[===============> ] 360.02M 23.5MB/s eta 3s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 86%[================> ] 370.02M 23.4MB/s eta 3s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 87%[================> ] 373.60M 22.0MB/s eta 3s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 88%[================> ] 377.65M 22.8MB/s eta 3s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 88%[================> ] 380.02M 21.6MB/s eta 2s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 90%[=================> ] 387.33M 23.1MB/s eta 2s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 90%[=================> ] 390.02M 21.4MB/s eta 2s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 93%[=================> ] 400.02M 21.5MB/s eta 2s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 95%[==================> ] 410.02M 21.6MB/s eta 1s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 97%[==================> ] 420.02M 22.7MB/s eta 1s " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\r", - "cuopt-link-release. 100%[===================>] 428.82M 25.3MB/s in 18s \r\n", - "\r\n", - "2025-07-17 12:21:36 (23.3 MB/s) - ‘cuopt-link-release.zip’ saved [449652025/449652025]\r\n", - "\r\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Archive: cuopt-link-release.zip\n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/librapids_logger.so \n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gamsconfig.yaml \n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libgomp-5fc1ad8c.so.1.0.0 \n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmscuopt.run \n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmscuopt.out \n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libmps_parser.so \n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/libcuopt.so " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - " inflating: /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/optcuopt.def \n" - ] - }, - { - "data": { - "text/plain": [ - "CompletedProcess(args='unzip -o cuopt-link-release.zip -d /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base', returncode=0)" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "!pip install --extra-index-url=https://pypi.nvidia.com cuopt-cu12==25.5.* nvidia-cuda-runtime-cu12==12.8.* nvidia-nvjitlink-cu12\n", - "!pip install gamspy\n", - "import subprocess\n", - "import sys\n", - "!wget -nc -O cuopt-link-release.zip \"https://github.com/GAMS-dev/cuoptlink-builder/releases/download/v0.0.1/cuopt-link-release.zip\"\n", - "gams_base_path = subprocess.check_output([sys.executable, '-m', 'gamspy', 'show', 'base']).decode('utf-8').strip()\n", - "subprocess.run(f\"unzip -o cuopt-link-release.zip -d {gams_base_path}\", shell=True, check=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# GAMSPy model example\n", - "\n", - "## Introduction\n", - "\n", - "This quick start guide is designed to provide you with a concise overview of GAMSPy and its key features. By the end of this guide, you'll have a solid understanding of how to create basic mathematical models using GAMSPy. For more advanced features, we recommend exploring our comprehensive [user guide](https://gamspy.readthedocs.io/en/latest/user/index.html) and the extensive [model library](https://gamspy.readthedocs.io/en/latest/user/model_library.html).\n", - "\n", - "While not mandatory, having a basic understanding of Python programming and familiarity with the [Pandas library](https://pandas.pydata.org/). will be helpful in following this tutorial.\n", - "\n", - "## A Transportation Problem\n", - "\n", - "In this guide, we'll delve into an example of the transportation problem. This classic scenario involves managing supplies from various plants to meet demands at multiple markets for a single commodity. Additionally, we have the unit costs associated with shipping the commodity from plants to markets. The fundamental economic question here is: \n", - "\n", - "> How can we optimize the shipment quantities between each plant and market to minimize the total transport cost?\n", - "\n", - "The problem's algebraic representation typically takes the following format:\n", - "\n", - "Indices (Sets):\n", - "\n", - "- $i$ = plants\n", - "- $j$ = markets\n", - "\n", - "Given Data (Parameters):\n", - "\n", - "- $a_i$ = supply of commodity at plant $i$ (in cases)\n", - "- $b_j$ = demand for commodity at market $j$ (in cases)\n", - "- $c_{ij}$ = cost per unit of shipment between plant $i$ and market $j$\n", - "\n", - "Decision Variables:\n", - "\n", - "- $x_{ij}$ = amount of commodity to ship from plant $i$ to market $j$ where $x_{ij} \\ge 0$ for all $i,j$\n", - "\n", - "Constraints:\n", - "\n", - "- Observe supply limit at plant $i$: $\\sum_j x_{ij} \\le a_i \\: \\forall i$\n", - "- Satisfy demand at market $j$: $\\sum_i x_{ij} \\ge b_j \\: \\forall j$\n", - "- Objective Function: Minimize $\\sum_i \\sum_j c_{ij} \\cdot x_{ij}$\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Data\n", - "\n", - "Before we dive into the optimization process, let's handle our data using the [Pandas library](https://pandas.pydata.org/). We'll begin by organizing the necessary information, which we will subsequently feed into our optimization model." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:40.915536Z", - "iopub.status.busy": "2025-07-17T10:21:40.915457Z", - "iopub.status.idle": "2025-07-17T10:21:41.083438Z", - "shell.execute_reply": "2025-07-17T10:21:41.083230Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
capacity
city
seattle350
san-diego600
\n", - "
" - ], - "text/plain": [ - " capacity\n", - "city \n", - "seattle 350\n", - "san-diego 600" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import pandas as pd\n", - "\n", - "capacities = pd.DataFrame(\n", - " [[\"seattle\", 350], [\"san-diego\", 600]], columns=[\"city\", \"capacity\"]\n", - ").set_index(\"city\")\n", - "\n", - "capacities" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.084284Z", - "iopub.status.busy": "2025-07-17T10:21:41.084168Z", - "iopub.status.idle": "2025-07-17T10:21:41.086987Z", - "shell.execute_reply": "2025-07-17T10:21:41.086797Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
demand
city
new-york325
chicago300
topeka275
\n", - "
" - ], - "text/plain": [ - " demand\n", - "city \n", - "new-york 325\n", - "chicago 300\n", - "topeka 275" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "demands = pd.DataFrame(\n", - " [[\"new-york\", 325], [\"chicago\", 300], [\"topeka\", 275]], columns=[\"city\", \"demand\"]\n", - ").set_index(\"city\")\n", - "\n", - "demands" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.087770Z", - "iopub.status.busy": "2025-07-17T10:21:41.087633Z", - "iopub.status.idle": "2025-07-17T10:21:41.091517Z", - "shell.execute_reply": "2025-07-17T10:21:41.091358Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
distance
fromto
seattlenew-york2.5
chicago1.7
topeka1.8
san-diegonew-york2.5
chicago1.8
topeka1.4
\n", - "
" - ], - "text/plain": [ - " distance\n", - "from to \n", - "seattle new-york 2.5\n", - " chicago 1.7\n", - " topeka 1.8\n", - "san-diego new-york 2.5\n", - " chicago 1.8\n", - " topeka 1.4" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "distances = pd.DataFrame(\n", - " [\n", - " [\"seattle\", \"new-york\", 2.5],\n", - " [\"seattle\", \"chicago\", 1.7],\n", - " [\"seattle\", \"topeka\", 1.8],\n", - " [\"san-diego\", \"new-york\", 2.5],\n", - " [\"san-diego\", \"chicago\", 1.8],\n", - " [\"san-diego\", \"topeka\", 1.4],\n", - " ],\n", - " columns=[\"from\", \"to\", \"distance\"],\n", - ").set_index([\"from\", \"to\"])\n", - "\n", - "distances" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.092111Z", - "iopub.status.busy": "2025-07-17T10:21:41.092042Z", - "iopub.status.idle": "2025-07-17T10:21:41.093337Z", - "shell.execute_reply": "2025-07-17T10:21:41.093174Z" - } - }, - "outputs": [], - "source": [ - "freight_cost = 90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Symbol Declaration\n", - "\n", - "In line with our systematic breakdown of the transportation problem into sets, parameters, variables, and constraints, we will adopt a similar approach to define the problem as a GAMSPy `Model`. To do so, it is essential to import the `gamspy` library initially." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.093948Z", - "iopub.status.busy": "2025-07-17T10:21:41.093881Z", - "iopub.status.idle": "2025-07-17T10:21:41.163655Z", - "shell.execute_reply": "2025-07-17T10:21:41.163440Z" - } - }, - "outputs": [], - "source": [ - "from gamspy import Container, Set, Parameter, Variable, Equation, Model, Sum, Sense" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Container\n", - "\n", - "Before we proceed further, let's create a `Container` to encapsulate all the relevant information for our GAMSPy ``Model``. This ``Container`` acts as a centralized hub, gathering essential data, sets, parameters, variables, and constraints, providing a clear structure for our optimization problem." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.164784Z", - "iopub.status.busy": "2025-07-17T10:21:41.164605Z", - "iopub.status.idle": "2025-07-17T10:21:41.172679Z", - "shell.execute_reply": "2025-07-17T10:21:41.172515Z" - } - }, - "outputs": [], - "source": [ - "m = Container()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Sets\n", - "\n", - "Sets serve as the fundamental building blocks of a GAMSPy ``Model``, directly corresponding to the indices in the algebraic representations of models. In our transportation problem context, we have defined the following indices:\n", - "\n", - "- $i$ = plants\n", - "- $j$ = markets\n", - "\n", - "For detailed guidance on using sets, please refer to the [set section](https://gamspy.readthedocs.io/en/latest/user/basics/set.html) of our user guide.\n", - "\n", - "There a two ways to declare sets:\n", - "\n", - "1. Separate declaration and data assignment\n", - "2. Combine declaration and data assignment\n", - "\n", - "#### Separate declaration and data assignment\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.173454Z", - "iopub.status.busy": "2025-07-17T10:21:41.173302Z", - "iopub.status.idle": "2025-07-17T10:21:41.179619Z", - "shell.execute_reply": "2025-07-17T10:21:41.179429Z" - } - }, - "outputs": [], - "source": [ - "i = Set(container=m, name=\"i\", description=\"plants\")\n", - "i.setRecords(capacities.index)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Combine declaration and data assignment\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.180411Z", - "iopub.status.busy": "2025-07-17T10:21:41.180278Z", - "iopub.status.idle": "2025-07-17T10:21:41.190480Z", - "shell.execute_reply": "2025-07-17T10:21:41.190323Z" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "j = Set(container=m, name=\"j\", description=\"markets\", records=demands.index)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The effect of using the above `Set` statements is that we declared two sets, namely $i$ and $j$. Additionally, we provided descriptions to elaborate on their meaning, enhancing the readability of our ``Model``. Lastly, we assigned members to the sets, establishing a clear connection between the abstract sets and their real-world counterparts.\n", - "\n", - "$i$ = {Seattle, San Diego}\n", - "\n", - "$j$ = {New York, Chicago, Topeka}\n", - "\n", - "To verify the content of a set, you can use `.records`." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.191227Z", - "iopub.status.busy": "2025-07-17T10:21:41.191108Z", - "iopub.status.idle": "2025-07-17T10:21:41.193520Z", - "shell.execute_reply": "2025-07-17T10:21:41.193371Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
unielement_text
0seattle
1san-diego
\n", - "
" - ], - "text/plain": [ - " uni element_text\n", - "0 seattle \n", - "1 san-diego " - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "i.records" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.194209Z", - "iopub.status.busy": "2025-07-17T10:21:41.194141Z", - "iopub.status.idle": "2025-07-17T10:21:41.196323Z", - "shell.execute_reply": "2025-07-17T10:21:41.196172Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
unielement_text
0new-york
1chicago
2topeka
\n", - "
" - ], - "text/plain": [ - " uni element_text\n", - "0 new-york \n", - "1 chicago \n", - "2 topeka " - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "j.records" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Parameters\n", - "\n", - "Declaring parameters involves using `Parameter`. Each parameter is assigned a name and a description. Note that parameter $a_i$ is indexed by $i$. To accommodate these indices, we include the `domain` attribute, pointing to the corresponding set.\n", - "\n", - "It is worth mentioning that, similar to sets, you have the flexibility to either combine or separate the declaration and data assignment steps. For convenience, we will proceed by combining the declaration and data assignment.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.196997Z", - "iopub.status.busy": "2025-07-17T10:21:41.196933Z", - "iopub.status.idle": "2025-07-17T10:21:41.201694Z", - "shell.execute_reply": "2025-07-17T10:21:41.201542Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
cityvalue
0seattle350.0
1san-diego600.0
\n", - "
" - ], - "text/plain": [ - " city value\n", - "0 seattle 350.0\n", - "1 san-diego 600.0" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a = Parameter(\n", - " container=m, \n", - " name=\"a\",\n", - " domain=i,\n", - " description=\"supply of commodity at plant i (in cases)\",\n", - " records=capacities.reset_index(),\n", - ")\n", - "a.records" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.202335Z", - "iopub.status.busy": "2025-07-17T10:21:41.202270Z", - "iopub.status.idle": "2025-07-17T10:21:41.206850Z", - "shell.execute_reply": "2025-07-17T10:21:41.206694Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
cityvalue
0new-york325.0
1chicago300.0
2topeka275.0
\n", - "
" - ], - "text/plain": [ - " city value\n", - "0 new-york 325.0\n", - "1 chicago 300.0\n", - "2 topeka 275.0" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "b = Parameter(\n", - " container=m,\n", - " name=\"b\",\n", - " domain=j,\n", - " description=\"demand for commodity at market j (in cases)\",\n", - " records=demands.reset_index(),\n", - ")\n", - "b.records" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.207532Z", - "iopub.status.busy": "2025-07-17T10:21:41.207468Z", - "iopub.status.idle": "2025-07-17T10:21:41.209778Z", - "shell.execute_reply": "2025-07-17T10:21:41.209610Z" - } - }, - "outputs": [], - "source": [ - "c = Parameter(\n", - " container=m,\n", - " name=\"c\",\n", - " domain=[i, j],\n", - " description=\"cost per unit of shipment between plant i and market j\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The cost per unit of shipment between plant $i$ and market $j$ is derived from the distance between $i$ and $j$ and can be calculated as follows:\n", - "\n", - "$c_{ij} = \\frac{90 \\cdot d_{ij}}{1000}$,\n", - "\n", - "where $d_{ij}$ denotes the distance between $i$ and $j$.\n", - "\n", - "We have two options to calculate $c_{ij}$ and assign the data to the GAMSPy parameter:\n", - "\n", - "1. Python assignment - calculation in Python, e.g., using Pandas and `.setRecords()`\n", - "2. GAMSPy assignment - calculation in GAMSPy\n", - "\n", - "#### Python Assignment" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.210541Z", - "iopub.status.busy": "2025-07-17T10:21:41.210390Z", - "iopub.status.idle": "2025-07-17T10:21:41.213168Z", - "shell.execute_reply": "2025-07-17T10:21:41.213001Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
distance
fromto
seattlenew-york0.225
chicago0.153
topeka0.162
san-diegonew-york0.225
chicago0.162
topeka0.126
\n", - "
" - ], - "text/plain": [ - " distance\n", - "from to \n", - "seattle new-york 0.225\n", - " chicago 0.153\n", - " topeka 0.162\n", - "san-diego new-york 0.225\n", - " chicago 0.162\n", - " topeka 0.126" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cost = freight_cost * distances / 1000\n", - "cost" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.213745Z", - "iopub.status.busy": "2025-07-17T10:21:41.213681Z", - "iopub.status.idle": "2025-07-17T10:21:41.218945Z", - "shell.execute_reply": "2025-07-17T10:21:41.218784Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
fromtovalue
0seattlenew-york0.225
1seattlechicago0.153
2seattletopeka0.162
3san-diegonew-york0.225
4san-diegochicago0.162
5san-diegotopeka0.126
\n", - "
" - ], - "text/plain": [ - " from to value\n", - "0 seattle new-york 0.225\n", - "1 seattle chicago 0.153\n", - "2 seattle topeka 0.162\n", - "3 san-diego new-york 0.225\n", - "4 san-diego chicago 0.162\n", - "5 san-diego topeka 0.126" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "c.setRecords(cost.reset_index())\n", - "c.records" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### GAMSPy Assignment\n", - "\n", - "For the direct assignment we need to declare a new ``Parameter`` denoting the distances between $i$ and $j$.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.219662Z", - "iopub.status.busy": "2025-07-17T10:21:41.219599Z", - "iopub.status.idle": "2025-07-17T10:21:41.225144Z", - "shell.execute_reply": "2025-07-17T10:21:41.224999Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
fromtovalue
0seattlenew-york2.5
1seattlechicago1.7
2seattletopeka1.8
3san-diegonew-york2.5
4san-diegochicago1.8
5san-diegotopeka1.4
\n", - "
" - ], - "text/plain": [ - " from to value\n", - "0 seattle new-york 2.5\n", - "1 seattle chicago 1.7\n", - "2 seattle topeka 1.8\n", - "3 san-diego new-york 2.5\n", - "4 san-diego chicago 1.8\n", - "5 san-diego topeka 1.4" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d = Parameter(\n", - " container=m,\n", - " name=\"d\",\n", - " domain=[i, j],\n", - " description=\"distance between plant i and market j\",\n", - " records=distances.reset_index(),\n", - ")\n", - "d.records" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.225778Z", - "iopub.status.busy": "2025-07-17T10:21:41.225715Z", - "iopub.status.idle": "2025-07-17T10:21:41.230168Z", - "shell.execute_reply": "2025-07-17T10:21:41.229995Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ijvalue
0seattlenew-york0.225
1seattlechicago0.153
2seattletopeka0.162
3san-diegonew-york0.225
4san-diegochicago0.162
5san-diegotopeka0.126
\n", - "
" - ], - "text/plain": [ - " i j value\n", - "0 seattle new-york 0.225\n", - "1 seattle chicago 0.153\n", - "2 seattle topeka 0.162\n", - "3 san-diego new-york 0.225\n", - "4 san-diego chicago 0.162\n", - "5 san-diego topeka 0.126" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "c[i, j] = freight_cost * d[i, j] / 1000\n", - "c.records" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Further information on the usage of parameters can be found in our [parameter section](https://gamspy.readthedocs.io/en/latest/user/basics/parameter.html) of the user guide." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Variables\n", - "\n", - "GAMSPy variables are declared using `Variable`. Each ``Variable`` is assigned a name, a domain if necessary, a type, and, optionally, a description." - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.230884Z", - "iopub.status.busy": "2025-07-17T10:21:41.230819Z", - "iopub.status.idle": "2025-07-17T10:21:41.233170Z", - "shell.execute_reply": "2025-07-17T10:21:41.233016Z" - } - }, - "outputs": [], - "source": [ - "x = Variable(\n", - " container=m,\n", - " name=\"x\",\n", - " domain=[i, j],\n", - " type=\"Positive\",\n", - " description=\"amount of commodity to ship from plant i to market j\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This statement results in the declaration of a shipment variable for each (i,j) pair.\n", - "\n", - "More information on variables can be found in the [variable section](https://gamspy.readthedocs.io/en/latest/user/basics/variable.html) of our user guide." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Equations\n", - "A GAMSPy ``Equation`` must be declared and defined in two separate statements. The format of the declaration is the same as for other GAMSPy symbols. First comes the keyword, `Equation` in this case, followed by the name, domain and text. The transportation problem has two constraints:\n", - "\n", - "Supply: observe supply limit at plant $i$: $\\sum_j x_{ij} \\le a_i \\: \\forall i$\n", - "\n", - "Demand: satisfy demand at market $j$: $\\sum_i x_{ij} \\ge b_j \\: \\forall j$" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.233875Z", - "iopub.status.busy": "2025-07-17T10:21:41.233798Z", - "iopub.status.idle": "2025-07-17T10:21:41.237181Z", - "shell.execute_reply": "2025-07-17T10:21:41.237005Z" - } - }, - "outputs": [], - "source": [ - "supply = Equation(\n", - " container=m, name=\"supply\", domain=i, description=\"observe supply limit at plant i\"\n", - ")\n", - "demand = Equation(\n", - " container=m, name=\"demand\", domain=j, description=\"satisfy demand at market j\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The components of an ``Equation`` definition are:\n", - "1. The Python variable of the ``Equation`` being defined\n", - "2. The domain (optional)\n", - "3. Domain restricting conditions (optional)\n", - "4. A `=` sign\n", - "5. Left hand side expression\n", - "6. Relational operator (`==`, `<=`, `>=`)\n", - "7. The right hand side expression.\n", - "\n", - "The ``Equation`` definition for the supply constraint of the transportation problem is implemented as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.237863Z", - "iopub.status.busy": "2025-07-17T10:21:41.237785Z", - "iopub.status.idle": "2025-07-17T10:21:41.240437Z", - "shell.execute_reply": "2025-07-17T10:21:41.240285Z" - } - }, - "outputs": [], - "source": [ - "supply[i] = Sum(j, x[i, j]) <= a[i]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Using the same logic as above, we can define the demand equation as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.241111Z", - "iopub.status.busy": "2025-07-17T10:21:41.241033Z", - "iopub.status.idle": "2025-07-17T10:21:41.243421Z", - "shell.execute_reply": "2025-07-17T10:21:41.243270Z" - } - }, - "outputs": [], - "source": [ - "demand[j] = Sum(i, x[i, j]) >= b[j]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "More information on equations is given in the [equation section](https://gamspy.readthedocs.io/en/latest/user/basics/equation.html) of our user guide." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Objective\n", - "The objective function of a GAMSPy ``Model`` does not require a separate ``Equation`` declaration. You can assign the objective expression to a Python variable or use it directly in the ``Model()`` statement of the [next section](#model).\n" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.244117Z", - "iopub.status.busy": "2025-07-17T10:21:41.244038Z", - "iopub.status.idle": "2025-07-17T10:21:41.245432Z", - "shell.execute_reply": "2025-07-17T10:21:41.245247Z" - } - }, - "outputs": [], - "source": [ - "obj = Sum((i, j), c[i, j] * x[i, j])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Model\n", - "\n", - "A GAMSPy `Model()` consolidates constraints, an objective function, a sense (minimize, maximize, and feasibility), and a problem type. It also possesses a name and is associated with a ``Container``.\n", - "\n", - "To define our transportation problem as a GAMSPy ``Model``, we assign it to a Python variable, link it to our ``Container`` (populated with symbols and data), name it \"transport\", specify the equations, set the problem type as linear program (LP), specify the sense of the objective function (``Sense.MIN``), and point to the objective expression.\n", - "\n", - "GAMSPy allows two alternatives to assign equations to a `Model`:\n", - "1. Using a list of equations,\n", - "2. Retrieving _all_ equations by calling `m.getEquations()`.\n", - "\n", - "### Using a List of Equations\n", - "Using a list of equations is especially useful if you want to define multiple GAMSPy ``Model``s with a subset of the equations in your ``Container``. For the transportation problem this can be done as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.246093Z", - "iopub.status.busy": "2025-07-17T10:21:41.246032Z", - "iopub.status.idle": "2025-07-17T10:21:41.248358Z", - "shell.execute_reply": "2025-07-17T10:21:41.248217Z" - } - }, - "outputs": [], - "source": [ - "transport = Model(\n", - " m,\n", - " name=\"transport\",\n", - " equations=[supply, demand],\n", - " problem=\"LP\",\n", - " sense=Sense.MIN,\n", - " objective=obj,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Retrieving all Equations\n", - "Using `m.getEquations()` is especially convenient if you want to include all equations of your ``Container`` to be associated with your model. For the transportation problem this can be done as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.248970Z", - "iopub.status.busy": "2025-07-17T10:21:41.248907Z", - "iopub.status.idle": "2025-07-17T10:21:41.251180Z", - "shell.execute_reply": "2025-07-17T10:21:41.251016Z" - } - }, - "outputs": [], - "source": [ - "transport_2 = Model(\n", - " m,\n", - " name=\"transport2\",\n", - " equations=m.getEquations(),\n", - " problem=\"LP\",\n", - " sense=Sense.MIN,\n", - " objective=obj,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "More information on the usage of a GAMSPy `Model` can be found in the [model section](https://gamspy.readthedocs.io/en/latest/user/basics/model.html) of our user guide." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Solve\n", - "\n", - "Upon defining the GAMSPy ``Model``, it's ready for being solved. The ``solve()`` statement triggers the generation of the specific model instance, creates suitable data structures for the solver, and invokes the solver. To view solver output in the console, the ``sys`` library can be used, passing the ``output=sys.stdout`` attribute to ``transport.solve()``.\n", - "\n", - "**Note**: The following cell contains the two most important pieces to get a GAMSPy model being solved by NVIDIA cuOpt:\n", - "1. Disable solver validation via `gp.set_options({\"SOLVER_VALIDATION\": 0})` as the solver is manually \"plugged into\" GAMSPy\n", - "2. Choose cuOpt as solver with `transport.solve(solver=\"cuopt\", ...)`" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": { - "execution": { - "iopub.execute_input": "2025-07-17T10:21:41.251912Z", - "iopub.status.busy": "2025-07-17T10:21:41.251772Z", - "iopub.status.idle": "2025-07-17T10:21:41.453729Z", - "shell.execute_reply": "2025-07-17T10:21:41.453525Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- Job _B03rB9R3R9SbAJSrApt6kQ.gms Start 07/17/25 12:21:41 50.2.0 d60bb663 LEX-LEG x86 64bit/Linux\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- Applying:\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmsprmun.txt\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gamsconfig.yaml\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- GAMS Parameters defined\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " LP cuopt\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Input /tmp/tmpz1ajkw_x/_B03rB9R3R9SbAJSrApt6kQ.gms\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Output /tmp/tmpz1ajkw_x/_B03rB9R3R9SbAJSrApt6kQ.lst\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " ScrDir /tmp/tmpz1ajkw_x/tmpe0l7t8w9/\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " SysDir /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " LogOption 3\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Trace /tmp/tmpz1ajkw_x/_B03rB9R3R9SbAJSrApt6kQ.txt\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " License /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gamslice.txt\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " OptFile 0\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " OptDir /tmp/tmpz1ajkw_x/\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " LimRow 0\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " LimCol 0\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " TraceOpt 3\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " GDX /tmp/tmpz1ajkw_x/_B03rB9R3R9SbAJSrApt6kQout.gdx\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " SolPrint 0\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " PreviousWork 1\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " gdxSymbols newOrChanged\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "System information: 12 physical cores and 62 Gb physical memory detected\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- Starting compilation\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- _B03rB9R3R9SbAJSrApt6kQ.gms(71) 4 Mb\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- Starting execution: elapsed 0:00:00.000\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- Generating LP model transport\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- _B03rB9R3R9SbAJSrApt6kQ.gms(142) 4 Mb\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- 6 rows 7 columns 19 non-zeroes\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- Range statistics (absolute non-zero finite values)\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- RHS [min, max] : [ 2.750E+02, 6.000E+02] - Zero values observed as well\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- Bound [min, max] : [ NA, NA] - Zero values observed as well\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- Matrix [min, max] : [ 1.260E-01, 1.000E+00]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- Executing CUOPT (Solvelink=2): elapsed 0:00:00.000\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Setting parameter log_file to /tmp/tmpz1ajkw_x/tmpe0l7t8w9/cuopt.dat\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Solving a problem with 5 constraints 6 variables (0 integers) and 12 nonzeros\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Objective offset -0.000000 scaling_factor 1.000000\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Running concurrent\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Dual simplex finished in 0.00 seconds\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " Iter Primal Obj. Dual Obj. Gap Primal Res. Dual Res. Time\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " 0 +0.00000000e+00 +0.00000000e+00 0.00e+00 5.21e+02 0.00e+00 0.010s\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "PDLP finished\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Concurrent time: 0.012s\n" - ] + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
distance
fromto
seattlenew-york2.5
chicago1.7
topeka1.8
san-diegonew-york2.5
chicago1.8
topeka1.4
\n", + "
" + ], + "text/plain": [ + " distance\n", + "from to \n", + "seattle new-york 2.5\n", + " chicago 1.7\n", + " topeka 1.8\n", + "san-diego new-york 2.5\n", + " chicago 1.8\n", + " topeka 1.4" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "distances = pd.DataFrame(\n", + " [\n", + " [\"seattle\", \"new-york\", 2.5],\n", + " [\"seattle\", \"chicago\", 1.7],\n", + " [\"seattle\", \"topeka\", 1.8],\n", + " [\"san-diego\", \"new-york\", 2.5],\n", + " [\"san-diego\", \"chicago\", 1.8],\n", + " [\"san-diego\", \"topeka\", 1.4],\n", + " ],\n", + " columns=[\"from\", \"to\", \"distance\"],\n", + ").set_index([\"from\", \"to\"])\n", + "\n", + "distances" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.092111Z", + "iopub.status.busy": "2025-07-17T10:21:41.092042Z", + "iopub.status.idle": "2025-07-17T10:21:41.093337Z", + "shell.execute_reply": "2025-07-17T10:21:41.093174Z" + } + }, + "outputs": [], + "source": [ + "freight_cost = 90" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Symbol Declaration\n", + "\n", + "In line with our systematic breakdown of the transportation problem into sets, parameters, variables, and constraints, we will adopt a similar approach to define the problem as a GAMSPy `Model`. To do so, it is essential to import the `gamspy` library initially." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.093948Z", + "iopub.status.busy": "2025-07-17T10:21:41.093881Z", + "iopub.status.idle": "2025-07-17T10:21:41.163655Z", + "shell.execute_reply": "2025-07-17T10:21:41.163440Z" + } + }, + "outputs": [], + "source": [ + "from gamspy import Container, Set, Parameter, Variable, Equation, Model, Sum, Sense" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Container\n", + "\n", + "Before we proceed further, let's create a `Container` to encapsulate all the relevant information for our GAMSPy ``Model``. This ``Container`` acts as a centralized hub, gathering essential data, sets, parameters, variables, and constraints, providing a clear structure for our optimization problem." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.164784Z", + "iopub.status.busy": "2025-07-17T10:21:41.164605Z", + "iopub.status.idle": "2025-07-17T10:21:41.172679Z", + "shell.execute_reply": "2025-07-17T10:21:41.172515Z" + } + }, + "outputs": [], + "source": [ + "m = Container()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Sets\n", + "\n", + "Sets serve as the fundamental building blocks of a GAMSPy ``Model``, directly corresponding to the indices in the algebraic representations of models. In our transportation problem context, we have defined the following indices:\n", + "\n", + "- $i$ = plants\n", + "- $j$ = markets\n", + "\n", + "For detailed guidance on using sets, please refer to the [set section](https://gamspy.readthedocs.io/en/latest/user/basics/set.html) of our user guide.\n", + "\n", + "There a two ways to declare sets:\n", + "\n", + "1. Separate declaration and data assignment\n", + "2. Combine declaration and data assignment\n", + "\n", + "#### Separate declaration and data assignment\n" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.173454Z", + "iopub.status.busy": "2025-07-17T10:21:41.173302Z", + "iopub.status.idle": "2025-07-17T10:21:41.179619Z", + "shell.execute_reply": "2025-07-17T10:21:41.179429Z" + } + }, + "outputs": [], + "source": [ + "i = Set(container=m, name=\"i\", description=\"plants\")\n", + "i.setRecords(capacities.index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Combine declaration and data assignment\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.180411Z", + "iopub.status.busy": "2025-07-17T10:21:41.180278Z", + "iopub.status.idle": "2025-07-17T10:21:41.190480Z", + "shell.execute_reply": "2025-07-17T10:21:41.190323Z" }, + "tags": [] + }, + "outputs": [], + "source": [ + "j = Set(container=m, name=\"j\", description=\"markets\", records=demands.index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The effect of using the above `Set` statements is that we declared two sets, namely $i$ and $j$. Additionally, we provided descriptions to elaborate on their meaning, enhancing the readability of our ``Model``. Lastly, we assigned members to the sets, establishing a clear connection between the abstract sets and their real-world counterparts.\n", + "\n", + "$i$ = {Seattle, San Diego}\n", + "\n", + "$j$ = {New York, Chicago, Topeka}\n", + "\n", + "To verify the content of a set, you can use `.records`." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.191227Z", + "iopub.status.busy": "2025-07-17T10:21:41.191108Z", + "iopub.status.idle": "2025-07-17T10:21:41.193520Z", + "shell.execute_reply": "2025-07-17T10:21:41.193371Z" + } + }, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Solved with dual simplex\n" - ] - }, + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
unielement_text
0seattle
1san-diego
\n", + "
" + ], + "text/plain": [ + " uni element_text\n", + "0 seattle \n", + "1 san-diego " + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "i.records" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.194209Z", + "iopub.status.busy": "2025-07-17T10:21:41.194141Z", + "iopub.status.idle": "2025-07-17T10:21:41.196323Z", + "shell.execute_reply": "2025-07-17T10:21:41.196172Z" + } + }, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Status: Optimal Objective: 1.53675000e+02 Iterations: 4 Time: 0.012s\n" - ] - }, + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
unielement_text
0new-york
1chicago
2topeka
\n", + "
" + ], + "text/plain": [ + " uni element_text\n", + "0 new-york \n", + "1 chicago \n", + "2 topeka " + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "j.records" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Parameters\n", + "\n", + "Declaring parameters involves using `Parameter`. Each parameter is assigned a name and a description. Note that parameter $a_i$ is indexed by $i$. To accommodate these indices, we include the `domain` attribute, pointing to the corresponding set.\n", + "\n", + "It is worth mentioning that, similar to sets, you have the flexibility to either combine or separate the declaration and data assignment steps. For convenience, we will proceed by combining the declaration and data assignment.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.196997Z", + "iopub.status.busy": "2025-07-17T10:21:41.196933Z", + "iopub.status.idle": "2025-07-17T10:21:41.201694Z", + "shell.execute_reply": "2025-07-17T10:21:41.201542Z" + } + }, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- Reading solution for model transport\n" - ] - }, + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cityvalue
0seattle350.0
1san-diego600.0
\n", + "
" + ], + "text/plain": [ + " city value\n", + "0 seattle 350.0\n", + "1 san-diego 600.0" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a = Parameter(\n", + " container=m, \n", + " name=\"a\",\n", + " domain=i,\n", + " description=\"supply of commodity at plant i (in cases)\",\n", + " records=capacities.reset_index(),\n", + ")\n", + "a.records" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.202335Z", + "iopub.status.busy": "2025-07-17T10:21:41.202270Z", + "iopub.status.idle": "2025-07-17T10:21:41.206850Z", + "shell.execute_reply": "2025-07-17T10:21:41.206694Z" + } + }, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- Executing after solve: elapsed 0:00:00.194\n" - ] - }, + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cityvalue
0new-york325.0
1chicago300.0
2topeka275.0
\n", + "
" + ], + "text/plain": [ + " city value\n", + "0 new-york 325.0\n", + "1 chicago 300.0\n", + "2 topeka 275.0" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b = Parameter(\n", + " container=m,\n", + " name=\"b\",\n", + " domain=j,\n", + " description=\"demand for commodity at market j (in cases)\",\n", + " records=demands.reset_index(),\n", + ")\n", + "b.records" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.207532Z", + "iopub.status.busy": "2025-07-17T10:21:41.207468Z", + "iopub.status.idle": "2025-07-17T10:21:41.209778Z", + "shell.execute_reply": "2025-07-17T10:21:41.209610Z" + } + }, + "outputs": [], + "source": [ + "c = Parameter(\n", + " container=m,\n", + " name=\"c\",\n", + " domain=[i, j],\n", + " description=\"cost per unit of shipment between plant i and market j\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The cost per unit of shipment between plant $i$ and market $j$ is derived from the distance between $i$ and $j$ and can be calculated as follows:\n", + "\n", + "$c_{ij} = \\frac{90 \\cdot d_{ij}}{1000}$,\n", + "\n", + "where $d_{ij}$ denotes the distance between $i$ and $j$.\n", + "\n", + "We have two options to calculate $c_{ij}$ and assign the data to the GAMSPy parameter:\n", + "\n", + "1. Python assignment - calculation in Python, e.g., using Pandas and `.setRecords()`\n", + "2. GAMSPy assignment - calculation in GAMSPy\n", + "\n", + "#### Python Assignment" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.210541Z", + "iopub.status.busy": "2025-07-17T10:21:41.210390Z", + "iopub.status.idle": "2025-07-17T10:21:41.213168Z", + "shell.execute_reply": "2025-07-17T10:21:41.213001Z" + } + }, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- _B03rB9R3R9SbAJSrApt6kQ.gms(143) 4 Mb\n" - ] - }, + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
distance
fromto
seattlenew-york0.225
chicago0.153
topeka0.162
san-diegonew-york0.225
chicago0.162
topeka0.126
\n", + "
" + ], + "text/plain": [ + " distance\n", + "from to \n", + "seattle new-york 0.225\n", + " chicago 0.153\n", + " topeka 0.162\n", + "san-diego new-york 0.225\n", + " chicago 0.162\n", + " topeka 0.126" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cost = freight_cost * distances / 1000\n", + "cost" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.213745Z", + "iopub.status.busy": "2025-07-17T10:21:41.213681Z", + "iopub.status.idle": "2025-07-17T10:21:41.218945Z", + "shell.execute_reply": "2025-07-17T10:21:41.218784Z" + } + }, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- _B03rB9R3R9SbAJSrApt6kQ.gms(201) 4 Mb\n" - ] - }, + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
fromtovalue
0seattlenew-york0.225
1seattlechicago0.153
2seattletopeka0.162
3san-diegonew-york0.225
4san-diegochicago0.162
5san-diegotopeka0.126
\n", + "
" + ], + "text/plain": [ + " from to value\n", + "0 seattle new-york 0.225\n", + "1 seattle chicago 0.153\n", + "2 seattle topeka 0.162\n", + "3 san-diego new-york 0.225\n", + "4 san-diego chicago 0.162\n", + "5 san-diego topeka 0.126" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c.setRecords(cost.reset_index())\n", + "c.records" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### GAMSPy Assignment\n", + "\n", + "For the direct assignment we need to declare a new ``Parameter`` denoting the distances between $i$ and $j$.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.219662Z", + "iopub.status.busy": "2025-07-17T10:21:41.219599Z", + "iopub.status.idle": "2025-07-17T10:21:41.225144Z", + "shell.execute_reply": "2025-07-17T10:21:41.224999Z" + } + }, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "--- GDX File /tmp/tmpz1ajkw_x/_B03rB9R3R9SbAJSrApt6kQout.gdx\n" - ] - }, + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
fromtovalue
0seattlenew-york2.5
1seattlechicago1.7
2seattletopeka1.8
3san-diegonew-york2.5
4san-diegochicago1.8
5san-diegotopeka1.4
\n", + "
" + ], + "text/plain": [ + " from to value\n", + "0 seattle new-york 2.5\n", + "1 seattle chicago 1.7\n", + "2 seattle topeka 1.8\n", + "3 san-diego new-york 2.5\n", + "4 san-diego chicago 1.8\n", + "5 san-diego topeka 1.4" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "d = Parameter(\n", + " container=m,\n", + " name=\"d\",\n", + " domain=[i, j],\n", + " description=\"distance between plant i and market j\",\n", + " records=distances.reset_index(),\n", + ")\n", + "d.records" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.225778Z", + "iopub.status.busy": "2025-07-17T10:21:41.225715Z", + "iopub.status.idle": "2025-07-17T10:21:41.230168Z", + "shell.execute_reply": "2025-07-17T10:21:41.229995Z" + } + }, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "*** Status: Normal completion\n" - ] - }, + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ijvalue
0seattlenew-york0.225
1seattlechicago0.153
2seattletopeka0.162
3san-diegonew-york0.225
4san-diegochicago0.162
5san-diegotopeka0.126
\n", + "
" + ], + "text/plain": [ + " i j value\n", + "0 seattle new-york 0.225\n", + "1 seattle chicago 0.153\n", + "2 seattle topeka 0.162\n", + "3 san-diego new-york 0.225\n", + "4 san-diego chicago 0.162\n", + "5 san-diego topeka 0.126" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c[i, j] = freight_cost * d[i, j] / 1000\n", + "c.records" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Further information on the usage of parameters can be found in our [parameter section](https://gamspy.readthedocs.io/en/latest/user/basics/parameter.html) of the user guide." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Variables\n", + "\n", + "GAMSPy variables are declared using `Variable`. Each ``Variable`` is assigned a name, a domain if necessary, a type, and, optionally, a description." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.230884Z", + "iopub.status.busy": "2025-07-17T10:21:41.230819Z", + "iopub.status.idle": "2025-07-17T10:21:41.233170Z", + "shell.execute_reply": "2025-07-17T10:21:41.233016Z" + } + }, + "outputs": [], + "source": [ + "x = Variable(\n", + " container=m,\n", + " name=\"x\",\n", + " domain=[i, j],\n", + " type=\"Positive\",\n", + " description=\"amount of commodity to ship from plant i to market j\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This statement results in the declaration of a shipment variable for each (i,j) pair.\n", + "\n", + "More information on variables can be found in the [variable section](https://gamspy.readthedocs.io/en/latest/user/basics/variable.html) of our user guide." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Equations\n", + "A GAMSPy ``Equation`` must be declared and defined in two separate statements. The format of the declaration is the same as for other GAMSPy symbols. First comes the keyword, `Equation` in this case, followed by the name, domain and text. The transportation problem has two constraints:\n", + "\n", + "Supply: observe supply limit at plant $i$: $\\sum_j x_{ij} \\le a_i \\: \\forall i$\n", + "\n", + "Demand: satisfy demand at market $j$: $\\sum_i x_{ij} \\ge b_j \\: \\forall j$" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.233875Z", + "iopub.status.busy": "2025-07-17T10:21:41.233798Z", + "iopub.status.idle": "2025-07-17T10:21:41.237181Z", + "shell.execute_reply": "2025-07-17T10:21:41.237005Z" + } + }, + "outputs": [], + "source": [ + "supply = Equation(\n", + " container=m, name=\"supply\", domain=i, description=\"observe supply limit at plant i\"\n", + ")\n", + "demand = Equation(\n", + " container=m, name=\"demand\", domain=j, description=\"satisfy demand at market j\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The components of an ``Equation`` definition are:\n", + "1. The Python variable of the ``Equation`` being defined\n", + "2. The domain (optional)\n", + "3. Domain restricting conditions (optional)\n", + "4. A `=` sign\n", + "5. Left hand side expression\n", + "6. Relational operator (`==`, `<=`, `>=`)\n", + "7. The right hand side expression.\n", + "\n", + "The ``Equation`` definition for the supply constraint of the transportation problem is implemented as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.237863Z", + "iopub.status.busy": "2025-07-17T10:21:41.237785Z", + "iopub.status.idle": "2025-07-17T10:21:41.240437Z", + "shell.execute_reply": "2025-07-17T10:21:41.240285Z" + } + }, + "outputs": [], + "source": [ + "supply[i] = Sum(j, x[i, j]) <= a[i]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the same logic as above, we can define the demand equation as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.241111Z", + "iopub.status.busy": "2025-07-17T10:21:41.241033Z", + "iopub.status.idle": "2025-07-17T10:21:41.243421Z", + "shell.execute_reply": "2025-07-17T10:21:41.243270Z" + } + }, + "outputs": [], + "source": [ + "demand[j] = Sum(i, x[i, j]) >= b[j]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "More information on equations is given in the [equation section](https://gamspy.readthedocs.io/en/latest/user/basics/equation.html) of our user guide." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Objective\n", + "The objective function of a GAMSPy ``Model`` does not require a separate ``Equation`` declaration. You can assign the objective expression to a Python variable or use it directly in the ``Model()`` statement of the [next section](#model).\n" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.244117Z", + "iopub.status.busy": "2025-07-17T10:21:41.244038Z", + "iopub.status.idle": "2025-07-17T10:21:41.245432Z", + "shell.execute_reply": "2025-07-17T10:21:41.245247Z" + } + }, + "outputs": [], + "source": [ + "obj = Sum((i, j), c[i, j] * x[i, j])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model\n", + "\n", + "A GAMSPy `Model()` consolidates constraints, an objective function, a sense (minimize, maximize, and feasibility), and a problem type. It also possesses a name and is associated with a ``Container``.\n", + "\n", + "To define our transportation problem as a GAMSPy ``Model``, we assign it to a Python variable, link it to our ``Container`` (populated with symbols and data), name it \"transport\", specify the equations, set the problem type as linear program (LP), specify the sense of the objective function (``Sense.MIN``), and point to the objective expression.\n", + "\n", + "GAMSPy allows two alternatives to assign equations to a `Model`:\n", + "1. Using a list of equations,\n", + "2. Retrieving _all_ equations by calling `m.getEquations()`.\n", + "\n", + "### Using a List of Equations\n", + "Using a list of equations is especially useful if you want to define multiple GAMSPy ``Model``s with a subset of the equations in your ``Container``. For the transportation problem this can be done as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.246093Z", + "iopub.status.busy": "2025-07-17T10:21:41.246032Z", + "iopub.status.idle": "2025-07-17T10:21:41.248358Z", + "shell.execute_reply": "2025-07-17T10:21:41.248217Z" + } + }, + "outputs": [], + "source": [ + "transport = Model(\n", + " m,\n", + " name=\"transport\",\n", + " equations=[supply, demand],\n", + " problem=\"LP\",\n", + " sense=Sense.MIN,\n", + " objective=obj,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Retrieving all Equations\n", + "Using `m.getEquations()` is especially convenient if you want to include all equations of your ``Container`` to be associated with your model. For the transportation problem this can be done as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.248970Z", + "iopub.status.busy": "2025-07-17T10:21:41.248907Z", + "iopub.status.idle": "2025-07-17T10:21:41.251180Z", + "shell.execute_reply": "2025-07-17T10:21:41.251016Z" + } + }, + "outputs": [], + "source": [ + "transport_2 = Model(\n", + " m,\n", + " name=\"transport2\",\n", + " equations=m.getEquations(),\n", + " problem=\"LP\",\n", + " sense=Sense.MIN,\n", + " objective=obj,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "More information on the usage of a GAMSPy `Model` can be found in the [model section](https://gamspy.readthedocs.io/en/latest/user/basics/model.html) of our user guide." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solve\n", + "\n", + "Upon defining the GAMSPy ``Model``, it's ready for being solved. The ``solve()`` statement triggers the generation of the specific model instance, creates suitable data structures for the solver, and invokes the solver. To view solver output in the console, the ``sys`` library can be used, passing the ``output=sys.stdout`` attribute to ``transport.solve()``.\n", + "\n", + "**Note**: The following cell contains the two most important pieces to get a GAMSPy model being solved by NVIDIA cuOpt:\n", + "1. Disable solver validation via `gp.set_options({\"SOLVER_VALIDATION\": 0})` as the solver is manually \"plugged into\" GAMSPy\n", + "2. Choose cuOpt as solver with `transport.solve(solver=\"cuopt\", ...)`" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "execution": { + "iopub.execute_input": "2025-07-17T10:21:41.251912Z", + "iopub.status.busy": "2025-07-17T10:21:41.251772Z", + "iopub.status.idle": "2025-07-17T10:21:41.453729Z", + "shell.execute_reply": "2025-07-17T10:21:41.453525Z" + } + }, + "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "--- Job _B03rB9R3R9SbAJSrApt6kQ.gms Stop 07/17/25 12:21:41 elapsed 0:00:00.194\n" + "--- Job _KOUVa9lhTvG5uTjqvKL_Uw.gms Start 07/17/25 17:31:15 50.2.0 d60bb663 LEX-LEG x86 64bit/Linux\n", + "--- Applying:\n", + " /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gmsprmun.txt\n", + " /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gamsconfig.yaml\n", + "--- GAMS Parameters defined\n", + " LP cuopt\n", + " Input /tmp/tmpn3ks7sgm/_KOUVa9lhTvG5uTjqvKL_Uw.gms\n", + " Output /tmp/tmpn3ks7sgm/_KOUVa9lhTvG5uTjqvKL_Uw.lst\n", + " ScrDir /tmp/tmpn3ks7sgm/tmp_wk_zgjf/\n", + " SysDir /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/\n", + " LogOption 3\n", + " Trace /tmp/tmpn3ks7sgm/_KOUVa9lhTvG5uTjqvKL_Uw.txt\n", + " License /home/gamsuser/andre/.venv/lib/python3.12/site-packages/gamspy_base/gamslice.txt\n", + " OptFile 0\n", + " OptDir /tmp/tmpn3ks7sgm/\n", + " LimRow 0\n", + " LimCol 0\n", + " TraceOpt 3\n", + " GDX /tmp/tmpn3ks7sgm/_KOUVa9lhTvG5uTjqvKL_Uwout.gdx\n", + " SolPrint 0\n", + " PreviousWork 1\n", + " gdxSymbols newOrChanged\n", + "System information: 12 physical cores and 62 Gb physical memory detected\n", + "--- Starting compilation\n", + "--- _KOUVa9lhTvG5uTjqvKL_Uw.gms(71) 4 Mb\n", + "--- Starting execution: elapsed 0:00:00.000\n", + "--- Generating LP model transport\n", + "--- _KOUVa9lhTvG5uTjqvKL_Uw.gms(142) 4 Mb\n", + "--- 6 rows 7 columns 19 non-zeroes\n", + "--- Range statistics (absolute non-zero finite values)\n", + "--- RHS [min, max] : [ 2.750E+02, 6.000E+02] - Zero values observed as well\n", + "--- Bound [min, max] : [ NA, NA] - Zero values observed as well\n", + "--- Matrix [min, max] : [ 1.260E-01, 1.000E+00]\n", + "--- Executing CUOPT (Solvelink=2): elapsed 0:00:00.001\n", + "Setting parameter log_file to /tmp/tmpn3ks7sgm/tmp_wk_zgjf/cuopt.dat\n", + "Solving a problem with 5 constraints 6 variables (0 integers) and 12 nonzeros\n", + "Objective offset -0.000000 scaling_factor 1.000000\n", + "Running concurrent\n", + "\n", + "Dual simplex finished in 0.00 seconds\n", + " Iter Primal Obj. Dual Obj. Gap Primal Res. Dual Res. Time\n", + " 0 +0.00000000e+00 +0.00000000e+00 0.00e+00 5.21e+02 0.00e+00 0.010s\n", + "PDLP finished\n", + "Concurrent time: 0.012s\n", + "Solved with dual simplex\n", + "Status: Optimal Objective: 1.53675000e+02 Iterations: 4 Time: 0.012s\n", + "--- Reading solution for model transport\n", + "--- Executing after solve: elapsed 0:00:00.174\n", + "--- _KOUVa9lhTvG5uTjqvKL_Uw.gms(201) 4 Mb\n", + "--- GDX File /tmp/tmpn3ks7sgm/_KOUVa9lhTvG5uTjqvKL_Uwout.gdx\n", + "*** Status: Normal completion\n", + "--- Job _KOUVa9lhTvG5uTjqvKL_Uw.gms Stop 07/17/25 17:31:15 elapsed 0:00:00.174\n" ] }, { @@ -2668,7 +1634,7 @@ "0 LP CUOPT 0.0 " ] }, - "execution_count": 26, + "execution_count": 55, "metadata": {}, "output_type": "execute_result" } @@ -2692,7 +1658,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 56, "metadata": { "execution": { "iopub.execute_input": "2025-07-17T10:21:41.454555Z", @@ -2806,7 +1772,7 @@ " topeka 275.0 0.0000 0.0 inf 1.0" ] }, - "execution_count": 27, + "execution_count": 56, "metadata": {}, "output_type": "execute_result" } @@ -2832,7 +1798,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 57, "metadata": { "execution": { "iopub.execute_input": "2025-07-17T10:21:41.459304Z", @@ -2848,7 +1814,7 @@ "153.675" ] }, - "execution_count": 28, + "execution_count": 57, "metadata": {}, "output_type": "execute_result" } From ed35e7fc026a7496eed75c721ac55dbee7b4005a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Schnabel?= Date: Thu, 17 Jul 2025 17:34:45 +0200 Subject: [PATCH 5/7] Add comment suggesting no -q to troubleshoot pip install issues --- GAMSPy_integration_example/trnsport_cuopt.ipynb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GAMSPy_integration_example/trnsport_cuopt.ipynb b/GAMSPy_integration_example/trnsport_cuopt.ipynb index b7591d8..6d5ac7e 100644 --- a/GAMSPy_integration_example/trnsport_cuopt.ipynb +++ b/GAMSPy_integration_example/trnsport_cuopt.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 30, + "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-07-17T10:21:15.883029Z", @@ -42,6 +42,7 @@ } ], "source": [ + "# remove -q to debug issues with pip installs\n", "!pip install -q --extra-index-url=https://pypi.nvidia.com cuopt-cu12==25.5.* nvidia-cuda-runtime-cu12==12.8.* nvidia-nvjitlink-cu12\n", "!pip install -q gamspy\n", "import subprocess\n", From 0049a0786ceb6af762e840df41391ea66eb4fdb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Schnabel?= Date: Thu, 17 Jul 2025 17:50:11 +0200 Subject: [PATCH 6/7] Remove README markdown file for GAMSPy integration example notebook --- GAMSPy_integration_example/README.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 GAMSPy_integration_example/README.md diff --git a/GAMSPy_integration_example/README.md b/GAMSPy_integration_example/README.md deleted file mode 100644 index efbe351..0000000 --- a/GAMSPy_integration_example/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## GAMSPy cuOpt integration example notebook - -### How to run the notebook -- Setup and activate a Python environment in the `cuopt-examples` root directory e.g. with `python -m venv .venv` and `source .venv/bin/activate` -- Install requirements `pip install -r requirements.txt` -- Run this notebook from a GUI or update its cells in the command line via `jupyter nbconvert --to notebook --execute --inplace trnsport_cuopt.ipynb` -- The first cell takes care of installing cuOpt runtime, GAMSPy, and the solver link. Skips most parts when it's already there. From 7d28e727e6728a07f2bb347a52a1dd86717e6f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Schnabel?= Date: Thu, 17 Jul 2025 18:08:05 +0200 Subject: [PATCH 7/7] Add license notice at end of notebook --- GAMSPy_integration_example/trnsport_cuopt.ipynb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/GAMSPy_integration_example/trnsport_cuopt.ipynb b/GAMSPy_integration_example/trnsport_cuopt.ipynb index 6d5ac7e..68c15f6 100644 --- a/GAMSPy_integration_example/trnsport_cuopt.ipynb +++ b/GAMSPy_integration_example/trnsport_cuopt.ipynb @@ -1823,6 +1823,15 @@ "source": [ "transport.objective_value" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: MIT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n", + "\n", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + ] } ], "metadata": {