Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# syntax=docker/dockerfile:1.5
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

ARG BASE
ARG PYTHON_PACKAGE_MANAGER=conda

FROM ${BASE} as pip-base

RUN apt update -y \
&& DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \
libboost-iostreams-dev \
libboost-serialization-dev \
libgrpc-dev \
libgrpc++-dev \
libprotobuf-dev \
protobuf-compiler \
protobuf-compiler-grpc \
libtbb-dev \
&& rm -rf /tmp/* /var/tmp/* /var/cache/apt/* /var/lib/apt/lists/*;

ENV DEFAULT_VIRTUAL_ENV=rapids
ENV RAPIDS_LIBUCX_PREFER_SYSTEM_LIBRARY=true

FROM ${BASE} as conda-base

ENV DEFAULT_CONDA_ENV=rapids

FROM ${PYTHON_PACKAGE_MANAGER}-base

ARG TARGETARCH

ARG CUDA
ENV CUDAARCHS="RAPIDS"
ENV CUDA_VERSION="${CUDA_VERSION:-${CUDA}}"

ARG PYTHON_PACKAGE_MANAGER
ENV PYTHON_PACKAGE_MANAGER="${PYTHON_PACKAGE_MANAGER}"

ENV PYTHONSAFEPATH="1"
ENV PYTHONUNBUFFERED="1"
ENV PYTHONDONTWRITEBYTECODE="1"

ENV HISTFILE="/home/coder/.cache/._bash_history"

###
# sccache configuration
###
ENV AWS_IDP_URL="https://token.rapids.nvidia.com"
ENV AWS_ROLE_ARN="arn:aws:iam::279114543810:role/rapids-token-sccache-devs"
ENV SCCACHE_REGION="us-east-2"
ENV SCCACHE_BUCKET="rapids-sccache-devs"
ENV SCCACHE_S3_USE_PREPROCESSOR_CACHE_MODE=true
ENV SCCACHE_IDLE_TIMEOUT=0

###
# sccache-dist configuration
###
# Enable sccache-dist by default
ENV DEVCONTAINER_UTILS_ENABLE_SCCACHE_DIST=1
# Compile locally if max retries exceeded
ENV SCCACHE_DIST_FALLBACK_TO_LOCAL_COMPILE=true
# Retry transient errors 4 times (for a total of 5 attempts)
ENV SCCACHE_DIST_MAX_RETRIES=4
# 1hr 59min (to accommodate debug builds)
ENV SCCACHE_DIST_REQUEST_TIMEOUT=7140
ENV SCCACHE_DIST_URL="https://${TARGETARCH}.linux.sccache.rapids.nvidia.com"

# Build as much in parallel as possible
ENV INFER_NUM_DEVICE_ARCHITECTURES=1
ENV MAX_DEVICE_OBJ_TO_COMPILE_IN_PARALLEL=20
60 changes: 60 additions & 0 deletions .devcontainer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# cuOpt Development Containers

This directory contains [devcontainer configurations](https://containers.dev/implementors/json_reference/) for using VSCode to [develop in a container](https://code.visualstudio.com/docs/devcontainers/containers) via the `Remote Containers` [extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) or [GitHub Codespaces](https://github.com/codespaces).

This container is a turnkey development environment for building and testing the cuOpt C++ and Python libraries.

## Table of Contents

* [Prerequisites](#prerequisites)
* [Host bind mounts](#host-bind-mounts)
* [Launch a Dev Container](#launch-a-dev-container)
* [Using the devcontainer](#using-the-devcontainer)

## Prerequisites

* [VSCode](https://code.visualstudio.com/download)
* [VSCode Remote Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)

## Host bind mounts

By default, the following directories are bind-mounted into the devcontainer:

* `${repo}:/home/coder/cuopt`
* `${repo}/../.aws:/home/coder/.aws`
* `${repo}/../.local:/home/coder/.local`
* `${repo}/../.cache:/home/coder/.cache`
* `${repo}/../.conda:/home/coder/.conda`
* `${repo}/../.config:/home/coder/.config`

This ensures caches, configurations, dependencies, and your commits are persisted on the host across container runs.

## Launch a Dev Container

To launch a devcontainer from VSCode, open the cuOpt repo and select the "Reopen in Container" button in the bottom right:<br/><img src="https://user-images.githubusercontent.com/178183/221771999-97ab29d5-e718-4e5f-b32f-2cdd51bba25c.png"/>
Comment thread
bdice marked this conversation as resolved.

Alternatively, open the VSCode command palette (typically `cmd/ctrl + shift + P`) and run the "Rebuild and Reopen in Container" command.

## Using the devcontainer

On startup, the devcontainer creates or updates the conda/pip environment using `cuopt/dependencies.yaml`.

The container includes convenience functions to clean, configure, and build the cuOpt components:

```shell
$ clean-cuopt-cpp # only cleans the C++ build dir
$ clean-cuopt-python # only cleans the Python build dir
$ clean-cuopt # cleans both C++ and Python build dirs

$ configure-cuopt-cpp # only configures cuOpt C++ lib

$ build-cuopt-cpp # only builds cuOpt C++ lib
$ build-cuopt-python # only builds cuOpt Python lib
$ build-cuopt # builds both C++ and Python libs
$ build-all # builds all libraries in this repo
```

* The C++ build script is a small wrapper around `cmake -S ~/cuopt/cpp -B ~/cuopt/cpp/build` and `cmake --build ~/cuopt/cpp/build`
* The Python build script is a small wrapper around `pip install --editable ~/cuopt/python/cuopt`

Unlike `build.sh`, these convenience scripts do not install the libraries after building them. Instead, they automatically inject the correct arguments to build the C++ libraries from source and use their build dirs as package roots.
44 changes: 44 additions & 0 deletions .devcontainer/cuda12.9-conda/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"build": {
"context": "${localWorkspaceFolder}/.devcontainer",
"dockerfile": "${localWorkspaceFolder}/.devcontainer/Dockerfile",
"args": {
"CUDA": "12.9",
"PYTHON_PACKAGE_MANAGER": "conda",
"BASE": "rapidsai/devcontainers:26.06-cpp-mambaforge"
}
},
"runArgs": [
"--rm",
"--name",
"${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-26.06-cuda12.9-conda",
"--ulimit",
"nofile=500000"
],
"hostRequirements": {"gpu": "optional"},
"features": {
"ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:26.6": {}
},
"overrideFeatureInstallOrder": [
"ghcr.io/rapidsai/devcontainers/features/rapids-build-utils"
],
"initializeCommand": ["/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config,conda/pkgs,conda/${localWorkspaceFolderBasename}-cuda12.9-envs}"],
"postAttachCommand": ["/bin/bash", "-c", "if [ ${CODESPACES:-false} = 'true' ]; then . devcontainer-utils-post-attach-command; . rapids-post-attach-command; fi"],
"workspaceFolder": "/home/coder",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/cuopt,type=bind,consistency=consistent",
"mounts": [
"source=${localWorkspaceFolder}/../.aws,target=/home/coder/.aws,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.cache,target=/home/coder/.cache,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.config,target=/home/coder/.config,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.conda/pkgs,target=/home/coder/.conda/pkgs,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.conda/${localWorkspaceFolderBasename}-cuda12.9-envs,target=/home/coder/.conda/envs,type=bind,consistency=consistent"
],
"customizations": {
"vscode": {
"extensions": [
"ms-python.flake8",
"nvidia.nsight-vscode-edition"
]
}
}
}
53 changes: 53 additions & 0 deletions .devcontainer/cuda12.9-pip/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"build": {
"context": "${localWorkspaceFolder}/.devcontainer",
"dockerfile": "${localWorkspaceFolder}/.devcontainer/Dockerfile",
"args": {
"CUDA": "12.9",
"PYTHON_PACKAGE_MANAGER": "pip",
"BASE": "rapidsai/devcontainers:26.06-cpp-cuda12.9-ucx1.19.0-openmpi5.0.10"
}
},
"runArgs": [
"--rm",
"--name",
"${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-26.06-cuda12.9-pip",
"--ulimit",
"nofile=500000"
],
"hostRequirements": {"gpu": "optional"},
"features": {
"ghcr.io/rapidsai/devcontainers/features/cuda:26.6": {
"version": "12.9",
"installcuBLAS": true,
"installcuDSS": true,
"installcuSOLVER": true,
"installcuRAND": true,
"installcuSPARSE": true
},
"ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:26.6": {}
},
"overrideFeatureInstallOrder": [
"ghcr.io/rapidsai/devcontainers/features/ucx",
"ghcr.io/rapidsai/devcontainers/features/cuda",
"ghcr.io/rapidsai/devcontainers/features/rapids-build-utils"
],
"initializeCommand": ["/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config/pip,local/share/${localWorkspaceFolderBasename}-cuda12.9-venvs}"],
"postAttachCommand": ["/bin/bash", "-c", "if [ ${CODESPACES:-false} = 'true' ]; then . devcontainer-utils-post-attach-command; . rapids-post-attach-command; fi"],
"workspaceFolder": "/home/coder",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/cuopt,type=bind,consistency=consistent",
"mounts": [
"source=${localWorkspaceFolder}/../.aws,target=/home/coder/.aws,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.cache,target=/home/coder/.cache,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.config,target=/home/coder/.config,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.local/share/${localWorkspaceFolderBasename}-cuda12.9-venvs,target=/home/coder/.local/share/venvs,type=bind,consistency=consistent"
],
"customizations": {
"vscode": {
"extensions": [
"ms-python.flake8",
"nvidia.nsight-vscode-edition"
]
}
}
}
44 changes: 44 additions & 0 deletions .devcontainer/cuda13.2-conda/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"build": {
"context": "${localWorkspaceFolder}/.devcontainer",
"dockerfile": "${localWorkspaceFolder}/.devcontainer/Dockerfile",
"args": {
"CUDA": "13.2",
"PYTHON_PACKAGE_MANAGER": "conda",
"BASE": "rapidsai/devcontainers:26.06-cpp-mambaforge"
}
},
"runArgs": [
"--rm",
"--name",
"${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-26.06-cuda13.2-conda",
"--ulimit",
"nofile=500000"
],
"hostRequirements": {"gpu": "optional"},
"features": {
"ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:26.6": {}
},
"overrideFeatureInstallOrder": [
"ghcr.io/rapidsai/devcontainers/features/rapids-build-utils"
],
"initializeCommand": ["/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config,conda/pkgs,conda/${localWorkspaceFolderBasename}-cuda13.2-envs}"],
"postAttachCommand": ["/bin/bash", "-c", "if [ ${CODESPACES:-false} = 'true' ]; then . devcontainer-utils-post-attach-command; . rapids-post-attach-command; fi"],
"workspaceFolder": "/home/coder",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/cuopt,type=bind,consistency=consistent",
"mounts": [
"source=${localWorkspaceFolder}/../.aws,target=/home/coder/.aws,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.cache,target=/home/coder/.cache,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.config,target=/home/coder/.config,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.conda/pkgs,target=/home/coder/.conda/pkgs,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.conda/${localWorkspaceFolderBasename}-cuda13.2-envs,target=/home/coder/.conda/envs,type=bind,consistency=consistent"
],
"customizations": {
"vscode": {
"extensions": [
"ms-python.flake8",
"nvidia.nsight-vscode-edition"
]
}
}
}
53 changes: 53 additions & 0 deletions .devcontainer/cuda13.2-pip/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"build": {
"context": "${localWorkspaceFolder}/.devcontainer",
"dockerfile": "${localWorkspaceFolder}/.devcontainer/Dockerfile",
"args": {
"CUDA": "13.2",
"PYTHON_PACKAGE_MANAGER": "pip",
"BASE": "rapidsai/devcontainers:26.06-cpp-cuda13.2-ucx1.19.0-openmpi5.0.10"
}
},
"runArgs": [
"--rm",
"--name",
"${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-26.06-cuda13.2-pip",
"--ulimit",
"nofile=500000"
],
"hostRequirements": {"gpu": "optional"},
"features": {
"ghcr.io/rapidsai/devcontainers/features/cuda:26.6": {
"version": "13.2",
"installcuBLAS": true,
"installcuDSS": true,
"installcuSOLVER": true,
"installcuRAND": true,
"installcuSPARSE": true
},
"ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:26.6": {}
},
"overrideFeatureInstallOrder": [
"ghcr.io/rapidsai/devcontainers/features/ucx",
"ghcr.io/rapidsai/devcontainers/features/cuda",
"ghcr.io/rapidsai/devcontainers/features/rapids-build-utils"
],
"initializeCommand": ["/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config/pip,local/share/${localWorkspaceFolderBasename}-cuda13.2-venvs}"],
"postAttachCommand": ["/bin/bash", "-c", "if [ ${CODESPACES:-false} = 'true' ]; then . devcontainer-utils-post-attach-command; . rapids-post-attach-command; fi"],
"workspaceFolder": "/home/coder",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/cuopt,type=bind,consistency=consistent",
"mounts": [
"source=${localWorkspaceFolder}/../.aws,target=/home/coder/.aws,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.cache,target=/home/coder/.cache,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.config,target=/home/coder/.config,type=bind,consistency=consistent",
"source=${localWorkspaceFolder}/../.local/share/${localWorkspaceFolderBasename}-cuda13.2-venvs,target=/home/coder/.local/share/venvs,type=bind,consistency=consistent"
],
"customizations": {
"vscode": {
"extensions": [
"ms-python.flake8",
"nvidia.nsight-vscode-edition"
]
}
}
}
26 changes: 26 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
- wheel-build-cuopt-mps-parser
- wheel-build-cuopt-sh-client
- test-self-hosted-server
- devcontainer
permissions:
contents: read
uses: rapidsai/shared-workflows/.github/workflows/pr-builder.yaml@main
Expand Down Expand Up @@ -159,6 +160,7 @@ jobs:
- '!.github/workflows/test.yaml'
- '!.github/workflows/test_images.yaml'
- '!.github/workflows/trigger-breaking-change-alert.yaml'
- '!.devcontainer/**'
- '!.gitignore'
- '!.pre-commit-config.yaml'
- '!AGENTS.md'
Expand Down Expand Up @@ -215,6 +217,7 @@ jobs:
- '!.github/workflows/test.yaml'
- '!.github/workflows/test_images.yaml'
- '!.github/workflows/trigger-breaking-change-alert.yaml'
- '!.devcontainer/**'
- '!.gitignore'
- '!.pre-commit-config.yaml'
- '!AGENTS.md'
Expand Down Expand Up @@ -279,6 +282,7 @@ jobs:
- '!.github/workflows/test.yaml'
- '!.github/workflows/test_images.yaml'
- '!.github/workflows/trigger-breaking-change-alert.yaml'
- '!.devcontainer/**'
- '!.gitignore'
- '!.pre-commit-config.yaml'
- '!AGENTS.md'
Expand Down Expand Up @@ -340,6 +344,7 @@ jobs:
- '!.github/workflows/test.yaml'
- '!.github/workflows/test_images.yaml'
- '!.github/workflows/trigger-breaking-change-alert.yaml'
- '!.devcontainer/**'
- '!.gitignore'
- '!.pre-commit-config.yaml'
- '!AGENTS.md'
Expand Down Expand Up @@ -627,3 +632,24 @@ jobs:
with:
build_type: pull-request
script: ci/test_self_hosted_service.sh
devcontainer:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to skip devcontainer build if there no changes required for the build or test ?

permissions:
actions: read
contents: read
id-token: write
packages: read
pull-requests: read
secrets: inherit # zizmor: ignore[secrets-inherit]
uses: rapidsai/shared-workflows/.github/workflows/build-in-devcontainer.yaml@main
with:
arch: '["amd64", "arm64"]'
cuda: '["13.2"]'
node_type: "cpu8"
env: |
SCCACHE_DIST_MAX_RETRIES=inf
SCCACHE_SERVER_LOG=sccache=debug
SCCACHE_DIST_FALLBACK_TO_LOCAL_COMPILE=false
build_command: |
sccache --zero-stats;
build-all -j0 -DBUILD_MIP_BENCHMARKS=ON -DBUILD_LP_BENCHMARKS=ON --verbose
sccache --show-adv-stats
Loading
Loading