Skip to content
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
a4c7a73
feat: add stable install testing for pip installs
gforsyth Apr 7, 2026
68e59ef
feat: add stable install testing for conda installs
gforsyth Apr 7, 2026
9bc9fbf
ci: add nightly test jobs for pip and conda stable installs
gforsyth Apr 7, 2026
5c3d9bc
refactor: apply suggestions from code review
gforsyth Apr 8, 2026
188e5c8
chore: remove defunct import script
gforsyth Apr 8, 2026
eac7264
refactor(ci): use matrix for arch selection
gforsyth Apr 8, 2026
e6e8f51
chore(release): bump stable rapids version for install checks
gforsyth Apr 8, 2026
f000c6d
refactor: add combined import test
gforsyth Apr 8, 2026
ca836f0
refactor(pip): download nvidia PyPI wheels and install upstream wheel…
gforsyth Apr 8, 2026
858fa3e
refactor(pip): test on cuda-toolkit major-minor
gforsyth Apr 8, 2026
b6bf46d
fix(imports): don't swallow import errors
gforsyth Apr 13, 2026
1597c63
revertme: add tests to `pr.yaml`
gforsyth Apr 13, 2026
80050f1
fix: source `test_imports` from CWD
gforsyth Apr 13, 2026
cd8e485
fix: source scripts relative to invocation directory
gforsyth Apr 13, 2026
0e78bc0
refactor: use `rapidsai/citestwheel` instead of `nvidia/cuda`
gforsyth Apr 13, 2026
a72cc90
fix: restore bootstrap uv install in pip script
gforsyth Apr 13, 2026
0d44f2d
chore: run newer minor versions first
gforsyth Apr 13, 2026
5b128ac
feat(imports): finish import tests but raise if any fail along the way
gforsyth Apr 13, 2026
0d88656
refactor: put minor version arrays at the top of the file for reference
gforsyth Apr 14, 2026
4476022
fix(env_setup): install explicit list of cuda-toolkit extras to avoid…
gforsyth Apr 14, 2026
d2dfd6b
fix: cleanup environment after each run so we don't run out of disk s…
gforsyth Apr 14, 2026
d518002
fix: remove nightly index from pip config
gforsyth Apr 15, 2026
78daa33
chore: update pip config mutation
gforsyth Apr 20, 2026
7ed84f4
fix: shift operator into array elements to loosen ctk12.2 bound
gforsyth Apr 20, 2026
5ab9e43
refactor: error if output contains error messages
gforsyth Apr 21, 2026
1be7ebf
fix: don't import `cucim` on cpu-only
gforsyth Apr 21, 2026
f1bb840
chore: remove tests from pr.yaml, restore in test.yaml
gforsyth Apr 22, 2026
17a1749
refactor: use compute-matrix to fan out jobs
gforsyth Apr 22, 2026
076fcf3
refactor(pip): remove looping from test script, require CUDA_VER and …
gforsyth Apr 22, 2026
7f96dcf
refactor(conda): remove looping from test script, require CUDA_VER an…
gforsyth Apr 22, 2026
dd30e2b
fix(ci): use correct node_type label
gforsyth Apr 22, 2026
c1a663d
fix(pip): fix container image name construction
gforsyth Apr 22, 2026
50721f0
fix(conda): strip patch version when installing `cuda-version`
gforsyth Apr 22, 2026
b359965
fix(pip): move `pip.conf` manually until we have 26.06 images
gforsyth Apr 22, 2026
3cd80a8
refactor: pass imports array to function, sort imports
gforsyth Apr 22, 2026
8a6ac7d
fix(pip): install rapidsmpf and cudf-polars, add branch for 12.2 arm
gforsyth Apr 22, 2026
b4ffdcf
fix(shellcheck): ignore unused variable warning for passing by name
gforsyth Apr 22, 2026
34bb97a
refactor: use compute-matrix in `test.yaml`
gforsyth Apr 22, 2026
c542852
fix(update-version): set stable install test to latest stable release
gforsyth Apr 22, 2026
1fec84b
chore: restore `conda-nightly-env` test and remove stable install che…
gforsyth Apr 27, 2026
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
47 changes: 47 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,50 @@ jobs:
script: "ci/test_conda_nightly_env.sh"
# just using the workflow to get the matrix, this isn't actually building anything we want to upload
upload-artifacts: false
test-stable-install-pip-cuda-12:
uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main
strategy:
fail-fast: false
matrix:
arch:
- amd64
- arm64
with:
build_type: pull-request
node_type: "cpu4"
arch: "${{matrix.arch}}"
container_image: "rapidsai/citestwheel:cuda12.9.1-ubuntu24.04-py3.14"
Comment thread
gforsyth marked this conversation as resolved.
Outdated
script: |
./ci/stable_install/install_and_test_pip.sh --cuda cu12
test-stable-install-pip-cuda-13:
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main
strategy:
fail-fast: false
matrix:
arch:
- amd64
- arm64
with:
build_type: pull-request
node_type: "cpu4"
arch: "${{matrix.arch}}"
container_image: "rapidsai/citestwheel:cuda13.2.0-ubuntu24.04-py3.14"
script: |
./ci/stable_install/install_and_test_pip.sh --cuda cu13
test-stable-install-conda:
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@main
strategy:
fail-fast: false
matrix:
arch:
- amd64
- arm64
with:
build_type: pull-request
node_type: "cpu4"
arch: "${{matrix.arch}}"
container_image: "rapidsai/ci-conda:26.04-latest"
script: |
./ci/stable_install/install_and_test_conda.sh
1 change: 1 addition & 0 deletions ci/release/update-version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ function sed_runner() {

sed_runner "/RAPIDS_VER=/ s/[0-9][0-9].[0-9][0-9]/${NEXT_SHORT_TAG}/" ci/conda-pack.sh
sed_runner "/RAPIDS_VERSION=/ s/[0-9][0-9].[0-9][0-9]/${NEXT_SHORT_TAG}/" ci/test_conda_nightly_env.sh
sed_runner "/STABLE_RAPIDS_VERSION=/ s/[0-9][0-9].[0-9][0-9]/${NEXT_SHORT_TAG}/" ci/stable_install/install_and_test_*.sh
Comment thread
gforsyth marked this conversation as resolved.
Outdated

# CI files - context-aware branch references
for FILE in .github/workflows/*.yaml; do
Expand Down
16 changes: 16 additions & 0 deletions ci/stable_install/bootstrap/pip.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
# Copyright (c) 2026, NVIDIA CORPORATION.

set -euo pipefail

echo "installing 'uv'"
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "done installing 'uv'"

source "$HOME"/.local/bin/env

rapids-logger "Removing nightly PyPI index"
pip config --global unset global.extra-index-url

rapids-logger "Setting pip global retries to 10"
pip config --global set global.retries 10
63 changes: 63 additions & 0 deletions ci/stable_install/install_and_test_conda.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/bin/bash
# Copyright (c) 2026, NVIDIA CORPORATION.

# By default, this script attempts to install the latest stable RAPIDS version
# in a clean conda environment for all supported versions of Python and CUDA
#
# The Python version, CUDA version, and RAPIDS version can be overridden by
# supplying the value to test to the appropriate flag (--python, --rapids, and
# --cuda, respectively).

set -euo pipefail

SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
source "${SCRIPT_DIR}/test_imports.sh"

STABLE_RAPIDS_VERSION="26.4.*"
Comment thread
gforsyth marked this conversation as resolved.
SUPPORTED_PYTHON_VERSIONS=(3.11 3.12 3.13 3.14)
SUPPORTED_CUDA_VERSIONS=("12.2" "12.9" "13.0" "13.1")

while [[ $# -gt 0 ]]; do
case $1 in
--python)
shift
SUPPORTED_PYTHON_VERSIONS=("$1")
shift
;;
--rapids)
shift
STABLE_RAPIDS_VERSION="$1"
shift
;;
--cuda)
shift
SUPPORTED_CUDA_VERSIONS=("$1")
shift
;;
-*)
rapids-echo-stderr "Unknown flag: $1. Supported flags: --python, --rapids, --cuda"
exit 1
;;
esac
done

. /opt/conda/etc/profile.d/conda.sh

for CUDA_VERSION in "${SUPPORTED_CUDA_VERSIONS[@]}"; do
for PY_VER in "${SUPPORTED_PYTHON_VERSIONS[@]}"; do
envName="rapids_${PY_VER}_${CUDA_VERSION}"

rapids-logger "Testing stable version install with Python $PY_VER and CUDA version $CUDA_VERSION"

# use `-O` to override channels so we don't include `rapidsai-nightly`
conda create -n "$envName" -O -c rapidsai -c conda-forge -y \
rapids="$STABLE_RAPIDS_VERSION" python="$PY_VER" "cuda-version==${CUDA_VERSION}"

conda activate "$envName"

testImports cudf dask_cudf cuml pylibraft raft_dask cugraph nx_cugraph cuxfilter cuvs # cucim

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we want cudf-polars, rapidsmpf, rmm …? There are many packages not listed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I was initially copying what's listed in the basic install docs, but I can add more packages


conda deactivate
conda env remove -n "$envName"
done
done
123 changes: 123 additions & 0 deletions ci/stable_install/install_and_test_pip.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/bin/bash
# Copyright (c) 2026, NVIDIA CORPORATION.

# By default, this script attempts to install the latest stable RAPIDS version
# in a clean Python venv for all supported versions of Python and CUDA
#
# The Python version, CUDA version, and RAPIDS version can be overridden by
# supplying the value to test to the appropriate flag (--python, --rapids, and
# --cuda, respectively).
#
# Note that the CUDA version should be specified as a -cu* suffix, e.g. `--cuda cu13`
# and will iterate over all supported minor CUDA versions, so `cu13` will test (13.0, 13.1)

set -euo pipefail

STABLE_RAPIDS_VERSION="26.4.*"
SUPPORTED_PYTHON_VERSIONS=(3.11 3.12 3.13 3.14)
SUPPORTED_CUDA_VERSIONS=("cu12" "cu13")
Comment thread
gforsyth marked this conversation as resolved.
Outdated
CUDA12_MINOR_VERSIONS=('>=12.2,<12.4' '==12.9')
CUDA13_MINOR_VERSIONS=('==13.0' '==13.1')

SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
source "${SCRIPT_DIR}/bootstrap/pip.sh"
source "${SCRIPT_DIR}/test_imports.sh"

while [[ $# -gt 0 ]]; do
case $1 in
--python)
shift
SUPPORTED_PYTHON_VERSIONS=("$1")
shift
;;
--rapids)
shift
STABLE_RAPIDS_VERSION="$1"
shift
;;
--cuda)
shift
SUPPORTED_CUDA_VERSIONS=("$1")
shift
;;
-*)
rapids-echo-stderr "Unknown flag: $1. Supported flags: --python, --rapids, --cuda"
exit 1
;;
esac
done

function createPyEnv {
PY_VER=$1
INSTALL_DIR=$2
pushd "$INSTALL_DIR"

rapids-logger "Creating virtualenv for Python $PY_VER"
uv venv --python="$PY_VER" --seed
Comment thread
gforsyth marked this conversation as resolved.
source "${INSTALL_DIR}/.venv/bin/activate"
}


for CUDA_SUFFIX in "${SUPPORTED_CUDA_VERSIONS[@]}"; do

case "${CUDA_SUFFIX}" in
cu12) CUDA_MINOR_VERSIONS=("${CUDA12_MINOR_VERSIONS[@]}") ;;
cu13) CUDA_MINOR_VERSIONS=("${CUDA13_MINOR_VERSIONS[@]}") ;;
esac



for cuda_major_minor in "${CUDA_MINOR_VERSIONS[@]}"; do
rapids-logger "Using cuda-toolkit for CUDA ${cuda_major_minor}"
PIP_INSTALL_PYPI=(
"cudf-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}"
"dask-cudf-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}"
"cuml-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}"
"pylibraft-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}"
"raft-dask-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}"
"cuda-toolkit[cublas,cufft,curand,cusolver,cusparse,nvcc,nvrtc]${cuda_major_minor}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe you can pin just the metapackage with no extras. The extras should be included in the solve by the other libraries. In fact, that should help ensure we have listed the right extras.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

James had a reason he wanted the extras explicitly listed but I can't remember what it was -- happy to go either way

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

James had a reason he wanted the extras explicitly listed but I can't remember what it was

Because without them, you can get a solve like:

cuda-toolkit==12.9.1
nvidia-cublas-cu12=={version-from-CUDA-13.0}

The solver can choose to work around conflicts by falling back to packages that pinned against nvidia-{component} wheels instead of cuda-toolkit.

Using the extras prevents that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That said I'm fine with this how it is, without the extras. No need for a followup.

)


for PY_VER in "${SUPPORTED_PYTHON_VERSIONS[@]}"; do

INSTALL_DIR=$(mktemp -d)
createPyEnv "$PY_VER" "$INSTALL_DIR"

rapids-logger "Downloading NVIDIA PyPI only wheels for Python $PY_VER and CUDA $cuda_major_minor"

WHEELS_DIR=$(mktemp -d)
pip download \
--isolated \
--index-url https://pypi.nvidia.com \
--prefer-binary \
--no-deps \
-d "${WHEELS_DIR}" \
"cucim-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}" \
"cugraph-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}" \
"cuvs-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}" \
"cuxfilter-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}" \
"libcugraph-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}" \
"libcuvs-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}" \
"nx-cugraph-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}" \
"pylibcugraph-${CUDA_SUFFIX}==${STABLE_RAPIDS_VERSION}"
Comment thread
gforsyth marked this conversation as resolved.
Outdated

rapids-logger "Testing stable version install with Python $PY_VER and CUDA $cuda_major_minor"

pip install \
--isolated \
--index-url https://pypi.org/simple \
--prefer-binary \
"${PIP_INSTALL_PYPI[@]}" \
"${WHEELS_DIR}"/*.whl

# can't import cucim on CPU-only
testImports cudf dask_cudf cuml pylibraft raft_dask cugraph nx_cugraph cuxfilter cuvs # cucim

popd

rapids-logger "Removing environment in $INSTALL_DIR/.venv"
rm -rf "$INSTALL_DIR/.venv"
done
done
done
53 changes: 53 additions & 0 deletions ci/stable_install/test_imports.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/bash
# Copyright (c) 2026, NVIDIA CORPORATION.

set -euo pipefail

# Patterns in import output that we want to flag as a failure even when Python exits 0
declare -a IMPORT_ERROR_PATTERNS=(
"dlopen error"
"cannot open shared object file"
"missing cuda symbols"
"initialization failed"
)
IMPORT_ERROR_PATTERN=$(printf "%s|" "${IMPORT_ERROR_PATTERNS[@]}")
# Strip off the trailing `|` from joining the patterns together
IMPORT_ERROR_PATTERN="${IMPORT_ERROR_PATTERN%|}"

function runImport {
local cmd="$1"
local label="$2"
local output exit_code=0
output=$(python -c "$cmd" 2>&1) || exit_code=$?
[[ -n "$output" ]] && echo "$output"
if [[ $exit_code -ne 0 ]]; then
rapids-logger "Test failed for: $label"
return 1
# here we grep over the combined output to look for errors that we want to
# flag even if Python would exit cleanly
# -E is for extended regex support for the pattern1|pattern2 matching
elif echo "$output" | grep -qi -E "${IMPORT_ERROR_PATTERN}"; then
rapids-logger "Test failed for: $label (error pattern detected in output)"
return 1
else
rapids-logger "Passed"
return 0
fi
}

function testImports {
local -a imports=()
local failures=0
while [[ $# -gt 0 ]]; do
rapids-logger "Standalone import test for $1"
runImport "import $1" "$1" || failures=$((failures + 1))
# add import to array for combined import test before shifting
imports+=("$1")
shift
done
local import_cmd
import_cmd=$(printf "import %s; " "${imports[@]}")
rapids-logger "Combined import test for: ${imports[*]}"
runImport "${import_cmd}" "${imports[*]}" || failures=$((failures + 1))
return $failures
}
Comment thread
gforsyth marked this conversation as resolved.
Loading