Files
faiss/pyproject-gpu.toml
T
Alibek Zhakubayev 5d9aae6ee8 Add faiss-gpu pip wheel packaging (#5131)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5131

Add pip wheel packaging for `faiss-gpu`, enabling `pip install faiss-gpu`
from PyPI. Builds GPU wheels for Linux x86_64, Python 3.10-3.13, with
CUDA 12.6 on manylinux_2_28.

**New files:**
- `pyproject-gpu.toml`: scikit-build-core config for faiss-gpu. Enables
  CUDA GPU support, uses Dynamic Dispatch, OpenBLAS, and excludes CUDA
  runtime libs (provided by nvidia-cuda-runtime-cu12 pip dependency).
- `.github/workflows/build-pip-gpu.yml`: CI workflow for GPU wheels using
  cibuildwheel on GPU runners (4-core-ubuntu-gpu-t4).
- `tests/test_wheel_smoke_gpu.py`: GPU smoke tests validating GPU
  detection, StandardGpuResources, GPU FlatL2/IP search, IVF+PQ on GPU,
  CPU<->GPU transfer roundtrip, and GPU serialization.

**Modified files:**
- `python/__init__.py`: Added `_preload_gpu_libs()` to pre-load CUDA
  shared libraries from pip packages before SWIG import. No-op on
  CPU-only installs.
- `.github/workflows/build.yml`: Added `build-pip-gpu` workflow call.
- `tests/BUCK`: Added `test_wheel_smoke_gpu` target for Buck CI.

Reviewed By: junjieqi

Differential Revision: D97507525

fbshipit-source-id: f8b5fa08405aa53267e791c2c0d263e2d6190741
2026-05-28 10:46:55 -07:00

136 lines
6.1 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]
requires = ["scikit-build-core>=0.10", "swig>=4.2,<5", "numpy>=2.0", "cmake>=3.24", "ninja"]
build-backend = "scikit_build_core.build"
[project]
name = "faiss-gpu"
dynamic = ["version"]
description = "A library for efficient similarity search and clustering of dense vectors (GPU support)."
readme = "README.md"
license = "MIT"
license-files = ["LICENSE", "THIRD_PARTY_NOTICES"]
requires-python = ">=3.10"
authors = [
{name = "Meta AI Research"},
]
keywords = ["search", "nearest-neighbors", "clustering", "vectors", "similarity", "gpu", "cuda"]
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.10",
"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 :: 12",
]
dependencies = [
"numpy>=1.25",
"packaging",
"nvidia-cuda-runtime-cu12>=12.6,<13",
"nvidia-cublas-cu12>=12.6,<13",
"nvidia-curand-cu12>=10.3.7,<11",
]
[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 = "OFF"
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"
CMAKE_CUDA_ARCHITECTURES = "70-real;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"
# Stable ABI (abi3): one cp310 wheel covers all 3.10+.
# 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 = "cp310"
[tool.cibuildwheel]
# Pass through the host GPU so the smoke test can actually exercise CUDA.
# 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 = "cp310-manylinux_x86_64"
test-requires = [
"numpy>=1.25,<3.0",
"pytest",
"nvidia-cuda-runtime-cu12>=12.6,<13",
"nvidia-cublas-cu12>=12.6,<13",
"nvidia-curand-cu12>=10.3.7,<11",
]
test-command = "python -m pytest {project}/tests/test_wheel_smoke_gpu.py -v"
[tool.cibuildwheel.linux]
manylinux-x86_64-image = "manylinux_2_28"
# manylinux_2_28 ships gcc-toolset-14; CUDA 12.6 only supports GCC <=13, so install
# gcc-toolset-13 explicitly and force the build to use it via CC/CXX/CUDAHOSTCXX below.
before-all = "dnf install -y gcc-toolset-13 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-nvcc-12-6 cuda-cudart-devel-12-6 cuda-cccl-12-6 cuda-profiler-api-12-6 libcublas-devel-12-6 libcurand-devel-12-6"
# auditwheel: exclude libcuda.so.1 (host driver, not pip-installable)
# and the libcudart/libcublas* shipped via nvidia-*-cu12 wheels (preloaded at import time).
repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel} --exclude libcudart.so.12 --exclude libcublas.so.12 --exclude libcublasLt.so.12 --exclude libcurand.so.10 --exclude libcuda.so.1"
# 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 --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-12.6 (NVIDIA RPM convention);
# GCC pinned to toolset-13 because CUDA 12.6 does not support GCC 14.
# CUDAHOSTCXX must match CXX or nvcc host TUs get an ABI-mismatched libstdc++.
[tool.cibuildwheel.linux.environment]
CUDA_HOME = "/usr/local/cuda-12.6"
CUDACXX = "/usr/local/cuda-12.6/bin/nvcc"
CC = "/opt/rh/gcc-toolset-13/root/usr/bin/gcc"
CXX = "/opt/rh/gcc-toolset-13/root/usr/bin/g++"
CUDAHOSTCXX = "/opt/rh/gcc-toolset-13/root/usr/bin/g++"