Repository navigation
Improve cuopt-developer skill content and sibling-skill routing #1176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
f5f3664
6dfd1ac
db5fdf1
cbbfc40
50d1c65
f8b94c1
b6a35a2
d53ffb9
56ded63
4d9543f
4d56b46
b02c7fb
c849bd8
049e3c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # Build & Test | ||
|
|
||
| Read this for component-level build commands, run-test commands, and `PARALLEL_LEVEL` detail. **Pre-flight checks** (CUDA driver compatibility, conda env activation, dataset setup) live in [SKILL.md → Build & Test → Pre-flight Checks](../SKILL.md#pre-flight-checks-required-before-first-build-or-test) — always run those first. | ||
|
|
||
| ## PARALLEL_LEVEL | ||
|
|
||
| `PARALLEL_LEVEL` controls the number of parallel compile jobs. It defaults to `$(nproc)` (all cores), which can cause OOM on machines with limited RAM — CUDA compilation needs roughly 4–8 GB per job. Set it based on available RAM: | ||
|
|
||
| ```bash | ||
| export PARALLEL_LEVEL=8 # adjust based on available RAM | ||
| ``` | ||
|
|
||
| ## Build Everything | ||
|
|
||
| ```bash | ||
| ./build.sh | ||
| ``` | ||
|
|
||
| ## Build Specific Components | ||
|
|
||
| ```bash | ||
| ./build.sh --help # Lists build options | ||
| ./build.sh libcuopt # C++ library | ||
| ./build.sh libmps_parser libcuopt --skip-routing-build --skip-tests-build --skip-c-python-adapters --cache-tool=ccache # native LP/MIP-focused build without routing/tests/adapters | ||
| ./build.sh cuopt # Python package | ||
| ./build.sh cuopt_server # Server | ||
| ./build.sh docs # Documentation | ||
| ``` | ||
|
|
||
| ## Run Tests | ||
|
|
||
| > Activate the conda env used to build first (`conda activate <env-name>`) and ensure datasets are fetched — see [Pre-flight Checks](../SKILL.md#pre-flight-checks-required-before-first-build-or-test) in SKILL.md. | ||
|
|
||
| ```bash | ||
| # C++ tests | ||
| ctest --test-dir cpp/build | ||
|
|
||
| # Python tests | ||
| pytest -v python/cuopt/cuopt/tests | ||
|
|
||
| # Server tests | ||
| pytest -v python/cuopt_server/tests | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| # Contributing — Commits, PRs, and Common Tasks | ||
|
|
||
| Read this for anything related to committing, pushing, opening PRs, or making structural changes to cuOpt (adding a solver parameter, dependency, server endpoint, or CUDA kernel). | ||
|
|
||
| ## Before You Commit | ||
|
|
||
| ### 1. Install Pre-commit Hooks | ||
|
|
||
| Run once per clone to have style checks run automatically on every `git commit`: | ||
|
|
||
| ```bash | ||
| pre-commit install | ||
| ``` | ||
|
|
||
| If a hook fails, the commit is blocked — fix the issues and commit again. To check all files manually (e.g., before pushing), run `pre-commit run --all-files --show-diff-on-failure`. | ||
|
|
||
| ### 2. Make Meaningful Commits | ||
|
|
||
| Group related changes into logical commits rather than committing all files at once. Each commit should represent one coherent change (e.g., separate the C++ change from the Python binding update from the test addition). This makes `git log` and `git bisect` useful for debugging later. | ||
|
|
||
| ### 3. Sign Your Commits (DCO Required) | ||
|
|
||
| ```bash | ||
| git commit -s -m "Your message" | ||
| ``` | ||
|
|
||
| To fix a prior commit missing the sign-off, use `git commit --amend -s` (or an interactive rebase for older commits). Do **not** use `--no-verify` to bypass the DCO check. | ||
|
|
||
| ### 4. Use Forks for Pull Requests | ||
|
|
||
| Never push branches directly to the main cuOpt repository. Use the fork workflow: | ||
|
|
||
| ```bash | ||
| # 1. Clone the main repo | ||
| git clone git@github.com:NVIDIA/cuopt.git | ||
| cd cuopt | ||
|
|
||
| # 2. Add your fork as a remote | ||
| git remote add fork git@github.com:<your-username>/cuopt.git | ||
|
|
||
| # 3. Create a branch from the appropriate base | ||
| git checkout -b my-feature-branch | ||
|
|
||
| # 4. Make changes, commit, then push to your fork | ||
| git push fork my-feature-branch | ||
|
|
||
| # 5. Create PR from your fork → upstream base branch | ||
| ``` | ||
|
|
||
| This applies to both human contributors and AI agents. Agents must never push to the upstream repo directly — provide the push command for the user to review and execute from their fork. | ||
|
|
||
| ### Pull Requests Created by Agents | ||
|
|
||
| When an AI agent creates a pull request, it **must be a draft PR** (`gh pr create --draft`). This gives the developer time to review and iterate on the changes before any reviewers get pinged. The developer marks it as ready for review when satisfied. | ||
|
|
||
| ### PR Descriptions | ||
|
|
||
| Keep PR summaries **short and informative**. State what changed and why in a few bullet points. Avoid verbose explanations, full file listings, or restating the diff. Reviewers read the code — the summary should give them context, not a transcript. | ||
|
|
||
| ## Common Tasks | ||
|
|
||
| ### Adding a Solver Parameter | ||
|
|
||
| 1. Add to settings struct in `cpp/include/cuopt/` and wire into `set_parameter_from_string()` in `cpp/src/` | ||
| 2. Expose in Python — if using the string-based interface, the parameter is auto-discovered (no `.pyx` change needed). Add a convenience method in `SolverSettings` if warranted. See [python_bindings.md](python_bindings.md) for the full checklist. | ||
| 3. Add to server schema (`docs/cuopt/source/cuopt_spec.yaml`) if applicable | ||
| 4. Add tests at C++ and Python levels | ||
| 5. Rebuild: `./build.sh libcuopt && ./build.sh cuopt` | ||
| 6. Update documentation | ||
|
|
||
| ### Adding a Dependency | ||
|
|
||
| All dependencies are managed through `dependencies.yaml` — never edit `conda/environments/*.yaml` or `pyproject.toml` files directly. The file uses [RAPIDS dependency-file-generator](https://github.com/rapidsai/dependency-file-generator) format: | ||
|
|
||
| 1. Find the appropriate group in `dependencies.yaml` (e.g., `build_cpp`, `run_common`, `test_python_common`) | ||
| 2. Add the package under the correct `output_types` (`conda`, `requirements`, `pyproject`, or a combination) | ||
| 3. Run `pre-commit run --all-files` — the RAPIDS dependency file generator hook regenerates downstream files automatically | ||
| 4. Verify: check that `conda/environments/` and relevant `pyproject.toml` files were updated | ||
|
|
||
| ### Adding a Server Endpoint | ||
|
|
||
| 1. Add route in `python/cuopt_server/cuopt_server/webserver.py` | ||
| 2. Update OpenAPI spec `docs/cuopt/source/cuopt_spec.yaml` | ||
| 3. Add tests in `python/cuopt_server/tests/` | ||
| 4. Update documentation | ||
|
|
||
| ### Modifying CUDA Kernels | ||
|
|
||
| 1. Edit kernel in `cpp/src/` | ||
| 2. Follow stream-ordering patterns | ||
| 3. Run C++ tests: `ctest --test-dir cpp/build` | ||
| 4. Run benchmarks to check performance | ||
|
|
||
| ## Third-Party Code | ||
|
|
||
| **Always ask before including external code.** When copying or adapting external code, you must attribute it properly, verify license compatibility, and flag it in the PR. See the [Third-Party Code section in CONTRIBUTING.md](../../../CONTRIBUTING.md#third-party-code) for the full process. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # Coding Conventions, Error Handling, and Memory Management | ||
|
|
||
| Read this for cuOpt code style: naming, file extensions, include order, error handling, memory management, and test impact. | ||
|
|
||
| ## C++ Naming | ||
|
|
||
| | Element | Convention | Example | | ||
| |---------|------------|---------| | ||
| | Variables | `snake_case` | `num_locations` | | ||
| | Functions | `snake_case` | `solve_problem()` | | ||
| | Classes | `snake_case` | `data_model` | | ||
| | Test cases | `PascalCase` | `SolverTest` | | ||
| | Device data | `d_` prefix | `d_locations_` | | ||
| | Host data | `h_` prefix | `h_data_` | | ||
| | Template params | `_t` suffix | `value_t` | | ||
| | Private members | `_` suffix | `n_locations_` | | ||
|
|
||
| ## File Extensions | ||
|
|
||
| | Extension | Usage | | ||
| |-----------|-------| | ||
| | `.hpp` | C++ headers | | ||
| | `.cpp` | C++ source | | ||
| | `.cu` | CUDA 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 | ||
| - Tests use pytest | ||
|
|
||
| ## Error Handling | ||
|
|
||
| ### Runtime Assertions | ||
|
|
||
| ```cpp | ||
| CUOPT_EXPECTS(condition, "Error message"); | ||
| CUOPT_FAIL("Unreachable code reached"); | ||
| ``` | ||
|
|
||
| ### CUDA Error Checking | ||
|
|
||
| ```cpp | ||
| RAFT_CUDA_TRY(cudaMemcpy(...)); | ||
| ``` | ||
|
|
||
| ## Memory Management | ||
|
|
||
| ```cpp | ||
| // ❌ WRONG | ||
| int* data = new int[100]; | ||
|
|
||
| // ✅ CORRECT - use RMM | ||
| rmm::device_uvector<int> data(100, stream); | ||
| ``` | ||
|
|
||
| - All operations should accept `cuda_stream_view` | ||
| - Views (`*_view` suffix) are non-owning | ||
|
|
||
| Read existing code in `cpp/src/` for real examples of RMM allocation, stream-ordering, RAFT utilities, and kernel launch patterns. | ||
|
|
||
| ## Test Impact Check | ||
|
|
||
| **Before any behavioral change, ask:** | ||
|
|
||
| 1. What scenarios must be covered? | ||
| 2. What's the expected behavior contract? | ||
| 3. Where should tests live? | ||
| - C++ gtests: `cpp/tests/` | ||
| - Python pytest: `python/.../tests/` | ||
|
|
||
| **Add at least one regression test for new behavior.** |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # Troubleshooting & CI Gotchas | ||
|
|
||
| Read this when a build, test, or CI step fails — symptoms, causes, fixes. | ||
|
|
||
| ## Common Pitfalls | ||
|
|
||
| | Problem | Solution | | ||
| |---------|----------| | ||
| | Cython changes not reflected | Rerun: `./build.sh cuopt` | | ||
| | Missing `nvcc` | Set `$CUDACXX` or add CUDA to `$PATH` | | ||
| | OOM during build | Lower `PARALLEL_LEVEL` (e.g., `export PARALLEL_LEVEL=8`) | | ||
| | CUDA out of memory | Reduce problem size | | ||
| | Build fails with CUDA errors on older driver | Conda installs `cuda-nvcc` for the latest supported CUDA (e.g., 13.1), but your GPU driver may not support it. Check with `nvidia-smi` — the top-right shows max CUDA version. Override with: `conda install cuda-nvcc=12.9` (or whichever version your driver supports). See [CUDA compatibility matrix](https://docs.nvidia.com/deploy/cuda-compatibility/) | | ||
| | Slow debug library loading | Device symbols cause delay | | ||
|
|
||
| ## CI Gotchas | ||
|
|
||
| | Failure | Cause | Fix | | ||
| |---------|-------|-----| | ||
| | Style check | Formatting drift | Run `pre-commit run --all-files` and commit fixes | | ||
| | DCO sign-off | Missing `-s` flag | `git commit --amend -s` (or rebase to fix older commits) | | ||
| | Dependency mismatch | Edited `pyproject.toml` or `conda/environments/` directly | Edit `dependencies.yaml` instead, let pre-commit regenerate | | ||
| | Skill validation | Missing frontmatter or version mismatch | Run `./ci/utils/validate_skills.sh` locally to diagnose | | ||
|
|
||
| For CI scripts and pipeline details, see [ci/README.md](../../../ci/README.md). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,17 @@ | ||
| --- | ||
| name: cuopt-installation-developer | ||
| version: "26.06.00" | ||
| description: Developer installation — build cuOpt from source, run tests. Use when the user wants to set up a dev environment to contribute or modify cuOpt. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does this need to reference build_and_test.md under cuopt-developer?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are referring cuopt-developer at the end for rest. So I think it will be covered |
||
| description: First-time dev env setup for cuOpt (CUDA check, conda env, initial build). Hand off to cuopt-developer for ongoing build/test/contribute work. | ||
| --- | ||
|
|
||
| # cuOpt Installation — Developer | ||
|
|
||
| Set up an environment to **build cuOpt from source** and run tests. For contribution behavior and PRs, see the developer skill after the build works. | ||
| **First-time dev environment setup**: verify CUDA/driver compatibility, create the conda env, clone, complete the first build. Once the env works, switch to `cuopt-developer` for ongoing build/test/contribute work. | ||
|
|
||
| ## When to use this skill | ||
|
|
||
| - User wants to *build* cuOpt (clone, build deps, build, tests). | ||
| - User is **setting up the dev environment for the first time** — clone, conda env, build deps, initial build. | ||
| - Once the env is working, switch to `cuopt-developer` for ongoing build, test, debug, and contribute work. | ||
| - Not for *using* cuOpt (pip/conda) — use the user installation skill instead. | ||
|
|
||
| ## Required questions (environment) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.