From 802d67817d2b53a21677295fe0c5db8a9f79e333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Schnabel?= Date: Tue, 15 Sep 2026 15:10:14 +0200 Subject: [PATCH 1/3] Pull nightly cuopt wheels in build workflows Track NVIDIA's nightly cuopt-cu12/cuopt-cu13 wheels (26.10 dev channel) instead of the pinned 26.8 stable release, so future builds on this branch stay current with pre-release fixes. This intentionally does not touch gmscuopt.c: the new multi-GPU PDLP feature is not reachable through the C API in any nightly build yet (confirmed by tracing cuOptSolve -> solve_lp_with_method -> run_pdlp, none of which read num_gpus for method=PDLP; distributed dispatch only exists in the mps_data_model-based solve_lp overload used by cuopt_cli, which the C API never calls). Co-Authored-By: Claude Sonnet 5 --- .github/workflows/main-arm64.yml | 12 +++++++++--- .github/workflows/main-x86_64.yml | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main-arm64.yml b/.github/workflows/main-arm64.yml index c6ac4d8..7b518d5 100644 --- a/.github/workflows/main-arm64.yml +++ b/.github/workflows/main-arm64.yml @@ -23,14 +23,20 @@ jobs: apt-get update && apt-get install -y patchelf curl unzip zip gcc pip install uv - # Get CUDA runtimes via pip + # Get CUDA runtimes via pip (nightly wheels, needed for pre-release multi-GPU PDLP support) - name: Set up python virtual environments with NVIDIA dependencies for CUDA 12 and CUDA 13 (respectively) run: | mkdir -p venvs uv venv venvs/cu12 - uv pip install --python venvs/cu12 --extra-index-url=https://pypi.nvidia.com 'cuopt-cu12==26.8.*' -qq + uv pip install --python venvs/cu12 --pre \ + --extra-index-url=https://pypi.nvidia.com \ + --extra-index-url=https://pypi.anaconda.org/rapidsai-wheels-nightly/simple/ \ + 'cuopt-cu12==26.10.*,>=0.0.0a0' -qq uv venv venvs/cu13 - uv pip install --python venvs/cu13 --extra-index-url=https://pypi.nvidia.com 'cuopt-cu13==26.8.*' -qq + uv pip install --python venvs/cu13 --pre \ + --extra-index-url=https://pypi.nvidia.com \ + --extra-index-url=https://pypi.anaconda.org/rapidsai-wheels-nightly/simple/ \ + 'cuopt-cu13==26.10.*,>=0.0.0a0' -qq # Get GAMS (ARM64 version) - name: Download and extract latest GAMS distribution diff --git a/.github/workflows/main-x86_64.yml b/.github/workflows/main-x86_64.yml index 535d4bd..e51cf68 100644 --- a/.github/workflows/main-x86_64.yml +++ b/.github/workflows/main-x86_64.yml @@ -23,14 +23,20 @@ jobs: apt-get update && apt-get install -y patchelf curl unzip zip gcc pip install uv - # Get CUDA runtimes via pip + # Get CUDA runtimes via pip (nightly wheels, needed for pre-release multi-GPU PDLP support) - name: Set up python virtual environments with NVIDIA dependencies for CUDA 12 and CUDA 13 (respectively) run: | mkdir -p venvs uv venv venvs/cu12 - uv pip install --python venvs/cu12 --extra-index-url=https://pypi.nvidia.com 'cuopt-cu12==26.8.*' -qq + uv pip install --python venvs/cu12 --pre \ + --extra-index-url=https://pypi.nvidia.com \ + --extra-index-url=https://pypi.anaconda.org/rapidsai-wheels-nightly/simple/ \ + 'cuopt-cu12==26.10.*,>=0.0.0a0' -qq uv venv venvs/cu13 - uv pip install --python venvs/cu13 --extra-index-url=https://pypi.nvidia.com 'cuopt-cu13==26.8.*' -qq + uv pip install --python venvs/cu13 --pre \ + --extra-index-url=https://pypi.nvidia.com \ + --extra-index-url=https://pypi.anaconda.org/rapidsai-wheels-nightly/simple/ \ + 'cuopt-cu13==26.10.*,>=0.0.0a0' -qq # Get GAMS - name: Download and extract latest GAMS distribution From 752eef852690371fe9baa0bda15002ce0b3f940f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Schnabel?= Date: Tue, 15 Sep 2026 15:25:13 +0200 Subject: [PATCH 2/3] Fix nightly wheel install by dropping the stable pypi.nvidia.com index uv's default index-strategy stops looking once it finds a matching package name on an index, even if no version there satisfies the constraint. Since pypi.nvidia.com only has stable cuopt-cu12/cuopt-cu13 releases (up to 26.8.0), uv found the package there first and refused to fall through to the nightly index for a 26.10.* build, failing resolution. Verified locally (dry-run) that the nightly index alone resolves all cu12/cu13 dependencies for both x86_64 and arm64. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/main-arm64.yml | 2 -- .github/workflows/main-x86_64.yml | 2 -- 2 files changed, 4 deletions(-) diff --git a/.github/workflows/main-arm64.yml b/.github/workflows/main-arm64.yml index 7b518d5..52d2ec6 100644 --- a/.github/workflows/main-arm64.yml +++ b/.github/workflows/main-arm64.yml @@ -29,12 +29,10 @@ jobs: mkdir -p venvs uv venv venvs/cu12 uv pip install --python venvs/cu12 --pre \ - --extra-index-url=https://pypi.nvidia.com \ --extra-index-url=https://pypi.anaconda.org/rapidsai-wheels-nightly/simple/ \ 'cuopt-cu12==26.10.*,>=0.0.0a0' -qq uv venv venvs/cu13 uv pip install --python venvs/cu13 --pre \ - --extra-index-url=https://pypi.nvidia.com \ --extra-index-url=https://pypi.anaconda.org/rapidsai-wheels-nightly/simple/ \ 'cuopt-cu13==26.10.*,>=0.0.0a0' -qq diff --git a/.github/workflows/main-x86_64.yml b/.github/workflows/main-x86_64.yml index e51cf68..52a8907 100644 --- a/.github/workflows/main-x86_64.yml +++ b/.github/workflows/main-x86_64.yml @@ -29,12 +29,10 @@ jobs: mkdir -p venvs uv venv venvs/cu12 uv pip install --python venvs/cu12 --pre \ - --extra-index-url=https://pypi.nvidia.com \ --extra-index-url=https://pypi.anaconda.org/rapidsai-wheels-nightly/simple/ \ 'cuopt-cu12==26.10.*,>=0.0.0a0' -qq uv venv venvs/cu13 uv pip install --python venvs/cu13 --pre \ - --extra-index-url=https://pypi.nvidia.com \ --extra-index-url=https://pypi.anaconda.org/rapidsai-wheels-nightly/simple/ \ 'cuopt-cu13==26.10.*,>=0.0.0a0' -qq From 02103480061af7dddf68a1fc3e076c1e30514401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Schnabel?= Date: Tue, 15 Sep 2026 15:43:21 +0200 Subject: [PATCH 3/3] Widen num_gpus range in optcuopt.def, clarify its effective cap cuOpt's C API accepts num_gpus up to 72, but the concurrent-mode code path it actually drives (solve.cu) hardcodes the barrier thread to device index 1, so values above 2 are accepted without error but have no further effect. Widen the GAMS option's upper bound to match the C API so it's not artificially more restrictive, and make the description explicit about the 2-GPU cap so users aren't misled into expecting more speedup from higher values. Co-Authored-By: Claude Sonnet 5 --- assets/optcuopt.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/optcuopt.def b/assets/optcuopt.def index 1366127..a1e9975 100644 --- a/assets/optcuopt.def +++ b/assets/optcuopt.def @@ -3,7 +3,7 @@ * * name type usermap default low high visible group num_cpu_threads integer 0 -1 -1 maxint 1 1 Controls the number of CPU threads used in the LP and MIP solvers (default GAMS Threads) -num_gpus integer 0 1 1 2 1 2 Controls the number of GPUs to use for the solve. This setting is only relevant for LP problems that uses concurrent mode and supports up to 2 GPUs at the moment. Using this mode will run PDLP and barrier in parallel on different GPUs to avoid sharing single GPU resources. +num_gpus integer 0 1 1 72 1 2 Controls the number of GPUs to use for the solve. This setting is only relevant for LP problems that use concurrent mode. Any value greater than 1 runs PDLP and barrier in parallel on two separate GPUs to avoid sharing single-GPU resources; cuOpt currently only ever engages exactly 2 GPUs this way, so values above 2 are accepted but have no further effect. presolve enumint 0 -1 1 1 Controls which presolver (if any) to use for presolve reductions. -1 1 default (Papilo for MIP, PSLP for LP) 0 1 off (disable presolve)