Skip to content
Draft
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
25 changes: 25 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
- conda-cpp-tests
- conda-cpp-checks
- conda-python-build
- conda-python-import-tests
- conda-python-tests
- rocky8-clib-standalone-build
- rocky8-clib-tests
Expand Down Expand Up @@ -170,6 +171,7 @@ jobs:
- '!ci/run_cuvs_pytests.sh'
- '!ci/test_cpp.sh'
- '!ci/test_python.sh'
- '!ci/test_python_imports.sh'
- '!ci/test_wheel_cuvs.sh'
- '!ci/validate_wheel.sh'
- '!conda/environments/**'
Expand Down Expand Up @@ -285,6 +287,7 @@ jobs:
- '!ci/test_java.sh'
- '!ci/test_lucene.sh'
- '!ci/test_python.sh'
- '!ci/test_python_imports.sh'
- '!ci/test_standalone_c.sh'
- '!ci/validate_wheel.sh'
- '!CODEOWNERS'
Expand Down Expand Up @@ -345,6 +348,7 @@ jobs:
- '!ci/test_java.sh'
- '!ci/test_lucene.sh'
- '!ci/test_python.sh'
- '!ci/test_python_imports.sh'
- '!ci/test_wheel_cuvs.sh'
- '!ci/validate_wheel.sh'
- '!docs/**'
Expand Down Expand Up @@ -398,6 +402,7 @@ jobs:
- '!ci/test_java.sh'
- '!ci/test_lucene.sh'
- '!ci/test_python.sh'
- '!ci/test_python_imports.sh'
- '!ci/test_standalone_c.sh'
- '!ci/test_wheel_cuvs.sh'
- '!ci/validate_wheel.sh'
Expand Down Expand Up @@ -549,6 +554,26 @@ jobs:
# Build a conda package for each CUDA x ARCH x minimum supported Python version
matrix_filter: group_by({CUDA_VER, ARCH}) | map(min_by(.PY_VER | split(".") | map(tonumber)))
matrix_type: pull-request
conda-python-import-tests:
# Installs the built Python packages with only their runtime dependencies and imports them on a
# CPU-only runner. This used to run as recipe tests inside conda-python-build; running it here
# keeps it off the critical path of the GPU test jobs.
needs: [conda-python-build, changed-files]
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/custom-job.yaml@main
if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda
with:
build_type: pull-request
node_type: cpu8
arch: "amd64"
container_image: "rapidsai/ci-conda:26.12-latest"
script: "ci/test_python_imports.sh"
conda-python-tests:
needs: [conda-python-build, changed-files]
permissions:
Expand Down
90 changes: 90 additions & 0 deletions ci/test_python_imports.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/bin/bash
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Install the built cuVS Conda packages with only their runtime dependencies
# and import them on a CPU-only runner. This replaces the import tests that
# used to run inside each recipe build, taking them off the critical path of
# the GPU test jobs, and checks that nothing links against the CUDA driver or
# initializes CUDA at import time.

set -euo pipefail

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

rapids-logger "Downloading built Conda packages"
CPP_CHANNEL=$(rapids-download-from-github "$(rapids-artifact-name conda_cpp libcuvs cuvs --cuda "$RAPIDS_CUDA_VERSION")")
PYTHON_CHANNEL=$(rapids-download-from-github "$(rapids-artifact-name conda_python cuvs cuvs --stable --cuda "$RAPIDS_CUDA_VERSION")")

# Create an environment holding the given built packages and their runtime
# dependencies, then import the given Python modules in it.
#
# usage: import_packages <env name> <package glob> [<package glob> ...] -- <module> [<module> ...]
import_packages() {
local env_name="$1"
shift
local packages=()
while [[ "$1" != "--" ]]; do
packages+=("$1")
shift
done
shift

rapids-logger "Install ${packages[*]} with only their runtime dependencies"
rapids-mamba-retry create --yes --name "${env_name}" --strict-channel-priority \
--override-channels \
--channel "${PYTHON_CHANNEL}" --channel "${CPP_CHANNEL}" \
--channel rapidsai-nightly --channel conda-forge \
"python=${RAPIDS_PY_VERSION}" "${packages[@]}"

set +u
conda activate "${env_name}"
set -u
rapids-print-env

for module in "$@"; do
rapids-logger "Import ${module} on a CPU-only runner"
python -c "import ${module}"
done

rapids-logger "Check that cuvs_bench ships its dataset configuration"
python -c "from importlib.resources import files; path = files('cuvs_bench') / 'config' / 'datasets' / 'datasets.yaml'; assert path.is_file(), path"

set +u
conda deactivate
set -u
}

