diff --git a/.ai/skills/cuopt.yaml b/.ai/skills/cuopt.yaml new file mode 100644 index 000000000..60ee68969 --- /dev/null +++ b/.ai/skills/cuopt.yaml @@ -0,0 +1,9 @@ +# cuOpt agent skill manifest (shim) +# +# Canonical location: +# - .github/.ai/skills/cuopt.yaml +# +# Many tools scan for `.ai/skills/*` at repo root; this file keeps those tools working. +manifest_version: 1 + +canonical: .github/.ai/skills/cuopt.yaml diff --git a/.github/.ai/skills/cuopt.yaml b/.github/.ai/skills/cuopt.yaml new file mode 100644 index 000000000..5cb35bbcb --- /dev/null +++ b/.github/.ai/skills/cuopt.yaml @@ -0,0 +1,85 @@ +# cuOpt agent skill manifest (machine-readable) +manifest_version: 1 + +name: cuOpt +vendor: NVIDIA +summary: GPU-accelerated optimization engine for Routing (TSP/VRP/PDP) and Math Optimization (LP/MILP/QP). + +capabilities: + routing: + problems: [TSP, VRP, PDP] + mathematical_optimization: + problems: [LP, MILP, QP] + notes: + - QP support exists in the Python API and is currently documented as beta. + +compute: + accelerator: NVIDIA_GPU + requirements: + - CUDA 12.0+ (or CUDA 13.0+ depending on package) + - NVIDIA driver compatible with CUDA runtime + - Compute Capability >= 7.0 (Volta+) + +interfaces: + - name: python + kind: library + supports: + routing: true + lp: true + milp: true + qp: true + packages: + - cuopt-cu12 + - cuopt-cu13 + docs: + - docs/cuopt/source/cuopt-python/quick-start.rst + - docs/cuopt/source/cuopt-python/routing/index.rst + - docs/cuopt/source/cuopt-python/lp-qp-milp/index.rst + + - name: c_api + kind: library + library: libcuopt + supports: + routing: false + lp: true + milp: true + qp: true + docs: + - docs/cuopt/source/cuopt-c/index.rst + + - name: server_rest + kind: service + protocol: HTTP + supports: + routing: true + lp: true + milp: true + qp: false + implementation: + - python/cuopt_server/cuopt_server/webserver.py + openapi: + spec_file: docs/cuopt/source/cuopt_spec.yaml + served_path: /cuopt.yaml + ui_paths: + - /cuopt/docs + - /cuopt/redoc + docs: + - docs/cuopt/source/cuopt-server/quick-start.rst + - docs/cuopt/source/cuopt-server/server-api/index.rst + - docs/cuopt/source/open-api.rst + +roles: + cuopt_user: + description: Use cuOpt to solve routing and math optimization problems without modifying cuOpt internals. + rules: + - .github/agents/cuopt-user.md + cuopt_developer: + description: Develop and maintain cuOpt (C++/CUDA/Python/server/docs/CI). + rules: + - .github/agents/cuopt-developer.md + - .github/AGENTS.md + +entrypoints: + human_router: + - .github/AGENTS.md + - AGENTS.md diff --git a/.github/AGENTS.md b/.github/AGENTS.md index 51f799e19..04cdc3703 100644 --- a/.github/AGENTS.md +++ b/.github/AGENTS.md @@ -1,156 +1,15 @@ # AGENTS.md - AI Coding Agent Guidelines for cuOpt -> This file provides essential context for AI coding assistants (Codex, Cursor, GitHub Copilot, etc.) working with the NVIDIA cuOpt codebase. +This file is intentionally **minimal**. Choose a role and follow the matching rules: -> **For setup, building, testing, and contribution guidelines, see [CONTRIBUTING.md](../CONTRIBUTING.md).** +- **Using cuOpt (model + solve problems)**: `.github/agents/cuopt-user.md` +- **Developing cuOpt (changing this repo)**: `.github/agents/cuopt-developer.md` ---- +### Machine-readable skill manifest -## Project Overview +- **Primary**: `.github/.ai/skills/cuopt.yaml` +- **Root shim (compat)**: `.ai/skills/cuopt.yaml` -**cuOpt** is NVIDIA's GPU-accelerated optimization engine for: -- **Mixed Integer Linear Programming (MILP)** -- **Linear Programming (LP)** -- **Quadratic Programming (QP)** -- **Vehicle Routing Problems (VRP)** including TSP and PDP +### Canonical contribution guide -### Architecture - -``` -cuopt/ -├── cpp/ # Core C++ engine (libcuopt, libmps_parser) -│ ├── include/cuopt/ # Public C/C++ headers -│ ├── src/ # Implementation (CUDA kernels, algorithms) -│ └── tests/ # C++ unit tests (gtest) -├── python/ -│ ├── cuopt/ # Python bindings and routing API -│ ├── cuopt_server/ # REST API server -│ ├── cuopt_self_hosted/ # Self-hosted deployment utilities -│ └── libcuopt/ # Python wrapper for C library -├── ci/ # CI/CD scripts and Docker configurations -├── conda/ # Conda recipes and environment files -├── docs/ # Documentation source -├── datasets/ # Test datasets for LP, MIP, routing -└── notebooks/ # Example Jupyter notebooks -``` - -### Supported APIs - -| API Type | LP | MILP | QP | Routing | -|----------|:--:|:----:|:--:|:-------:| -| C API | ✓ | ✓ | ✓ | ✗ | -| C++ API | ✓ | ✓ | ✓ | ✓ | -| Python | ✓ | ✓ | ✓ | ✓ | -| Server | ✓ | ✓ | ✗ | ✓ | - ---- - -## Coding Style and Conventions - -### C++ Naming Conventions - -- **Base style**: `snake_case` for all names (except test cases: PascalCase) -- **Prefixes/Suffixes**: - - `d_` → device data variables (e.g., `d_locations_`) - - `h_` → host data variables (e.g., `h_data_`) - - `_t` → template type parameters (e.g., `i_t`, `value_t`) - - `_` → private member variables (e.g., `n_locations_`) - -```cpp -// Example naming pattern -template -class locations_t { - private: - i_t n_locations_{}; - i_t* d_locations_{}; // device pointer - i_t* h_locations_{}; // host pointer -}; -``` - -### File Extensions - -| Extension | Usage | -|-----------|-------| -| `.hpp` | C++ headers | -| `.cpp` | C++ source | -| `.cu` | CUDA C++ source (nvcc required) | -| `.cuh` | CUDA headers with device code | - -### Include Order - -1. Local headers -2. RAPIDS headers -3. Related libraries -4. Dependencies -5. STL - -### Python Style - -- Follow PEP 8 -- Use type hints where applicable -- Tests use `pytest` framework - -### Formatting - -- **C++**: Enforced by `clang-format` (config: `cpp/.clang-format`) -- **Python**: Enforced via pre-commit hooks -- See [CONTRIBUTING.md](../CONTRIBUTING.md) for pre-commit setup - ---- - -## Error Handling Patterns - -### Runtime Assertions - -```cpp -// Use CUOPT_EXPECTS for runtime checks -CUOPT_EXPECTS(lhs.type() == rhs.type(), "Column type mismatch"); - -// Use CUOPT_FAIL for unreachable code paths -CUOPT_FAIL("This code path should not be reached."); -``` - -### CUDA Error Checking - -```cpp -// Always wrap CUDA calls -RAFT_CUDA_TRY(cudaMemcpy(&dst, &src, num_bytes)); -``` - ---- - -## Memory Management Guidelines - -- **Never use raw `new`/`delete`** - Use RMM allocators -- **Prefer `rmm::device_uvector`** for device memory -- **All operations should be stream-ordered** - Accept `cuda_stream_view` -- **Views (`*_view` suffix) are non-owning** - Don't manage their lifetime - ---- - -## Key Files Reference - -| Purpose | Location | -|---------|----------| -| Main build script | `build.sh` | -| Dependencies | `dependencies.yaml` | -| C++ formatting | `cpp/.clang-format` | -| Conda environments | `conda/environments/` | -| Test data download | `datasets/get_test_data.sh` | -| CI configuration | `ci/` | -| Version info | `VERSION` | - ---- - -## Common Pitfalls - -| Problem | Solution | -|---------|----------| -| Cython changes not reflected | Rerun: `./build.sh cuopt` | -| Missing `nvcc` | Set `$CUDACXX` or add CUDA to `$PATH` | -| CUDA out of memory | Reduce problem size or use streaming | -| Slow debug library loading | Device symbols cause delay; use selectively | - ---- - -*For detailed setup, build instructions, testing workflows, debugging, and contribution guidelines, see [CONTRIBUTING.md](../CONTRIBUTING.md).* +- `CONTRIBUTING.md` diff --git a/.github/agents/cuopt-developer.md b/.github/agents/cuopt-developer.md new file mode 100644 index 000000000..34d06801c --- /dev/null +++ b/.github/agents/cuopt-developer.md @@ -0,0 +1,166 @@ +# cuOpt engineering contract (cuopt_developer) + +You are modifying the **cuOpt codebase**. Your priorities are correctness, performance, compatibility, and minimal-risk diffs. + +If you only need to **use** cuOpt (not change it), switch to `cuopt_user` (`.github/agents/cuopt-user.md`). + +## Project overview (developer context) + +**cuOpt** is NVIDIA's GPU-accelerated optimization engine for: + +- **Mixed Integer Linear Programming (MILP)** +- **Linear Programming (LP)** +- **Quadratic Programming (QP)** +- **Vehicle Routing Problems (VRP)** including TSP and PDP + +### Architecture (high level) + +``` +cuopt/ +├── cpp/ # Core C++ engine (libcuopt, libmps_parser) +│ ├── include/cuopt/ # Public C/C++ headers +│ ├── src/ # Implementation (CUDA kernels, algorithms) +│ └── tests/ # C++ unit tests (gtest) +├── python/ +│ ├── cuopt/ # Python bindings and routing API +│ ├── cuopt_server/ # REST API server +│ ├── cuopt_self_hosted/ # Self-hosted deployment utilities +│ └── libcuopt/ # Python wrapper for C library +├── ci/ # CI/CD scripts and Docker configurations +├── conda/ # Conda recipes and environment files +├── docs/ # Documentation source +├── datasets/ # Test datasets for LP, MIP, routing +└── notebooks/ # Example Jupyter notebooks +``` + +### Supported APIs (at a glance) + +| API Type | LP | MILP | QP | Routing | +|----------|:--:|:----:|:--:|:-------:| +| C API | ✓ | ✓ | ✓ | ✗ | +| C++ API | (internal) | (internal) | (internal) | (internal) | +| Python | ✓ | ✓ | ✓ | ✓ | +| Server | ✓ | ✓ | ✗ | ✓ | + +## Canonical project docs (source of truth) + +- **Contributing / build / test / debugging**: `CONTRIBUTING.md` +- **CI scripts**: `ci/README.md` +- **Release/version scripts**: `ci/release/README.md` +- **Documentation build**: `docs/cuopt/README.md` + +## Safety rules for agents + +- **Minimal diffs**: change only what’s necessary; avoid drive-by refactors. +- **No mass reformatting**: don’t run formatters over unrelated code. +- **No API invention**: especially for routing / server schemas—align with `docs/cuopt/source/` + OpenAPI spec. +- **Don’t bypass CI**: don’t suggest skipping checks or using `--no-verify` unless explicitly required and approved. +- **CUDA/GPU hygiene**: keep operations stream-ordered, follow existing RAFT/RMM patterns, avoid raw `new`/`delete`. + +## Before you commit (style + signoff) + +- **Run the same style checks CI runs**: + - `./ci/check_style.sh` + - Or run pre-commit directly: `pre-commit run --all-files --show-diff-on-failure` + - Details: `CONTRIBUTING.md` (Code Formatting / pre-commit) +- **Signed commits are required (DCO sign-off)**: + - Use `git commit -s ...` (or `--signoff`) + - Details: `CONTRIBUTING.md` (Signing Your Work) + +## Coding style and conventions (summary) + +### C++ naming conventions + +- **Base style**: `snake_case` for all names (except test cases: PascalCase) +- **Prefixes/Suffixes**: + - `d_` → device data variables (e.g., `d_locations_`) + - `h_` → host data variables (e.g., `h_data_`) + - `_t` → template type parameters (e.g., `i_t`, `value_t`) + - `_` → private member variables (e.g., `n_locations_`) + +### File extensions + +| Extension | Usage | +|-----------|-------| +| `.hpp` | C++ headers | +| `.cpp` | C++ source | +| `.cu` | CUDA C++ source (nvcc required) | +| `.cuh` | CUDA headers with device code | + +### Include order + +1. Local headers +2. RAPIDS headers +3. Related libraries +4. Dependencies +5. STL + +### Python style + +- Follow PEP 8 +- Use type hints where applicable +- Tests use `pytest` framework + +### Formatting + +- **C++**: Enforced by `clang-format` (config: `cpp/.clang-format`) +- **Python**: Enforced via pre-commit hooks +- See `CONTRIBUTING.md` for pre-commit setup + +## Error handling patterns + +### Runtime assertions + +- Use `CUOPT_EXPECTS` for runtime checks +- Use `CUOPT_FAIL` for unreachable code paths + +### CUDA error checking + +- Wrap CUDA calls (e.g., `RAFT_CUDA_TRY(...)`) + +## Memory management guidelines + +- **Never use raw `new`/`delete`** - use RMM allocators +- **Prefer `rmm::device_uvector`** for device memory +- **All operations should be stream-ordered** - accept `cuda_stream_view` +- **Views (`*_view` suffix) are non-owning** - don't manage their lifetime + +## Repo navigation (practical) + +- **C++/CUDA core**: `cpp/` (includes `libmps_parser`, `libcuopt`) +- **Python packages**: `python/` (`cuopt`, `libcuopt`, `cuopt_server`, `cuopt_self_hosted`) +- **Docs (Sphinx)**: `docs/cuopt/source/` +- **Datasets**: `datasets/` + +## Build & test (quick reference; defer details to CONTRIBUTING) + +- **Build**: `./build.sh` (supports building individual components; see `./build.sh --help`) +- **C++ tests**: `ctest --test-dir cpp/build` +- **Python tests**: `pytest -v python/cuopt/cuopt/tests` (dataset env vars may be required; see `CONTRIBUTING.md`) +- **Docs build**: `./build.sh docs` or `make html` under `docs/cuopt` + +## Release discipline + +- Do not change versioning/release files unless explicitly requested. +- Prefer changes that are forward-merge friendly with RAPIDS branching conventions (see `CONTRIBUTING.md`). + +## Key files reference + +| Purpose | Location | +|---------|----------| +| Main build script | `build.sh` | +| Dependencies | `dependencies.yaml` | +| C++ formatting | `cpp/.clang-format` | +| Conda environments | `conda/environments/` | +| Test data download | `datasets/get_test_data.sh` | +| CI configuration | `ci/` | +| Version info | `VERSION` | + +## Common pitfalls + +| Problem | Solution | +|---------|----------| +| Cython changes not reflected | Rerun: `./build.sh cuopt` | +| Missing `nvcc` | Set `$CUDACXX` or add CUDA to `$PATH` | +| CUDA out of memory | Reduce problem size or use streaming | +| Slow debug library loading | Device symbols cause delay; use selectively | diff --git a/.github/agents/cuopt-user.md b/.github/agents/cuopt-user.md new file mode 100644 index 000000000..4fac28199 --- /dev/null +++ b/.github/agents/cuopt-user.md @@ -0,0 +1,461 @@ +# cuOpt agent skill (cuopt_user) + +**Purpose:** Help users correctly use NVIDIA cuOpt as an end user (modeling, solving, integration), do **not** modify cuOpt internals unless explicitly asked; if you need to change cuOpt itself, switch to `cuopt_developer` (`.github/agents/cuopt-developer.md`). + +--- + +## Scope & safety rails (read first) + +This agent **assists users of cuOpt**, not cuOpt developers. +Canonical product documentation lives under `docs/cuopt/source/` (Sphinx). Prefer linking to and following those docs instead of guessing. + +### Interface summary + +#### Link access note (important) + +- **If the agent has the repo checked out**: local paths like `docs/cuopt/source/...` are accessible and preferred. +- **If the agent only receives this file as context (no repo access)**: prefer **public docs** and **GitHub links**: + - Official docs: [cuOpt User Guide (latest)](https://docs.nvidia.com/cuopt/user-guide/latest/introduction.html) + - Source repo: [NVIDIA/cuopt](https://github.com/NVIDIA/cuopt) + - Examples/notebooks: [NVIDIA/cuopt-examples](https://github.com/NVIDIA/cuopt-examples) + - Issues: [NVIDIA/cuopt issues](https://github.com/NVIDIA/cuopt/issues) + +If you need an online link for any local path in this document, convert it with one of these templates: + +- **GitHub (view file)**: `https://github.com/NVIDIA/cuopt/blob/main/` +- **GitHub (raw file)**: `https://raw.githubusercontent.com/NVIDIA/cuopt/main/` + +Examples: + +- `docs/cuopt/source/open-api.rst` → `https://github.com/NVIDIA/cuopt/blob/main/docs/cuopt/source/open-api.rst` +- `.github/.ai/skills/cuopt.yaml` → `https://github.com/NVIDIA/cuopt/blob/main/.github/.ai/skills/cuopt.yaml` +- `docs/cuopt/source/cuopt-python/routing/examples/smoke_test_example.sh` → `https://raw.githubusercontent.com/NVIDIA/cuopt/main/docs/cuopt/source/cuopt-python/routing/examples/smoke_test_example.sh` + +```yaml +role: cuopt_user +scope: use_cuopt_only +do_not: + - modify_cuopt_source_or_schemas + - invent_apis_or_payload_fields +repo_base: + view: https://github.com/NVIDIA/cuopt/blob/main/ + raw: https://raw.githubusercontent.com/NVIDIA/cuopt/main/ +interfaces: + python: + supports: {routing: true, lp: true, milp: true, qp: true} + server_rest: + supports: {routing: true, lp: true, milp: true, qp: false} + openapi_served_path: /cuopt.yaml + cli: + supports: {routing: false, lp: true, milp: true, qp: false} + mps_note: + - MPS can also be used via C API, Python API examples and via the server local-file feature; CLI is not mandatory. + c_api: + supports: {routing: false, lp: true, milp: true, qp: true} +escalate_to: .github/agents/cuopt-developer.md +``` + +### What cuOpt solves + +- **Routing**: TSP / VRP / PDP (GPU-accelerated) +- **Math optimization**: **LP / MILP / QP** (QP is documented as beta for the Python API) + +### DO +- Help users model, solve, and integrate optimization problems using **documented cuOpt interfaces** +- Choose the **correct interface** (Python API, REST server, CLI, C API) +- Follow official documentation and examples + +### DO NOT +- Modify cuOpt internals, solver logic, schemas, or source code +- Invent APIs, fields, endpoints, or solver behaviors +- Guess payload formats or method names + +### SWITCH TO `cuopt_developer` IF: +- User asks to change solver behavior, internals, performance heuristics +- User asks to modify OpenAPI schema or cuOpt source +- User asks to add new endpoints or features + +--- + +## Interface selection (critical) + +**Always choose the interface first.** + +### Use Python API when: +- User gives equations, variables, constraints +- User wants to solve routing / LP / MILP / QP directly +- User wants in-process solving (scripts, notebooks) + +➡ Use: + - Quickstart: `docs/cuopt/source/cuopt-python/quick-start.rst` + - Routing API reference: `docs/cuopt/source/cuopt-python/routing/routing-api.rst` + - LP/QP/MILP API reference: `docs/cuopt/source/cuopt-python/lp-qp-milp/lp-qp-milp-api.rst` + +### Use Server REST API when: +- User wants production deployment +- User asks for REST payloads or HTTP calls +- User wants asynchronous or remote solving + +➡ Use: + - Server quickstart (includes curl smoke test): `docs/cuopt/source/cuopt-server/quick-start.rst` + - API overview: `docs/cuopt/source/cuopt-server/server-api/index.rst` + - OpenAPI reference (Swagger): `docs/cuopt/source/open-api.rst` + - OpenAPI spec exactly (`cuopt.yaml` / `cuopt_spec.yaml`) + +### Use CLI when: +- User wants **quick testing** / **research** / **reproducible debugging** from a terminal +- User wants to solve **LP/MILP from MPS files** without writing code + +➡ Use: + - CLI overview: `docs/cuopt/source/cuopt-cli/index.rst` + - CLI quickstart: `docs/cuopt/source/cuopt-cli/quick-start.rst` + - CLI examples: `docs/cuopt/source/cuopt-cli/cli-examples.rst` + +**Note on MPS inputs:** having an `.mps` file does **not** imply you must use the CLI. +Choose based on integration/deployment needs: + +- **CLI**: fastest local repro (LP/MILP from MPS) +- **C API**: native embedding; includes MPS-based examples under `docs/cuopt/source/cuopt-c/lp-qp-milp/examples/` +- **Server**: can use its local-file feature (see server docs/OpenAPI) when running a service + +### Use C API when: +- User explicitly requests native integration +- User is embedding cuOpt into C/C++ systems +- **Do not** recommend the **C++ API** to end users (it is not documented and may change; see repo `README.md` note). + +➡ Use: + - C overview: `docs/cuopt/source/cuopt-c/index.rst` + - C quickstart: `docs/cuopt/source/cuopt-c/quick-start.rst` + - C LP/QP/MILP API + examples: `docs/cuopt/source/cuopt-c/lp-qp-milp/index.rst` + +--- + +## Installation (minimal) + +Pick **one** installation method and match it to your CUDA major version (cuOpt publishes CUDA-variant packages). + +### pip + +- **Python API**: + +```bash +# Simplest (latest compatible from the index): +# CUDA 13 +pip install --extra-index-url=https://pypi.nvidia.com cuopt-cu13 + +# CUDA 12 +pip install --extra-index-url=https://pypi.nvidia.com cuopt-cu12 + +# Recommended (reproducible; pin to the current major/minor release line): +# CUDA 13 +pip install --extra-index-url=https://pypi.nvidia.com 'cuopt-cu13==26.2.*' + +# CUDA 12 +pip install --extra-index-url=https://pypi.nvidia.com 'cuopt-cu12==26.2.*' +``` + +- **Server + thin client (self-hosted)**: + +```bash +# Simplest: +# CUDA 12 example +pip install --extra-index-url=https://pypi.nvidia.com \ + cuopt-server-cu12 cuopt-sh-client + +# Recommended (reproducible): +# CUDA 12 example +pip install --extra-index-url=https://pypi.nvidia.com \ + nvidia-cuda-runtime-cu12==12.9.* \ + cuopt-server-cu12==26.02.* cuopt-sh-client==26.02.* +``` + +### conda + +```bash +# Simplest: +# Python API +conda install -c rapidsai -c conda-forge -c nvidia cuopt + +# Server + thin client +conda install -c rapidsai -c conda-forge -c nvidia cuopt-server cuopt-sh-client + +# Recommended (reproducible): +# Python API +conda install -c rapidsai -c conda-forge -c nvidia cuopt=26.02.* cuda-version=26.02.* + +# Server + thin client +conda install -c rapidsai -c conda-forge -c nvidia cuopt-server=26.02.* cuopt-sh-client=26.02.* +``` + +### container + +```bash +docker pull nvidia/cuopt:latest-cuda12.9-py3.13 +docker run --gpus all -it --rm -p 8000:8000 -e CUOPT_SERVER_PORT=8000 nvidia/cuopt:latest-cuda12.9-py3.13 +``` + +For full, up-to-date installation instructions (including nightlies), see: + +- `docs/cuopt/source/cuopt-python/quick-start.rst` +- `docs/cuopt/source/cuopt-server/quick-start.rst` + +--- + +## Python workflow (high level) + +### Routing (VRP/TSP/PDP) + +- **Model**: build a `cuopt.routing.DataModel` (tasks, fleet, costs/time windows/capacities as applicable) +- **Configure**: set `cuopt.routing.SolverSettings` (e.g., `time_limit`) +- **Solve**: call `cuopt.routing.Solve(...)` +- **Read results**: parse `cuopt.routing.Assignment` / solution status + +Use the API reference (above) as the source of truth for field names and types. + +### LP / MILP / QP + +- **Model**: create a `cuopt.linear_programming.problem.Problem`, add variables/constraints/objective +- **Configure**: `cuopt.linear_programming.solver_settings.SolverSettings` +- **Solve**: run the solver via the documented API +- **Read results**: - Check `problem.Status`, read `problem.ObjValue`, use `var.getValue()` + +If you need file-based modeling (MPS/QPS), prefer the documented examples under `docs/cuopt/source/` and `datasets/` rather than guessing a loader. + +## Server REST workflow (self-hosted) + +cuOpt server is implemented with FastAPI (`python/cuopt_server/cuopt_server/webserver.py`) and serves an OpenAPI spec at **`/cuopt.yaml`**. + +- **POST** `/cuopt/request`: submit a routing or LP/MILP request (async). Returns `{"reqId": "..."}` +- **GET** `/cuopt/solution/{reqId}`: poll until a solution is ready +- **GET** `/cuopt/request/{reqId}`: check request status + +### Practical request rules + +- **Set headers correctly**: + - `Content-Type: application/json` (or the documented msgpack/zlib types) + - For local/dev usage, docs show `CLIENT-VERSION: custom` to bypass strict client version checks +- **Payload schema**: do not guess—use `docs/cuopt/source/cuopt_spec.yaml` or the rendered OpenAPI docs. + +--- + +## Quickstarts (golden paths) + +### Quickstart 1: Python (routing smoke test) + +Assuming `cuopt` is installed in your environment (see `docs/cuopt/source/cuopt-python/quick-start.rst`), run the documented routing smoke test: + +```bash +bash docs/cuopt/source/cuopt-python/routing/examples/smoke_test_example.sh +``` + +If you want the inline version (same as the smoke test): + +```bash +python -c ' +import cudf +from cuopt import routing + +cost_matrix = cudf.DataFrame( + [[0, 2, 2, 2], + [2, 0, 2, 2], + [2, 2, 0, 2], + [2, 2, 2, 0]], + dtype="float32" +) + +task_locations = cudf.Series([1, 2, 3]) +n_vehicles = 2 + +dm = routing.DataModel(cost_matrix.shape[0], n_vehicles, len(task_locations)) +dm.add_cost_matrix(cost_matrix) +dm.add_transit_time_matrix(cost_matrix.copy(deep=True)) + +ss = routing.SolverSettings() +sol = routing.Solve(dm, ss) +print(sol.get_route()) +sol.display_routes() +' +``` + +### Quickstart 2: Canonical Python LP / MILP Modeling Template + +Use this skeleton for LP/MILP/QP problems. + +```python +from cuopt.linear_programming.problem import ( + Problem, CONTINUOUS, INTEGER, MINIMIZE +) +from cuopt.linear_programming.solver_settings import SolverSettings + +problem = Problem("MyOptimizationProblem") + +x = problem.addVariable(lb=0, vtype=CONTINUOUS, name="x") +y = problem.addVariable(lb=0, ub=1, vtype=INTEGER, name="y") + +problem.addConstraint(x <= 10 * y) + +problem.setObjective(5 * x + 100 * y, sense=MINIMIZE) + +settings = SolverSettings() +settings.set_parameter("time_limit", 60) +problem.solve(settings) + +print(problem.Status.name, problem.ObjValue) +``` + +### Quickstart 3: Server (self-hosted, REST) + +This is the documented copy/paste smoke test (see `docs/cuopt/source/cuopt-server/quick-start.rst`) in a shortened form: + +```bash +sudo apt install -y jq curl + +SERVER_IP=0.0.0.0 +SERVER_PORT=8000 + +python3 -m cuopt_server.cuopt_service --ip $SERVER_IP --port $SERVER_PORT > cuopt_server.log 2>&1 & +SERVER_PID=$! + +curl -fsS "http://${SERVER_IP}:${SERVER_PORT}/cuopt/health" >/dev/null + +REQID=$(curl --location "http://${SERVER_IP}:${SERVER_PORT}/cuopt/request" \ + --header 'Content-Type: application/json' \ + --header "CLIENT-VERSION: custom" \ + -d '{ + "cost_matrix_data": {"data": {"0": [[0, 1], [1, 0]]}}, + "task_data": {"task_locations": [1], "demand": [[1]], "task_time_windows": [[0, 10]], "service_times": [1]}, + "fleet_data": {"vehicle_locations":[[0, 0]], "capacities": [[2]], "vehicle_time_windows":[[0, 20]]}, + "solver_config": {"time_limit": 2} + }' | jq -r '.reqId') + +curl --location "http://${SERVER_IP}:${SERVER_PORT}/cuopt/solution/${REQID}" \ + --header 'Content-Type: application/json' \ + --header "CLIENT-VERSION: custom" | jq . + +kill $SERVER_PID +``` + +### Quickstart 4: C API (LP example) + +Use the C examples + Makefile under `docs/cuopt/source/cuopt-c/lp-qp-milp/examples/`. + +If installed via conda, a common setup is: + +```bash +export INCLUDE_PATH="${CONDA_PREFIX}/include" +export LIBCUOPT_LIBRARY_PATH="${CONDA_PREFIX}/lib" +cd docs/cuopt/source/cuopt-c/lp-qp-milp/examples +make simple_lp_example +./simple_lp_example +``` + +### Quickstart 5: CLI (LP from an MPS file) + +If you have `cuopt_cli` in your PATH: + +```bash +cuopt_cli --help +``` + +Minimal LP solve (creates an MPS file, solves it, then cleans up): + +```bash +cat > sample.mps << 'EOF' +* optimize +* cost = -0.2 * VAR1 + 0.1 * VAR2 +* subject to +* 3 * VAR1 + 4 * VAR2 <= 5.4 +* 2.7 * VAR1 + 10.1 * VAR2 <= 4.9 +NAME SAMPLE +ROWS + N COST + L ROW1 + L ROW2 +COLUMNS + VAR1 COST -0.2 + VAR1 ROW1 3.0 + VAR1 ROW2 2.7 + VAR2 COST 0.1 + VAR2 ROW1 4.0 + VAR2 ROW2 10.1 +RHS + RHS1 ROW1 5.4 + RHS1 ROW2 4.9 +ENDATA +EOF + +cuopt_cli sample.mps +rm -f sample.mps +``` + +--- + +## Common user requests → action map + +| User asks | Action | +|----------|--------| +| “Solve this routing problem” | Use routing API | +| “Solve this LP/MILP” | Use Python LP API | +| “Give REST payload” | Open OpenAPI spec | +| “I have MPS file” | CLI for quick repro **or** C API MPS examples **or** Server local-file feature (choose based on deployment) | +| “422 / schema error” | Fix payload | +| “Solver too slow” | Adjust allowed settings | +| “Change solver logic” | Switch agent | + +--- + +## Solver settings (safe adjustments) + +Allowed: +- Time limit +- Gap tolerances (if documented) +- Verbosity / logging + +Not allowed: +- Changing heuristics +- Modifying internals +- Undocumented parameters + +--- + +## Data formats & performance + +- **Payload formats**: JSON is the default; msgpack/zlib are supported for some endpoints (see server docs/OpenAPI). +- **GPU constraints**: requires a supported NVIDIA GPU/driver/CUDA runtime; see the system requirements in the main README and docs. +- **Tuning**: use solver settings (e.g., time limits) and avoid unnecessary host↔device churn; follow the feature docs under `docs/cuopt/source/`. + +--- + +## Error handling (agent rules) + +- **Validation errors (HTTP 4xx)**: treat as schema/typing issues; consult OpenAPI spec and fix the request payload. +- **Server errors (HTTP 5xx)**: capture `reqId`, poll logs/status endpoints where applicable, and reproduce with the smallest request. +- **Never “paper over” errors** by changing schemas or endpoints—align with the documented API. +- **Debugging a failure**: search existing [GitHub Issues](https://github.com/NVIDIA/cuopt/issues) first (use exact error text + cuOpt/CUDA/driver versions). If no match, file a new issue with a minimal repro, expected vs actual behavior, environment details, and any logs/`reqId`. + +For common troubleshooting and known issues, see: + +- `docs/cuopt/source/faq.rst` +- `docs/cuopt/source/resources.rst` + +--- + +## Additional resources (when to use) + +- **Examples / notebooks**: [NVIDIA/cuopt-examples](https://github.com/NVIDIA/cuopt-examples) → runnable notebooks +- **Google Colab**: [cuopt-examples notebooks on Colab](https://colab.research.google.com/github/nvidia/cuopt-examples/) → runnable examples +- **Official docs**: [cuOpt User Guide](https://docs.nvidia.com/cuopt/user-guide/latest/introduction.html) → modeling correctness +- **Videos/tutorials**: [cuOpt examples and tutorials videos](https://docs.nvidia.com/cuopt/user-guide/latest/resources.html#cuopt-examples-and-tutorials-videos) → unclear behavior +- **Try in the cloud**: [NVIDIA Launchable](https://brev.nvidia.com/launchable/deploy?launchableID=env-2qIG6yjGKDtdMSjXHcuZX12mDNJ) → GPU environments +- **Support / questions**: [NVIDIA Developer Forums (cuOpt)](https://forums.developer.nvidia.com/c/ai-data-science/nvidia-cuopt/514) → unclear behavior +- **Bugs / feature requests**: [GitHub Issues](https://github.com/NVIDIA/cuopt/issues) → unclear behavior + +--- + +## Final agent rules (non-negotiable) + +- Never invent APIs +- Never assume undocumented behavior +- Always choose interface first +- Prefer correctness over speed +- When unsure → open docs or ask user to clarify diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..1cd7c9e43 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,7 @@ +# AGENTS.md (shim) + +The canonical AI-agent entrypoint for this repo is: + +- `.github/AGENTS.md` + +If you are a coding agent, start there.