Skip to content

Commit 5908588

Browse files
Merge branch 'main' into fix/nbtest-transport-skip-typo
2 parents 4942c0d + 2ca56e7 commit 5908588

163 files changed

Lines changed: 2642 additions & 1612 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude-plugin/marketplace.json

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,12 @@
5656
"skills": "./",
5757
"description": "Trace and interpret the Pareto frontier across competing objectives using repeated single-objective cuOpt solves (weighted-sum and ε-constraint)."
5858
},
59-
{
60-
"name": "cuopt-routing-formulation",
61-
"source": "./skills/cuopt-routing-formulation",
62-
"skills": "./",
63-
"description": "Vehicle routing (VRP, TSP, PDP) — problem types and data requirements. Domain concepts; no API or interface."
64-
},
6559
{
6660
"name": "cuopt-routing-api-python",
6761
"source": "./skills/cuopt-routing-api-python",
6862
"skills": "./",
6963
"description": "Vehicle routing (VRP, TSP, PDP) with cuOpt — Python API only. Use when the user is building or solving routing in Python."
7064
},
71-
{
72-
"name": "cuopt-server-common",
73-
"source": "./skills/cuopt-server-common",
74-
"skills": "./",
75-
"description": "cuOpt REST server — what it does and how requests flow. Domain concepts; no deploy or client code."
76-
},
7765
{
7866
"name": "cuopt-server-api-python",
7967
"source": "./skills/cuopt-server-api-python",

.github/workflows/pr.yaml

Lines changed: 8 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ permissions: {}
1717
jobs:
1818
pr-builder:
1919
needs:
20-
- check-lean-ci
21-
- prevent-merge-with-lean-ci
2220
- compute-matrix-filters
2321
- changed-files
2422
- checks
@@ -41,87 +39,23 @@ jobs:
4139
if: always()
4240
with:
4341
needs: ${{ toJSON(needs) }}
44-
check-lean-ci:
45-
permissions:
46-
contents: read
47-
pull-requests: read
48-
runs-on: ubuntu-latest
49-
outputs:
50-
lean_ci_enabled: ${{ steps.check-label.outputs.lean_ci_enabled }}
51-
steps:
52-
- name: Check for lean-ci label
53-
id: check-label
54-
env:
55-
GH_TOKEN: ${{ github.token }}
56-
run: |
57-
# Extract PR number from branch name (pull-request/123 -> 123)
58-
PR_NUMBER=$(echo "$GITHUB_REF" | sed 's|refs/heads/pull-request/||')
59-
echo "Checking PR #$PR_NUMBER for lean-ci label..."
60-
61-
# Check if the PR has the 'lean-ci' label
62-
if gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json labels --jq '.labels[].name' | grep -q "^lean-ci$"; then
63-
echo "lean_ci_enabled=true" >> $GITHUB_OUTPUT
64-
echo "⚠️ Lean CI is enabled (lean-ci label found)"
65-
else
66-
echo "lean_ci_enabled=false" >> $GITHUB_OUTPUT
67-
echo "✅ Full CI is enabled"
68-
fi
69-
70-
prevent-merge-with-lean-ci:
71-
permissions:
72-
contents: read
73-
runs-on: ubuntu-latest
74-
needs: check-lean-ci
75-
steps:
76-
- name: Check lean-ci status
77-
env:
78-
LEAN_CI: ${{ needs.check-lean-ci.outputs.lean_ci_enabled }}
79-
run: |
80-
if [ "$LEAN_CI" == "true" ]; then
81-
echo "❌ ERROR: This PR has the 'lean-ci' label enabled."
82-
echo "Lean CI is only for testing purposes and should not be merged."
83-
echo "Please remove the 'lean-ci' label and run full CI before merging."
84-
exit 1
85-
else
86-
echo "✅ No lean-ci label found. PR can be merged."
87-
exit 0
88-
fi
8942
compute-matrix-filters:
90-
needs: check-lean-ci
9143
permissions:
9244
contents: read
9345
runs-on: ubuntu-latest
9446
outputs:
95-
conda_lean_filter: ${{ steps.set-filters.outputs.conda_lean_filter }}
96-
conda_test_filter: ${{ steps.set-filters.outputs.conda_test_filter }}
97-
wheel_lean_filter: ${{ steps.set-filters.outputs.wheel_lean_filter }}
9847
libcuopt_filter: ${{ steps.set-filters.outputs.libcuopt_filter }}
9948
cuopt_server_filter: ${{ steps.set-filters.outputs.cuopt_server_filter }}
10049
cuopt_server_test_filter: ${{ steps.set-filters.outputs.cuopt_server_test_filter }}
10150
cuopt_sh_client_filter: ${{ steps.set-filters.outputs.cuopt_sh_client_filter }}
10251
steps:
10352
- name: Set matrix filters
10453
id: set-filters
105-
env:
106-
LEAN_CI: ${{ needs.check-lean-ci.outputs.lean_ci_enabled }}
10754
run: |
108-
if [ "$LEAN_CI" == "true" ]; then
109-
echo "conda_lean_filter=[map(select(.ARCH == \"amd64\" and .PY_VER == \"3.11\")) | max_by(.CUDA_VER | split(\".\") | map(tonumber))]" >> $GITHUB_OUTPUT
110-
echo "conda_test_filter=[map(select(.ARCH == \"amd64\" and .PY_VER == \"3.13\")) | max_by(.CUDA_VER | split(\".\") | map(tonumber))]" >> $GITHUB_OUTPUT
111-
echo "wheel_lean_filter=[map(select(.ARCH == \"amd64\" and .PY_VER == \"3.12\")) | max_by(.CUDA_VER | split(\".\") | map(tonumber))]" >> $GITHUB_OUTPUT
112-
echo "libcuopt_filter=[map(select(.ARCH == \"amd64\" and .PY_VER == \"3.12\")) | max_by(.CUDA_VER | split(\".\") | map(tonumber))]" >> $GITHUB_OUTPUT
113-
echo "cuopt_server_filter=[map(select(.ARCH == \"amd64\" and .PY_VER == \"3.12\")) | max_by(.CUDA_VER | split(\".\") | map(tonumber))]" >> $GITHUB_OUTPUT
114-
echo "cuopt_server_test_filter=[map(select(.ARCH == \"amd64\")) | max_by(.CUDA_VER | split(\".\") | map(tonumber))]" >> $GITHUB_OUTPUT
115-
echo "cuopt_sh_client_filter=[map(select(.ARCH == \"amd64\" and .PY_VER == \"3.12\")) | max_by(.CUDA_VER | split(\".\") | map(tonumber))]" >> $GITHUB_OUTPUT
116-
else
117-
echo "conda_lean_filter=." >> $GITHUB_OUTPUT
118-
echo "conda_test_filter=." >> $GITHUB_OUTPUT
119-
echo "wheel_lean_filter=." >> $GITHUB_OUTPUT
120-
echo "libcuopt_filter=group_by([.ARCH, (.CUDA_VER|split(\".\")|map(tonumber)|.[0])]) | map(max_by(.PY_VER|split(\".\")|map(tonumber)))" >> $GITHUB_OUTPUT
121-
echo "cuopt_server_filter=map(select(.ARCH == \"amd64\")) | group_by(.CUDA_VER|split(\".\")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(\".\")|map(tonumber)), (.CUDA_VER|split(\".\")|map(tonumber))]))" >> $GITHUB_OUTPUT
122-
echo "cuopt_server_test_filter=map(select(.ARCH == \"amd64\")) | group_by(.CUDA_VER | split(\".\") | map(tonumber) | .[0]) | map(max_by([(.PY_VER | split(\".\") | map(tonumber)), (.CUDA_VER | split(\".\") | map(tonumber))]))" >> $GITHUB_OUTPUT
123-
echo "cuopt_sh_client_filter=[map(select(.ARCH == \"amd64\")) | min_by((.PY_VER | split(\".\") | map(tonumber)), (.CUDA_VER | split(\".\") | map(-tonumber)))]" >> $GITHUB_OUTPUT
124-
fi
55+
echo "libcuopt_filter=group_by([.ARCH, (.CUDA_VER|split(\".\")|map(tonumber)|.[0])]) | map(max_by(.PY_VER|split(\".\")|map(tonumber)))" >> $GITHUB_OUTPUT
56+
echo "cuopt_server_filter=map(select(.ARCH == \"amd64\")) | group_by(.CUDA_VER|split(\".\")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(\".\")|map(tonumber)), (.CUDA_VER|split(\".\")|map(tonumber))]))" >> $GITHUB_OUTPUT
57+
echo "cuopt_server_test_filter=map(select(.ARCH == \"amd64\")) | group_by(.CUDA_VER | split(\".\") | map(tonumber) | .[0]) | map(max_by([(.PY_VER | split(\".\") | map(tonumber)), (.CUDA_VER | split(\".\") | map(tonumber))]))" >> $GITHUB_OUTPUT
58+
echo "cuopt_sh_client_filter=[map(select(.ARCH == \"amd64\")) | min_by((.PY_VER | split(\".\") | map(tonumber)), (.CUDA_VER | split(\".\") | map(-tonumber)))]" >> $GITHUB_OUTPUT
12559
12660
changed-files:
12761
permissions:
@@ -413,9 +347,8 @@ jobs:
413347
with:
414348
build_type: pull-request
415349
script: ci/build_cpp.sh
416-
matrix_filter: ${{ needs.compute-matrix-filters.outputs.conda_lean_filter }}
417350
conda-cpp-tests:
418-
needs: [conda-cpp-build, changed-files, compute-matrix-filters]
351+
needs: [conda-cpp-build, changed-files]
419352
permissions:
420353
actions: read
421354
contents: read
@@ -427,7 +360,6 @@ jobs:
427360
with:
428361
build_type: pull-request
429362
script: ci/test_cpp.sh
430-
matrix_filter: ${{ needs.compute-matrix-filters.outputs.conda_test_filter }}
431363
secrets:
432364
script-env-secret-1-key: CUOPT_S3_URI
433365
script-env-secret-1-value: ${{ secrets.CUOPT_S3_URI }}
@@ -436,7 +368,7 @@ jobs:
436368
script-env-secret-3-key: CUOPT_AWS_SECRET_ACCESS_KEY
437369
script-env-secret-3-value: ${{ secrets.CUOPT_AWS_SECRET_ACCESS_KEY }}
438370
conda-python-build:
439-
needs: [conda-cpp-build, compute-matrix-filters, changed-files]
371+
needs: [conda-cpp-build, changed-files]
440372
# Consumed by conda-python-tests and docs-build.
441373
if: >-
442374
fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda ||
@@ -452,9 +384,8 @@ jobs:
452384
with:
453385
build_type: pull-request
454386
script: ci/build_python.sh
455-
matrix_filter: ${{ needs.compute-matrix-filters.outputs.conda_test_filter }}
456387
conda-python-tests:
457-
needs: [conda-python-build, changed-files, compute-matrix-filters]
388+
needs: [conda-python-build, changed-files]
458389
permissions:
459390
actions: read
460391
contents: read
@@ -467,7 +398,6 @@ jobs:
467398
run_codecov: false
468399
build_type: pull-request
469400
script: ci/test_python.sh
470-
matrix_filter: ${{ needs.compute-matrix-filters.outputs.conda_test_filter }}
471401
secrets:
472402
script-env-secret-1-key: CUOPT_S3_URI
473403
script-env-secret-1-value: ${{ secrets.CUOPT_S3_URI }}
@@ -528,9 +458,8 @@ jobs:
528458
script: ci/build_wheel_cuopt.sh
529459
package-name: cuopt
530460
package-type: python
531-
matrix_filter: ${{ needs.compute-matrix-filters.outputs.wheel_lean_filter }}
532461
wheel-tests-cuopt:
533-
needs: [wheel-build-cuopt, wheel-build-cuopt-sh-client, changed-files, compute-matrix-filters]
462+
needs: [wheel-build-cuopt, wheel-build-cuopt-sh-client, changed-files]
534463
permissions:
535464
actions: read
536465
contents: read
@@ -542,7 +471,6 @@ jobs:
542471
with:
543472
build_type: pull-request
544473
script: ci/test_wheel_cuopt.sh
545-
matrix_filter: ${{ needs.compute-matrix-filters.outputs.wheel_lean_filter }}
546474
secrets:
547475
script-env-secret-1-key: CUOPT_S3_URI
548476
script-env-secret-1-value: ${{ secrets.CUOPT_S3_URI }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ __pycache__
1212
*.dylib
1313
.cache
1414
.vscode
15+
.cursor/
1516
*.swp
1617
*.pytest_cache
1718
*.manifest

AGENTS.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ AI agent skills for NVIDIA cuOpt optimization engine. Skills live in **`skills/`
1414
### Common (concepts only; no API code)
1515
- `skills/cuopt-numerical-optimization-formulation/` — LP / MILP / QP: concepts + problem parsing + common formulation patterns
1616
- `skills/cuopt-multi-objective-exploration/` — Multi-objective: trace + interpret the Pareto frontier across competing objectives (ε-constraint / weighted-sum over repeated cuOpt solves)
17-
- `skills/cuopt-routing-formulation/` — Routing: VRP, TSP, PDP (problem types, data)
18-
- `skills/cuopt-server-common/` — Server: capabilities, workflow
1917

2018
### Installation
2119
- `skills/cuopt-install/` — User install for Python, C, and server (pip, conda, Docker, verification). For building cuOpt from source, see `skills/cuopt-developer/`.

ci/test_doc_examples.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ find_cuopt_libraries() {
457457
fi
458458

459459
# Search in common locations including Python site-packages
460-
local search_dirs=("${HOME}" "${CONDA_PREFIX}" "/usr" "/opt")
460+
local search_dirs=("${HOME}" "${CONDA_PREFIX:-}" "/usr" "/opt")
461461
if [ -n "${site_packages}" ] && [ -d "${site_packages}" ]; then
462462
search_dirs+=("${site_packages}")
463463
fi

cpp/include/cuopt/mathematical_optimization/constants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
#define CUOPT_MIP_FLOW_COVER_CUTS "mip_flow_cover_cuts"
7373
#define CUOPT_MIP_IMPLIED_BOUND_CUTS "mip_implied_bound_cuts"
7474
#define CUOPT_MIP_CLIQUE_CUTS "mip_clique_cuts"
75+
#define CUOPT_MIP_ZERO_HALF_CUTS "mip_zero_half_cuts"
7576
#define CUOPT_MIP_STRONG_CHVATAL_GOMORY_CUTS "mip_strong_chvatal_gomory_cuts"
7677
#define CUOPT_MIP_REDUCED_COST_STRENGTHENING "mip_reduced_cost_strengthening"
7778
#define CUOPT_MIP_OBJECTIVE_STEP "mip_objective_step"

cpp/include/cuopt/mathematical_optimization/mip/solver_settings.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class mip_solver_settings_t {
127127
i_t knapsack_cuts = -1;
128128
i_t flow_cover_cuts = -1;
129129
i_t clique_cuts = -1;
130+
i_t zero_half_cuts = -1;
130131
i_t implied_bound_cuts = -1;
131132
i_t strong_chvatal_gomory_cuts = -1;
132133
i_t reduced_cost_strengthening = -1;

cpp/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ set(UTIL_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/utilities/seed_generator.cu
99
${CMAKE_CURRENT_SOURCE_DIR}/utilities/timestamp_utils.cpp
1010
${CMAKE_CURRENT_SOURCE_DIR}/utilities/work_unit_scheduler.cpp)
1111

12+
add_subdirectory(linear_algebra)
1213
add_subdirectory(pdlp)
1314
add_subdirectory(math_optimization)
1415
add_subdirectory(mip_heuristics)

0 commit comments

Comments
 (0)