# cuvs-bench and cuvs-bench-cpu both provide the cuvs_bench module, so they
# are checked in separate environments.
import_packages python_imports \
"${PYTHON_CHANNEL}"/linux-64/cuvs-[0-9]*.conda \
"${PYTHON_CHANNEL}"/linux-64/cuvs-bench-[0-9]*.conda \
-- \
cuvs \
cuvs.cluster \
cuvs.common \
cuvs.distance \
cuvs.neighbors \
cuvs.preprocessing \
cuvs_bench \
cuvs_bench.generate_groundtruth \
cuvs_bench.get_dataset \
cuvs_bench.plot \
cuvs_bench.run \
cuvs_bench.split_groundtruth

# cuvs-bench-cpu is only built for one CUDA major version (see ci/build_python.sh).
if compgen -G "${PYTHON_CHANNEL}/linux-64/cuvs-bench-cpu-[0-9]*.conda" > /dev/null; then
import_packages python_imports_cpu \
"${PYTHON_CHANNEL}"/linux-64/cuvs-bench-cpu-[0-9]*.conda \
-- \
cuvs_bench \
cuvs_bench.generate_groundtruth \
cuvs_bench.get_dataset \
cuvs_bench.plot \
cuvs_bench.run \
cuvs_bench.split_groundtruth
else
rapids-logger "No cuvs-bench-cpu package was built for CUDA ${RAPIDS_CUDA_VERSION}; skipping"
fi
14 changes: 0 additions & 14 deletions conda/recipes/cuvs-bench-cpu/recipe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ context:
linux64: ${{ linux and x86_64 }}
py_abi_min: ${{ env.get("RAPIDS_PY_VERSION") }}
py_buildstring: ${{ py_abi_min | version_to_buildstring }}
py_runtime_latest: "3.14"

package:
name: cuvs-bench-cpu
Expand Down Expand Up @@ -118,19 +117,6 @@ requirements:
- libcublas
- mkl # relaxes pin from host `mkl-devel`


tests:
- python:
imports:
- cuvs_bench
- cuvs_bench.generate_groundtruth
- cuvs_bench.get_dataset
- cuvs_bench.plot
- cuvs_bench.run
- cuvs_bench.split_groundtruth
python_version: ${{ py_runtime_latest }}.*
pip_check: false

about:
homepage: ${{ load_from_file("python/cuvs_bench/pyproject.toml").project.urls.Homepage }}
license: ${{ load_from_file("python/cuvs_bench/pyproject.toml").project.license }}
Expand Down
16 changes: 0 additions & 16 deletions conda/recipes/cuvs-bench/recipe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ context:
head_rev: '${{ git.head_rev(".")[:8] }}'
py_abi_min: ${{ env.get("RAPIDS_PY_VERSION") }}
py_buildstring: ${{ py_abi_min | version_to_buildstring }}
py_runtime_latest: "3.14"

package:
name: cuvs-bench
Expand Down Expand Up @@ -60,21 +59,6 @@ requirements:
by_name:
- cuda-version

tests:
- package_contents:
files:
- site-packages/cuvs_bench/config/datasets/datasets.yaml
- python:
imports:
- cuvs_bench
- cuvs_bench.generate_groundtruth
- cuvs_bench.get_dataset
- cuvs_bench.plot
- cuvs_bench.run
- cuvs_bench.split_groundtruth
python_version: ${{ py_runtime_latest }}.*
pip_check: false

about:
homepage: ${{ load_from_file("python/cuvs_bench/pyproject.toml").project.urls.Homepage }}
license: ${{ load_from_file("python/cuvs_bench/pyproject.toml").project.license }}
Expand Down
8 changes: 0 additions & 8 deletions conda/recipes/cuvs/recipe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ context:
head_rev: '${{ git.head_rev(".")[:8] }}'
py_abi_min: ${{ env.get("RAPIDS_PY_VERSION") }}
py_buildstring: ${{ py_abi_min | version_to_buildstring }}
py_runtime_latest: "3.14"

package:
name: cuvs
Expand Down Expand Up @@ -99,13 +98,6 @@ requirements:
- cuda-version
- cuda-cudart

tests:
- python:
imports:
- cuvs
python_version: ${{ py_runtime_latest }}.*
pip_check: false

about:
homepage: ${{ load_from_file("python/cuvs/pyproject.toml").project.urls.Homepage }}
license: ${{ load_from_file("python/cuvs/pyproject.toml").project.license }}
Expand Down
Loading