mirror of
https://github.com/facebookresearch/faiss.git
synced 2026-10-11 22:50:00 +00:00
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5643 `faiss-gpu-cuvs` 1.15.0 fails at import on a clean install: ``` ImportError: libfaiss.so: undefined symbol: _ZTIN3rmm9bad_allocE ``` ## Root cause, measured RAPIDS 26.08 wrapped RMM in a per-release ABI inline namespace. `nm -D` on the published `librmm-cu13` wheels: | Version | `typeinfo for rmm::bad_alloc` | Exported instead | | --- | --- | --- | | 26.2.0 | present | | | 26.4.0 | present | | | 26.6.0 | present | | | 26.8.0 | **absent** | `typeinfo for rmm::_RMM_26_8::bad_alloc` | `pyproject-gpu-cuvs.toml` builds against `==26.06.*` in `before-all` but declares `>=26.06,<27` at runtime and in `test-requires`. A fresh install therefore pairs a 26.06-built `libfaiss.so` with a 26.8 `librmm.so` that renamed every `rmm::` symbol. Nothing vendored covers the gap: `repair-wheel-command` hands every RAPIDS `lib*.so*` under `/opt/cuvs` to `auditwheel --exclude`. The 1.15.0 wheel was uploaded 2026-08-03, two days before RAPIDS 26.08 reached PyPI. It published green and began failing for every new installer afterwards, which matches `build-pip-gpu / Build & test faiss-gpu-cuvs` going red on 2026-08-05 after 68 consecutive passes. An exact-series pin rather than a narrower range is required: the inline namespace encodes the release, so **any** range spanning more than one RAPIDS minor series is broken by construction. ## This diff - Pin `libcuvs-cu13`, `libraft-cu13`, and `librmm-cu13` to `==26.06.*` in both `dependencies` and `test-requires`. - Declare `libraft-cu13`. `faiss/python/__init__.py` imports `libraft` and calls `libraft.load_library()`, but only `before-all` installed it, so at runtime its version floated on `libcuvs-cu13` transitive metadata. - Correct the cuSOLVER soname in the `auditwheel` exclude list from `libcusolver.so.11` to `libcusolver.so.12`, which is what CUDA 13.2 ships. - Update the `_preload_gpu_libs` fix-it message, which told users to install the range this diff removes. - Add `TestCuvsRapidsPinning` to `tests/test_wheel_smoke_gpu.py`. ## Regression guard `tests/test_wheel_smoke_gpu.py` is already the `test-command` for the cuVS wheel, so the new class runs inside `build-pip-gpu.yml` with no workflow change and no new test file. It asserts three properties of the built wheel's own `Requires-Dist`: 1. every RAPIDS distribution `_preload_gpu_libs` dlopens is declared 2. each is pinned to `==26.06.*` rather than an open range 3. the installed versions sit in that series `_RAPIDS_SERIES` duplicates the series from `pyproject-gpu-cuvs.toml` because the wheel does not ship that file. The duplication is the tripwire: a RAPIDS bump has to touch both places deliberately. ## Prior attempt D117099095 made the version-pin change on 2026-08-23 and was abandoned on 2026-09-04 without landing. It never failed review. `faiss/public_tld/` is ShipIt-mirrored with `requireExportConfig`, so `github-export-checks` held it Unpublished pending a `facebookresearch/faiss` PR that a bot cannot open, and three pings over 12 days went unanswered. This diff needs that same export. ## Notes The published 1.15.0 metadata declares only `libcuvs-cu13`, not `librmm-cu13`. That is not a fbsource/GitHub divergence: `librmm-cu13` was added to `dependencies` on 2026-08-14, after the 08-03 release, and has never shipped. `rapids-logger` is installed by `before-all` but stays undeclared here. `librmm-cu13` owns that link-time dependency and carries it in its own metadata; an unversioned duplicate would not make the resolve safer. Reviewed By: mnorris11 Differential Revision: D120162004 fbshipit-source-id: eb6dc316a4fba2a4228eab62d7b86ac8ea94a1b7
169 lines
8.5 KiB
TOML
169 lines
8.5 KiB
TOML
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
#
|
|
# This source code is licensed under the MIT license found in the
|
|
# LICENSE file in the root directory of this source tree.
|
|
|
|
[build-system]
|
|
# cuVS requires rapids-cmake which needs cmake >= 3.30.4.
|
|
requires = ["scikit-build-core>=0.10", "swig>=4.2,<5", "numpy>=2.0", "cmake>=3.30.4", "ninja"]
|
|
build-backend = "scikit_build_core.build"
|
|
|
|
[project]
|
|
name = "faiss-gpu-cuvs"
|
|
dynamic = ["version"]
|
|
description = "A library for efficient similarity search and clustering of dense vectors (GPU + cuVS/CAGRA support)."
|
|
readme = "README.md"
|
|
license = "MIT"
|
|
license-files = ["LICENSE", "THIRD_PARTY_NOTICES"]
|
|
requires-python = ">=3.11"
|
|
authors = [
|
|
{name = "Meta AI Research"},
|
|
]
|
|
keywords = ["search", "nearest-neighbors", "clustering", "vectors", "similarity", "gpu", "cuda", "cuvs", "cagra"]
|
|
classifiers = [
|
|
"Development Status :: 5 - Production/Stable",
|
|
"Intended Audience :: Developers",
|
|
"Intended Audience :: Science/Research",
|
|
"Operating System :: POSIX :: Linux",
|
|
"Programming Language :: C++",
|
|
"Programming Language :: Python :: 3",
|
|
"Programming Language :: Python :: 3.11",
|
|
"Programming Language :: Python :: 3.12",
|
|
"Programming Language :: Python :: 3.13",
|
|
"Programming Language :: Python :: 3.14",
|
|
"Programming Language :: Python :: 3 :: Only",
|
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
"Environment :: GPU :: NVIDIA CUDA :: 13",
|
|
]
|
|
dependencies = [
|
|
"numpy>=1.25",
|
|
"packaging",
|
|
"nvidia-cuda-runtime>=13.2,<14",
|
|
"nvidia-cublas>=13.2,<14",
|
|
"nvidia-curand>=10.3.7,<11",
|
|
"nvidia-nvjitlink>=13.2,<14",
|
|
# Exact-series pin, not a range: RAPIDS >=26.08 wraps RMM in a per-release
|
|
# inline namespace (rmm::_RMM_26_8::), so each minor series renames the
|
|
# symbols libfaiss.so is linked against. libraft is listed because
|
|
# _preload_gpu_libs dlopens it directly.
|
|
"libcuvs-cu13==26.06.*",
|
|
"libraft-cu13==26.06.*",
|
|
"librmm-cu13==26.06.*",
|
|
]
|
|
|
|
[project.urls]
|
|
Homepage = "https://github.com/facebookresearch/faiss"
|
|
Documentation = "https://github.com/facebookresearch/faiss/wiki"
|
|
Repository = "https://github.com/facebookresearch/faiss"
|
|
Issues = "https://github.com/facebookresearch/faiss/issues"
|
|
|
|
[tool.scikit-build]
|
|
cmake.build-type = "Release"
|
|
|
|
# Pull version from CMakeLists.txt's project(VERSION ...) — single source of truth.
|
|
metadata.version.provider = "scikit_build_core.metadata.regex"
|
|
metadata.version.input = "CMakeLists.txt"
|
|
metadata.version.regex = '^\s+VERSION\s+(?P<value>[0-9]+\.[0-9]+\.[0-9]+)'
|
|
|
|
# Exclude C++ headers, cmake configs, static libs, and binaries from the wheel.
|
|
# Only the Python package (faiss/) and bundled shared libs remain.
|
|
wheel.exclude = ["include/**", "share/**", "lib/**", "lib64/**", "bin/**"]
|
|
|
|
[tool.scikit-build.cmake.define]
|
|
FAISS_OPT_LEVEL = "dd"
|
|
FAISS_ENABLE_GPU = "ON"
|
|
FAISS_ENABLE_CUVS = "ON"
|
|
FAISS_ENABLE_PYTHON = "ON"
|
|
FAISS_ENABLE_MKL = "OFF"
|
|
FAISS_ENABLE_C_API = "OFF"
|
|
FAISS_ENABLE_EXTRAS = "OFF"
|
|
FAISS_ENABLE_SVS = "OFF"
|
|
FAISS_USE_LTO = "ON"
|
|
# Turing → Hopper SASS + Hopper PTX trailer for forward compat (e.g. Blackwell JIT).
|
|
# CUDA 13 dropped offline compilation for Maxwell/Pascal/Volta, so 70 (V100) is gone
|
|
# and 75 (Turing) is the floor. Drop 72 (Jetson Xavier) for a datacenter-targeted
|
|
# wheel; include 89 (L4/L40/RTX 40xx).
|
|
CMAKE_CUDA_ARCHITECTURES = "75-real;80-real;86-real;89-real;90"
|
|
CMAKE_CUDA_FLAGS_RELEASE = "-O3 -Xfatbin=-compress-all --threads 4 -Xcompiler=-fdata-sections,-ffunction-sections"
|
|
CMAKE_C_FLAGS = "-fdata-sections -ffunction-sections"
|
|
CMAKE_CXX_FLAGS = "-fdata-sections -ffunction-sections"
|
|
CMAKE_SHARED_LINKER_FLAGS = "-Wl,--gc-sections -Wl,--strip-all"
|
|
CMAKE_MODULE_LINKER_FLAGS = "-Wl,--gc-sections -Wl,--strip-all"
|
|
BUILD_TESTING = "OFF"
|
|
BUILD_SHARED_LIBS = "ON"
|
|
# cuVS + transitive deps (raft, rmm, rapids_logger, header-only cutlass/cuco/nvtx3)
|
|
# are found via CMAKE_PREFIX_PATH (environment block below) at the RAPIDS wheel roots,
|
|
# mirroring the conda build — no explicit *_DIR, agnostic to lib/ vs lib64/.
|
|
|
|
# Stable ABI (abi3): one cp311 wheel covers all 3.11+.
|
|
# Floor is 3.11 because the runtime dep libcuvs-cu13>=26.06 (RAPIDS) requires
|
|
# Python >=3.11 — RAPIDS dropped 3.10 in the 26.04 release.
|
|
# GPU is Linux-only; free-threaded Python (cp3*t) cannot use abi3.
|
|
[[tool.scikit-build.overrides]]
|
|
if.platform-system = "linux"
|
|
if.abi-flags = "^$" # Free-threaded Python does not support stable ABI.
|
|
wheel.py-api = "cp311"
|
|
|
|
[tool.cibuildwheel]
|
|
# Pass through the host GPU so the smoke test can actually exercise CUDA + cuVS.
|
|
# Without this, faiss.get_num_gpus() returns 0 inside the container and all
|
|
# GPU tests silently skip — masking real packaging / driver / SASS-arch problems.
|
|
container-engine = { name = "docker", create-args = ["--gpus", "all"] }
|
|
build = "cp311-manylinux_x86_64"
|
|
test-requires = [
|
|
"numpy>=1.25,<3.0",
|
|
"pytest",
|
|
"nvidia-cuda-runtime>=13.2,<14",
|
|
"nvidia-cublas>=13.2,<14",
|
|
"nvidia-curand>=10.3.7,<11",
|
|
"nvidia-nvjitlink>=13.2,<14",
|
|
"libcuvs-cu13==26.06.*",
|
|
"libraft-cu13==26.06.*",
|
|
"librmm-cu13==26.06.*",
|
|
]
|
|
test-command = "python -m pytest {project}/tests/test_wheel_smoke_gpu.py -v"
|
|
|
|
[tool.cibuildwheel.linux]
|
|
# manylinux_2_28 ships gcc-toolset-14; CUDA 13.2 supports GCC 14, so install
|
|
# gcc-toolset-14 explicitly and force the build to use it via CC/CXX/CUDAHOSTCXX below.
|
|
# epel-release is needed for swig. Install the FULL cuda-toolkit-13-2 (not just nvcc +
|
|
# narrow dev libs as faiss-gpu does) because cuVS pulls in RAFT which transitively
|
|
# needs cuSOLVER, cuSPARSE, nvrtc, etc. headers — easier to install all than to track
|
|
# the exact list. Wheel size is unaffected since auditwheel excludes all CUDA libs.
|
|
#
|
|
# cuVS dev files (headers + cmake) come from RAPIDS' manylinux PyPI wheels via
|
|
# `pip install --target /opt/cuvs` — ABI-clean, so no libstdc++/libgcc_s/libgomp strip
|
|
# or RMM symlink shim. cp311 interpreter is explicit (manylinux puts no `pip` on PATH).
|
|
manylinux-x86_64-image = "manylinux_2_28"
|
|
before-all = "dnf install -y gcc-toolset-14 epel-release && dnf install -y openblas-devel openblas-openmp swig && dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo && dnf install -y --setopt=obsoletes=0 cuda-toolkit-13-2 && /opt/python/cp311-cp311/bin/python -m pip install --target /opt/cuvs --no-deps --only-binary ':all:' --extra-index-url https://pypi.nvidia.com 'libcuvs-cu13==26.06.*' 'libraft-cu13==26.06.*' 'librmm-cu13==26.06.*' 'rapids-logger'"
|
|
# auditwheel excludes (not vendored; supplied at runtime by nvidia-* / libcuvs-cu13
|
|
# wheels): host driver libcuda, CUDA runtime/math libs (cusparse/cusolver are explicit —
|
|
# under the cuda-toolkit RPM, not /opt/cuvs), and every RAPIDS .so found under /opt/cuvs.
|
|
repair-wheel-command = "bash -c 'EXCLUDES=\"--exclude libcuda.so.1 --exclude libcudart.so.13 --exclude libcublas.so.13 --exclude libcublasLt.so.13 --exclude libcurand.so.10 --exclude libnvJitLink.so.13 --exclude libcusparse.so.12 --exclude libcusolver.so.12\"; for f in $(find /opt/cuvs -name \"lib*.so*\" -printf \"%f\\n\" | sort -u); do EXCLUDES=\"$EXCLUDES --exclude $f\"; done; auditwheel repair -w {dest_dir} {wheel} $EXCLUDES'"
|
|
# Canary: ensure the host GPU is actually visible to the container before tests
|
|
# run. Without this, smoke tests would silently skip on broken --gpus passthrough.
|
|
before-test = "nvidia-smi || (echo 'GPU not visible to container; check container-engine create-args' && exit 1)"
|
|
|
|
# Run abi3audit on Linux to guarantee Stable ABI compliance.
|
|
# We use 'append' so that the auditwheel repair-wheel-command from
|
|
# [tool.cibuildwheel.linux] (with the CUDA + cuVS --exclude flags) still runs first.
|
|
[[tool.cibuildwheel.overrides]]
|
|
select = "*-manylinux*"
|
|
inherit.repair-wheel-command = "append"
|
|
repair-wheel-command = "pipx run abi3audit --strict --report {wheel}"
|
|
|
|
# Build-tool paths. CUDA from /usr/local/cuda-13.2 (NVIDIA RPM convention);
|
|
# GCC pinned to toolset-14 for CUDA 13.2 support.
|
|
# CUDAHOSTCXX must match CXX or nvcc host TUs get an ABI-mismatched libstdc++.
|
|
# CMAKE_PREFIX_PATH points at the RAPIDS wheel roots so find_package(cuvs) resolves.
|
|
# Set as env (not cmake.define) so CMake merges it with scikit-build-core's own path.
|
|
[tool.cibuildwheel.linux.environment]
|
|
CUDA_HOME = "/usr/local/cuda-13.2"
|
|
CUDACXX = "/usr/local/cuda-13.2/bin/nvcc"
|
|
CC = "/opt/rh/gcc-toolset-14/root/usr/bin/gcc"
|
|
CXX = "/opt/rh/gcc-toolset-14/root/usr/bin/g++"
|
|
CUDAHOSTCXX = "/opt/rh/gcc-toolset-14/root/usr/bin/g++"
|
|
CMAKE_PREFIX_PATH = "/opt/cuvs/libcuvs:/opt/cuvs/libraft:/opt/cuvs/librmm:/opt/cuvs/rapids_logger"
|