diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..362d6ff --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,57 @@ +name: Bug report +description: Wrong results, crashes or installation problems with the cuOpt link +labels: [bug] +body: + - type: textarea + id: description + attributes: + label: What happened? + description: What did you expect, and what happened instead? + validations: + required: true + - type: textarea + id: reproduce + attributes: + label: How to reproduce + description: A small GAMS or GAMSPy model and the options (e.g. `cuopt.opt`) that trigger the problem. + validations: + required: false + - type: input + id: release + attributes: + label: cuOpt link release + placeholder: e.g. v0.0.8e + validations: + required: true + - type: input + id: gams + attributes: + label: GAMS or GAMSPy version + placeholder: e.g. GAMS 54.5.0 or GAMSPy 1.28.1 + validations: + required: true + - type: dropdown + id: cuda + attributes: + label: CUDA version of the link + options: + - CUDA 12 + - CUDA 13 + validations: + required: true + - type: input + id: system + attributes: + label: GPU, driver and OS + description: The output of `nvidia-smi` shows the GPU and driver version. + placeholder: e.g. NVIDIA L4, driver 580.65, Ubuntu 24.04 x86_64 (or WSL2) + validations: + required: true + - type: textarea + id: log + attributes: + label: Solver log + description: The log of the solve, including the lines starting with `GAMS/cuOpt link was built against` and `cuOpt version`. + render: text + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..dbae8a0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: true +contact_links: + - name: GAMS forum + url: https://forum.gams.com/ + about: Questions about modeling with GAMS or GAMSPy + - name: Security issue + url: https://github.com/GAMS-dev/cuoptlink-builder/blob/main/SECURITY.md + about: Please report security problems privately, not as a public issue diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..43e886b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,39 @@ +# Contributing + +Thanks for helping improve the GAMS/cuOpt solver link! Bug reports, fixes and new cuOpt options are all welcome. + +## Questions and bug reports + +- Usage questions about GAMS or GAMSPy are best asked in the [GAMS forum](https://forum.gams.com/) or via support@gams.com. +- Bugs of the cuOpt link itself go into a [GitHub issue](https://github.com/GAMS-dev/cuoptlink-builder/issues/new/choose). Please include the versions and the solver log the bug report form asks for, and a small model that reproduces the problem if possible. +- Please report security issues privately, see [SECURITY.md](SECURITY.md). + +## Building the link locally + +The link (`gmscuopt.c`) is built against the GAMS C API from a GAMS distribution and the cuOpt libraries from NVIDIA's Python wheels: + +```bash +python -m venv .venv +.venv/bin/pip install --extra-index-url=https://pypi.nvidia.com 'cuopt-cu13==26.8.*' +GAMSDIST=/path/to/gams ./build-link.sh +``` + +`build-link.sh` compiles `gmscuopt.out` for CUDA 13, sets its RPATH (needs `gcc` and `patchelf`), and copies it together with the cuOpt and CUDA libraries and the files from `assets/` into `$GAMSDIST`. Since that includes `gamsconfig_cuopt.yaml`, merge it into `gamsconfig.yaml` as described in the [README](README.md#manual-installation). The CI workflows in `.github/workflows` build the release archives for CUDA 12 and 13 on x86_64 and arm64. + +New or changed cuOpt options go into `assets/optcuopt.def` and have to be passed on to cuOpt in `gmscuopt.c`. + +## Testing + +| Command | What it checks | GPU needed | +|---|---|---| +| `python3 tests/test-fetch-cuoptlink.py -v` | Unit tests of the installer script `fetch-cuoptlink.py` | no | +| `examples/models/regression_tests/run_tests.sh` | Self-checking models for duals, statuses, options, error handling and capability checks | yes | +| `python3 tests/test-gamslib-cuopt.py` | Solves the models in `tests/baseline.txt` from the GAMS model library and compares the objectives with CPLEX | yes | + +The GPU tests use the GAMS system found in your `PATH`, with the link installed. + +## Pull requests + +- Keep each pull request focused on one change and describe how you tested it. +- If you fix a bug in the link, add or extend a model in `examples/models/regression_tests` that would have caught it. +- By contributing you agree that your contribution is licensed under the [Apache License 2.0](LICENSE). diff --git a/README.md b/README.md index bc3cf0d..4f5d11c 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,40 @@ You can get more details and tips by reading the blog post ["GPU-Accelerated Opt Supported model types are LP, MIP, RMIP, QCP, RMIQCP. QCP and RMIQCP models must be convex. Mixed-integer quadratic models (MIQCP) are not supported, since cuOpt's MIP solver only handles linear objectives and constraints. +## Quickstart + +Install GAMSPy and the cuOpt link (including the CUDA runtime libraries) into GAMSPy's GAMS system directory: + +```bash +pip install gamspy +curl -O https://raw.githubusercontent.com/GAMS-dev/cuoptlink-builder/main/fetch-cuoptlink.py +python fetch-cuoptlink.py install -g "$(gamspy show base)" --cuda-runtime +``` + +Then pick `cuopt` as solver: + +```python +import gamspy as gp + +gp.set_options({"SOLVER_VALIDATION": 0}) # cuOpt is added to GAMSPy by hand + +m = gp.Container() +x = gp.Variable(m, "x", type="positive") +y = gp.Variable(m, "y", type="positive") +e1 = gp.Equation(m, "e1", definition=x + 2 * y >= 2) +e2 = gp.Equation(m, "e2", definition=3 * x + y >= 3) + +model = gp.Model(m, "demo", equations=[e1, e2], problem="LP", sense="min", objective=x + y) +model.solve(solver="cuopt") +print(model.objective_value) # 1.4 +``` + +For a standalone GAMS system pass its directory to `-g` instead and see [Test the setup](#test-the-setup). To try it without a local setup, open one of the [example notebooks](#notebooks) in Google Colab. + +## Performance + +cuOpt's GPU-based PDLP method pays off on large LPs. In NVIDIA's [benchmark on Mittelmann's LP test set](https://developer.nvidia.com/blog/accelerate-large-linear-programming-problems-with-nvidia-cuopt/) (October 2024, H100 SXM GPU, no presolve), cuOpt was faster than a state-of-the-art CPU LP solver on 60% of the instances, more than 10x faster on 20%, and up to 5000x faster on a large multi-commodity flow instance, while 8 of the 49 public instances hit the one-hour time limit. On small models the GPU overhead usually dominates, so compare on your own instances. The default `method 0` (concurrent) runs PDLP, dual simplex and barrier in parallel. + ## Requirements - **Operating System:** Linux, Windows 11 through WSL2 @@ -86,8 +120,10 @@ gams trnsport lp cuopt ### Notebooks -- [examples/trnsport_cuopt.ipynb](examples/trnsport_cuopt.ipynb) for CUDA 12 on x86_64 -- [examples/trnsport_cuopt.ipynb](examples/trnsport_cuopt_cu13.ipynb) for CUDA 13 on x86_64 +- [examples/trnsport_cuopt.ipynb](examples/trnsport_cuopt.ipynb) for CUDA 12 [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/GAMS-dev/cuoptlink-builder/blob/main/examples/trnsport_cuopt.ipynb) +- [examples/trnsport_cuopt_cu13.ipynb](examples/trnsport_cuopt_cu13.ipynb) for CUDA 13 [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/GAMS-dev/cuoptlink-builder/blob/main/examples/trnsport_cuopt_cu13.ipynb) + +In Google Colab, select a GPU runtime first (*Runtime → Change runtime type*). If unsure, start with the CUDA 12 notebook, which also works with older NVIDIA drivers. ### GAMS models diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..28ceea7 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,15 @@ +# Security policy + +## Supported versions + +Security fixes are only made for the [latest release](https://github.com/GAMS-dev/cuoptlink-builder/releases/latest) of the cuOpt link. + +## Reporting a vulnerability + +Please do **not** open a public GitHub issue for security problems. Instead, email support@gams.com with: + +- a description of the problem and its impact, +- steps to reproduce it, +- the affected release and your GAMS/GAMSPy version. + +We will confirm receipt and keep you updated on the fix. Vulnerabilities in NVIDIA cuOpt or the CUDA libraries themselves should be reported to [NVIDIA](https://www.nvidia.com/en-us/security/). diff --git a/examples/README.md b/examples/README.md index d37a2db..c62784e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,6 +1,11 @@ ## GAMSPy cuOpt integration example notebook -### How to run the notebook +### Run in Google Colab +- CUDA 12: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/GAMS-dev/cuoptlink-builder/blob/main/examples/trnsport_cuopt.ipynb) +- CUDA 13: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/GAMS-dev/cuoptlink-builder/blob/main/examples/trnsport_cuopt_cu13.ipynb) +- Select a GPU runtime first (*Runtime → Change runtime type*), then run all cells. + +### How to run the notebook locally - Setup and activate a Python environment 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`