164 Commits
Author SHA1 Message Date
ihb2032 5e74b1bdde feat: implement RVV optimized scalar quantizer codecs and distance computation (#5535)
Summary:
This PR adds RISC-V Vector Extension SIMD support for Faiss scalar quantizer.

The implementation introduces runtime vector-length aware RVV kernels using the m8 vector configuration, instead of assuming a fixed vector width. This matches the variable-length nature of RVV hardware and allows the implementation to scale across different RISC-V vector implementations.

## Changes

- Add RVV implementations for scalar quantizer codecs:
  - 8-bit codec decoding
  - 4-bit codec decoding
  - (6-bit stays scalar: the RVV gather decoder measured 12-22% slower
    than the scalar path, so QT_6bit falls back until a faster decoder
    exists)

- Add RVV quantizer reconstruction support for:
  - Uniform quantizers
  - Non-uniform quantizers
  - FP16 (Zvfhmin is the enforced minimum ISA of the RISCV_RVV level; a
    build without it fails compilation rather than silently falling back)
  - BF16
  - Direct 8-bit quantization
  - Signed 8-bit quantization
  - LloydMax quantizers (1/2/3/4/8-bit)

- Add RVV optimized similarity implementations:
  - L2 distance
  - Inner product

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5535

Reviewed By: mnorris11

Differential Revision: D116996553

Pulled By: juancarpio27

fbshipit-source-id: dc726948fa602a04a757d8f9cab8eea41ac1979a
2026-09-23 12:00:59 -07:00
anthony-zy bf8be4a79b fix(ci): use GCC 14 riscv64 cross-compiler for RVV tuple/zvfhmin intrinsics (#5653)
Summary:
fix(ci): use GCC 14 riscv64 cross-compiler for RVV tuple/zvfhmin intrinsics

The linux-riscv64-DD CI job installs the default cross-compiler from
Ubuntu noble, which resolves to GCC 13.3. GCC 13's <riscv_vector.h>
does not export the RVV tuple types (vuint8m1x3_t) nor the zvfhmin
f16 intrinsics (vfloat16m1_t, __riscv_vle16_v_f16m1,
__riscv_vfwcvt_f_f_v_f32m2) used by the SQ RVV kernels, so building
sq-rvv.cpp failed with "'vuint8m1x3_t' was not declared in this
scope" (and similar) in the Codec6bit software-pipelined loops and
the QuantizerFP16 fast paths.

The intrinsics used are all legal under -march=rv64gcv_zvfhmin (only
vle16/vse16/vfwcvt/vfncvt on f16) and are fully supported starting
with GCC 14, so no source changes are needed.

Explicitly install gcc-14-riscv64-linux-gnu / g++-14-riscv64-linux-gnu
and point the toolchain file at the versioned binaries, avoiding any
reliance on update-alternatives defaults. A version self-check in the
workflow makes the resolved compiler visible in the CI log.

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5653

Reviewed By: alibeklfc

Differential Revision: D120734761

Pulled By: mnorris11

fbshipit-source-id: d82cf2c99dfd6e8720f31bdadb718806f9e71044
2026-09-21 16:23:17 -07:00
郑紫阳10295048 0f23e6a2ef Add RVV SIMD specialization for scalar quantizer distance compute (#5539)
Summary:
This PR adds RISC-V Vector Extension SIMD specialization for the scalar
quantizer distance computation, following the codec/quantizer/similarity
specialization already present for other SIMD levels. The kernels use the
runtime vector-length aware m8 vector configuration and are shared across
all RVV hardware widths, instead of assuming a fixed vector length.

Changes
Add RVV specialized L2 / inner-product distance kernels for the scalar
quantizer codecs:

- QT_4bit / QT_4bit_uniform
- QT_6bit
- QT_8bit / QT_8bit_uniform
- QT_8bit_direct / QT_8bit_direct_signed
- QT_bf16
- QT_fp16

Each kernel reuses the reconstructed (quantizer) L2 / IP formulation that
avoids per-dimension reconstruction, keeping the hot loop in the integer
domain and applying the final scale at the tail.

Performance
Cmd: 1M 768 <SQ> 32 100 16 1 1000 1 <metric>  (search ms/query, lower is better)
Δ_SQ%: SQ scalar baseline -> RVV;
Δ_F%: Faiss flat baseline -> RVV.

| 序号 | QT_TYPE               | Metric | F1(ms) | SQ1(ms) | F2(ms) | SQ2(ms) | Δ_SQ%   | Δ_F%   |
|------|-----------------------|--------|--------|---------|--------|---------|---------|--------|
| 01   | QT_4bit               | L2     | 1.841  | 6.231   | 1.824  | 1.450   | -76.73% | -0.92% |
| 02   | QT_4bit               | IP     | 1.652  | 6.086   | 1.674  | 1.273   | -79.08% | +1.33% |
| 03   | QT_4bit_uniform       | L2     | 1.806  | 2.560   | 1.806  | 1.135   | -55.66% | +0.00% |
| 04   | QT_4bit_uniform       | IP     | 1.612  | 6.007   | 1.597  | 1.244   | -79.29% | -0.93% |
| 05   | QT_6bit               | L2     | 1.801  | 5.701   | 1.805  | 1.500   | -73.69% | +0.22% |
| 06   | QT_6bit               | IP     | 1.608  | 5.706   | 1.619  | 1.249   | -78.11% | +0.68% |
| 07   | QT_8bit               | L2     | 1.821  | 3.736   | 1.907  | 1.394   | -62.69% | +4.72% |
| 08   | QT_8bit               | IP     | 1.704  | 3.378   | 1.730  | 1.277   | -62.20% | +1.53% |
| 09   | QT_8bit_direct        | L2     | 1.977  | 0.280   | 1.947  | 0.054   | -80.71% | -1.52% |
| 10   | QT_8bit_direct        | IP     | 1.709  | 0.458   | 1.740  | 0.099   | -78.38% | +1.81% |
| 11   | QT_8bit_direct_signed | L2     | 1.581  | 3.234   | 1.572  | 0.761   | -76.47% | -0.57% |
| 12   | QT_8bit_direct_signed | IP     | 1.740  | 0.414   | 1.748  | 0.148   | -64.25% | +0.46% |
| 13   | QT_8bit_uniform       | L2     | 1.943  | 3.204   | 1.928  | 0.927   | -71.07% | -0.77% |
| 14   | QT_8bit_uniform       | IP     | 1.727  | 3.121   | 1.744  | 0.947   | -69.66% | +0.98% |
| 15   | QT_bf16               | L2     | 1.862  | 2.889   | 1.894  | 1.466   | -49.26% | +1.72% |
| 16   | QT_bf16               | IP     | 1.619  | 2.846   | 1.793  | 1.204   | -57.70% | +10.75% |
| 17   | QT_fp16               | L2     | 2.011  | 5.691   | 1.950  | 1.570   | -72.41% | -3.03% |
| 18   | QT_fp16               | IP     | 1.797  | 5.584   | 1.790  | 1.189   | -78.71% | -0.39% |

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5539

Reviewed By: mnorris11

Differential Revision: D117914328

Pulled By: juancarpio27

fbshipit-source-id: 879863b9ab4da6d1c8685892ccc3d64190975181
2026-09-17 13:34:43 -07:00
Alibek Zhakubayev 1dbb3d25b0 Update backward compatibility test to v1.15.1 (#5646)
Summary:
- Update backward compatibility test to use faiss-cpu=1.15.1

Note: the test was previously pinned to faiss-cpu=1.14.3, so this skips over 1.15.0.

**Do not land until faiss-cpu=1.15.1 is available on the pytorch conda channel** — the conda package is published by the tag-triggered release build. Landing earlier will break this workflow on main.

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5646

Test Plan:
- [ ] CI passes
- [ ] Backward compatibility test uses correct version

Reviewed By: mnorris11

Differential Revision: D120265026

Pulled By: alibeklfc

fbshipit-source-id: 9459958af352716d5aef25e45043444105f22ff1
2026-09-16 13:58:02 -07:00
Michael Norris 00928e3f76 Fix ROCm CI: build in a dedicated conda env instead of the runner's broken base (#5545)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5545

The `linux-x86_64-GPU-w-ROCm-cmake` job fails installing AMD's ROCm torch wheels: they exist for one CPython ABI only, and the MI325 runner's interpreter is 3.14, not the 3.12 the action asks for.

Nothing in `build_cmake` actually constrained the interpreter. `setup-miniconda` requests `python-version: '3.12'` and `Configure build environment` asks for `python=3.12` again, but the runner's conda base has `conda-meta` listing both `python 3.12.9` and `cpython 3.14.6`, so conda reports "already installed" while `bin/python` is 3.14. Forcing it does downgrade the interpreter, but strands conda's own compiled extensions (`pydantic_core`), and conda builds its argument parser through its plugins -- so every subsequent conda call in the job dies. Working around that with `CONDA_NO_PLUGINS` in turn drops the libmamba solver, which conda then rejects because `solver: libmamba` stays configured. Meanwhile the base env is inconsistent across three Python ABIs (conda lists ~200 conflicting packages), so there is no in-place repair to converge on.

So stop repairing base. For ROCm only, `conda create` a fresh `$CONDA/envs/faiss` prefix on 3.12 and point `$CONDA` at it, leaving base untouched so conda keeps running on its own interpreter. `$CONDA` is the single lever the later steps already read (`-DPYTHON_EXECUTABLE`, `setup.py install`, the import smoke tests), so redirecting it is enough.

Making that lever actually hold:
- Pass `-p "$CONDA"` on every `conda install`, and `conda activate "$CONDA"`. A bare `conda install` targets the active env, which is base regardless of `$CONDA`. No-op for the non-ROCm jobs, where `$CONDA` is base.
- Write base's `bin` to `$GITHUB_PATH` *before* the env's. The runner prepends entries as it reads them, so the last line written ends up first on PATH: this leaves the env's interpreter ahead of base's while keeping base reachable for `conda` itself.
- Drive the ROCm torch step through `"$CONDA/bin/python" -m pip` rather than bare `python`/`pip3`, so it does not depend on PATH ordering at all.
- `rm -rf` the prefix before `conda create`: it survives between runs on this self-hosted runner and `conda create` refuses an existing one. A fresh prefix each run is the point.
- Derive the `libpthread_nonshared.a` symlink from `$CONDA` instead of a hardcoded `$HOME/miniconda3`, since `sysroot_linux-64` now installs into the build's prefix, and assert the target exists -- `ln -s` does not check, so a wrong path would surface much later as a link failure.
- `conda list -p "$CONDA"` for the diagnostics, so the logs describe the env under test rather than base.

Torch wheel installation:
- Resolve through `--find-links` as a flat index instead of hardcoding a `cp312-cp312-linux_x86_64` filename; the hardcoded tag is what made an interpreter mismatch surface as "not a supported wheel on this platform".
- Keep a retag fallback for pip builds that reject the unqualified `linux_x86_64` tag, but gate it on the resolver's own error text so a transient failure (network, disk) fails loudly instead of being retagged over.
- `--ignore-installed`, because this runner is self-hosted and a wrong-ABI torch from an earlier run otherwise satisfies the requirement and skips tag matching.
- Use AMD's wheels built against the system ROCm rather than the PyTorch Foundation `rocm7.2` wheels, which bundle an older ROCr lacking `hsa_amd_memory_get_preferred_copy_engine` and collide with the system `libamdhip64`. `ROCM_VERSION` is exported to `$GITHUB_ENV` so the apt release and the wheel release cannot drift apart.
- Assert on interpreter version, torch's install location, and `torch.version.hip` rather than printing them. Each of these failures previously surfaced several steps later as something unrelated-looking.

Note for infra: the base env on this runner is corrupt independently of this change (mixed 3.12/3.13/3.14 packages, and truncated `lib/python3.1/site-packages` paths from a `sys.version[:3]` bug upstream). Wiping it would let several of the workarounds above be dropped.

Reviewed By: alibeklfc

Differential Revision: D117896658

fbshipit-source-id: 26f98c53e5daf747dd81e0fd35232b4160f62377
2026-09-10 08:01:09 -07:00
Chao Zhang 3a716ead1a Add Windows ARM64 support to CI (#5544)
Summary:
Hi team, I'm from Microsoft and recently I'm working on improving Python ecosystem support for Windows on Arm.
So I updates the CI workflows to add support for Windows ARM64 build and release. Could you please help to review? Thanks.

**Windows ARM64 support and OpenBLAS installation improvements:**

* Added a new PowerShell script `install-openblas.ps1` that automatically detects the runner architecture (x64 or ARM64), downloads the appropriate OpenBLAS binary, verifies its hash, and installs it to `C:\openblas`. This ensures consistent and secure OpenBLAS setup on all Windows runners.
* Updated the build matrix in `.github/workflows/build-pip.yml` to include `windows-11-arm`, enabling CI builds and tests on Windows ARM64 runners.
* Refactored the Windows `before-all` build step in `pyproject.toml` to use the new PowerShell script, replacing the previous hardcoded x64-only download command. This allows seamless support for both x64 and ARM64 architectures.

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5544

Reviewed By: mnorris11

Differential Revision: D117818430

Pulled By: trang-nm-nguyen

fbshipit-source-id: dac342878d063828437952e1b19f76e6699e1b6b
2026-08-28 10:06:58 -07:00
Evan Haque 3110fd2424 Add MetalIndexIVFPQ with product quantization and residual encoding support (#5288)
Summary:
Adds IVF-PQ (inverted file with product quantization) index support to the Metal GPU backend

- Add `MetalIndexIVFPQ` with full train/add/search/reset/copyFrom/copyTo support
- Add `MetalIVFPQImpl` GPU-resident IVF list storage for PQ codes (segment allocator, same pattern as IVFFlat)
- Support 8-bit product quantization with precomputed per-query lookup tables
- Support both L2 and inner product metrics
- Residual encoding when `by_residual=true` (default for L2)
- CPU-side PQ lookup table computation with precomputed tables optimization for L2
- GPU scan path via `runMetalIVFPQFullSearch` with CPU LUT fallback via `runMetalIVFPQScan`
- Update `MetalCloner` to support IVFPQ in `index_cpu_to_metal_gpu` / `index_metal_gpu_to_cpu`

## Changes
- **New:** `MetalIndexIVFPQ.h/.mm` - IVFPQ index class (train, add, search, reset, copyFrom/copyTo, cloner support)
- **New:** `impl/MetalIVFPQ.h/.mm` - GPU-resident IVF list storage with segment allocator for PQ codes
- **New:** `test/TestMetalIndexIVFPQ.mm` - 4 C++ tests (L2, IP, reset, CPU↔GPU round-trip)
- **Modified:** `test/CMakeLists.txt` - added TestMetalIndexIVFPQ build target

## Differences from CUDA IVFPQ

**Training:** Delegates to CPU (`IndexIVFPQ::train`). CUDA can train on GPU. Same rationale as IVFFlat - training is a one-time cost.

**Add path:** Coarse quantization and PQ encoding run on CPU, then codes are copied to GPU storage. CUDA does both on GPU. On Apple Silicon with unified memory, the copy cost is minimal.

**Residual encoding:** When `by_residual=true`, residuals (x - coarse_centroid) are computed on CPU before PQ encoding. CUDA computes residuals on GPU. Functionally equivalent.

**Lookup tables:** PQ distance lookup tables are computed on CPU and uploaded to GPU for the scan phase. CUDA computes LUTs on GPU. CPU LUT computation is fast relative to the scan and avoids a separate GPU kernel launch.

**IVF list storage:** Same segment allocator pattern as IVFFlat - single contiguous buffer rather than CUDA's per-list `DeviceVector` allocations.

## Note
FP16 coarse quantizer and GPU merge kernel are planned optimizations for a future PR. Both apply across all IVF index types (IVFFlat, IVFPQ, IVFSQ).

## Build and test
```bash
cmake -B build \
  -DFAISS_ENABLE_GPU=OFF \
  -DFAISS_ENABLE_METAL=ON \
  -DBUILD_TESTING=ON \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_PREFIX_PATH="$(brew --prefix libomp)" \
  .
cmake --build build --target faiss faiss_metal TestMetalIndexIVFPQ -j$(sysctl -n hw.logicalcpu)
cd build && ctest -R TestMetalIndexIVFPQ --output-on-failure
```

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5288

Reviewed By: alibeklfc

Differential Revision: D113037852

Pulled By: mnorris11

fbshipit-source-id: 5fdb729b10ad9884a673fc3483543b4c5fcdb621
2026-07-23 09:01:19 -07:00
Michael Norris 3a7cce4ea9 Faiss OSS CI: skip GPU jobs on PRs that touch no GPU-relevant code (#5402)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5402

TLDR:
- GPU only changes: run just linux-x86_64-cmake --> GPU jobs
- CPU only changes: run just CPU jobs
- both: run everything

Most PRs touch only CPU or only GPU code, but CI ran the full matrix every time. This adds a lightweight `changes` job (`dorny/paths-filter`) that detects whether a PR touches GPU-relevant or non-GPU paths, then gates each job with `needs: changes` and an `if:` guard: GPU jobs run only on GPU changes, and the CPU variant matrix (AVX/SVE/DD/SVS/conda/etc.) runs only on non-GPU changes. Non-PR events (push to `main`, tags) always run everything, so post-merge and release coverage is unchanged.

Globs fail safe: shared build files (`cmake/**`, `CMakeLists.txt`, pyproject, the workflows) count as both GPU and CPU changes, so any build-system change re-runs the full matrix. The same gating is applied across `build-pull-request.yml`, `build-pip.yml`, and `build-pip-gpu.yml`.

Reviewed By: mdouze

Differential Revision: D111494465

fbshipit-source-id: 1e47780e2b6209417beecf6bf1a8021f1ec11030
2026-07-13 08:42:59 -07:00
Michael Norris 63378f0ace Fix cuVS GPU CI timeout: pin CUDA toolkit to 13.2 (#5401)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5401

`faiss/gpu/test/test_gpu_index_serialize.py` was timing out (10 min hard cap) on the GitHub `Linux x86_64 GPU w/ cuVS (cmake)` job, hanging inside `index_cpu_to_gpu` on the first cuVS GPU operation.

Root cause: D106837134 bumped the conda cuVS toolkit from CUDA 12.9 to 13.3. The 13.3 `cudart` deadlocks cuVS GPU kernels on the T4 runner. The change's stated intent was only to pull `libnvJitLink` up to 13.3 — the conda `libcuvs=26.06` build links it and needs the `__nvJitLinkCreate_13_3` symbol — but `cuda-nvcc`, `cuda-cudart-dev`, `cuda-cupti`, and `cuda-nvtx` were bumped to 13.3 alongside it. CUDA 13.2 is already the version used by both the non-cuVS GPU job and the pip-wheel cuVS build (whose GPU smoke test passes on the same T4 runner class), and it matches the runner driver. Only `libnvJitLink` actually needs to be 13.3.

Fix: pin the CUDA toolkit (`cuda-nvcc`/`cuda-cudart-dev`/`cuda-cupti`/`cuda-nvtx` and `cuda-version`) back to 13.2 for the cuVS cmake build, keeping the explicit `libnvjitlink>=13.3,<14` pin so `libcuvs` still loads.

passed in https://github.com/facebookresearch/faiss/actions/runs/29109874975/job/86419354334?pr=5401

Reviewed By: alibeklfc

Differential Revision: D111466548

fbshipit-source-id: 6eef20488605981f2326aaa2fb628b3315b9ed75
2026-07-10 17:33:47 -07:00
Michael Norris 4d778bc595 Add multi-GPU CAGRA → HNSW build with trainAllNeighbors and multi-GPU optimize (#5282)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5282

Adds `GpuIndexCagra::trainAllNeighbors()`: builds a single unified HNSW index for a large dataset sharded across multiple GPUs using cuVS `all_neighbors` (overlapping-cluster kNN graph, no stitching) plus a multi-GPU graph-optimize pass, then `copyTo(IndexHNSWCagra)`.

End-to-end pipeline (Approach D):
1. Data load: stream real `prefilter_embedding` vectors from Hive (`feed_fblearner/test_unicorn_model_streaming_full_dump_fbr_umia_i2i_clic_ts`) in-process via Koski into a preallocated host `(N, 129)` float32 array. No Manifold file, no tiling, no duplicate vectors. A Manifold `.npy` + `--n` tiling path is retained as a fallback.
2. kNN graph: `cuvs::neighbors::all_neighbors::build` with IVF-PQ per-cluster construction across 8 GPUs; overlapping clusters provide cross-cluster connectivity so no post-hoc stitching is needed.
3. Optimize/prune: multi-GPU 2-hop detour counting (custom `kern_detour_count` kernel) + CPU pruning + reverse-graph construction; prunes `intermediate_graph_degree` down to `graph_degree`.
4. Convert: `copyTo(IndexHNSWCagra)` with `base_level_only=True` — use the CAGRA graph directly as HNSW level-0, skipping upper-level construction.
5. Serialize the HNSW index to disk.

API: `trainAllNeighbors(n, x, devices, n_clusters, overlap_factor, multi_gpu_optimize, build_algo, refinement_rate, ivfpq_search_batch)` on `GpuIndexCagra`, followed by `copyTo(IndexHNSWCagra)`.

Approaches evaluated (D recommended):
- A: independent HNSW per GPU shard via `IndexShards` -- fast build, but serving-time query cost multiplies by the number of graphs.
- B: SNMG CAGRA + GPU brute-force stitching -- poor recall (0.82).
- C: SNMG CAGRA + CPU HNSW stitching -- good recall, slow at scale.
- D: `all_neighbors` + multi-GPU optimize -- best recall/speed/query-cost trade-off.

Key optimizations and knobs:
- Multi-GPU detour counting: ~120x speedup on the optimize phase.
- IVF-PQ per-cluster build: ~2.3x faster than NN-descent for `all_neighbors`.
- `base_level_only` copyTo: ~59x faster CAGRA->HNSW conversion.
- New `refinement_rate` knob (IVF-PQ refinement multiplier; previously hardcoded).
- New `ivfpq_search_batch` knob: caps the IVF-PQ search `max_internal_batch_size` (cuVS default 131072) to bound the GPU search workspace; recall-neutral.

100M memory tuning: at 100M real vectors the cuVS IVF-PQ build OOMs on H100 (96 GB) with the default search batch (a 12.76 GB workspace) and at `intermediate_graph_degree=48`. Capping `ivfpq_search_batch` (e.g. 8192) and/or lowering `igd` to 32/24 makes it fit while keeping recall@10 >= 0.95. (The earlier "0.902 @ 100M" number was on 50M tiled 2x, which has duplicate vectors and is not representative.)

Build/runtime note: the MAST H100 fleet runs the CUDA 13.0 driver, so the fbpkg must be built for it: `buck2 build mode/opt -c fbcode.nvcc_arch=h100 --modifier ovr_config//third-party/cuda/constraints:13.0 //faiss/gpu/test:bench_approaches`. Otherwise cuVS kernels fail at runtime with `cudaErrorInvalidKernelImage`.

Files: `faiss/gpu/GpuIndexCagra.{cu,h}` (API + knobs), `faiss/gpu/test/bench_approaches.py` (benchmark + Koski Hive loader + isolated index-build timing), `faiss/gpu/test/BUCK` (Koski dep), `users/mnorris/launch_mast.sh` (single MAST launcher), `users/mnorris/STITCH_OPTIMIZATION.md` (design notes, results, debugging log).

Reviewed By: junjieqi

Differential Revision: D106837134

fbshipit-source-id: f6072e9a41c4f6f2040496db8286c425a79195a8
2026-07-08 14:34:57 -07:00
Rafik Saliev 42dc2862c2 Implement memory-mapped I/O for Flat and static Vamana SVS indices (#5271)
Summary:
This pull request adds support for memory-mapped I/O (mmap) loading of static SVS (Scalable Vector Search) indices in Faiss, enabling faster and more memory-efficient index loading. The main changes include implementing mmap-based deserialization for static Vamana and Flat indices, updating the index loading logic to use mmap when requested, and adding comprehensive tests for the new functionality.

**Memory-mapped index loading support:**

* Added `map_to` methods to `IndexSVSVamana` and `IndexSVSFlat` for loading static indices directly from memory-mapped files, including logic to manage memory mapping ownership and adjust file positions after mapping.

**Index and file structure updates:**

* Extended `IndexSVSVamana` and `IndexSVSFlat` classes to hold a reference to the mmap owner, ensuring the mapped memory remains valid for the lifetime of the index. Also added forward declarations and includes for mmap-related types.
* Modified `reset` methods to release memory mappings when the index is reset, preventing resource leaks.

**Testing and interface improvements:**

* Enhanced test utilities and added new tests to verify correct mmap loading for various static Vamana index types, including FP32, FP16, SQI8, LVQ4x4, and LeanVec4x4 in `tests/test_svs.cpp`

These changes collectively provide robust and efficient support for memory-mapped loading of static SVS indices, improving both performance and usability for large-scale vector search applications.

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5271

Reviewed By: alibeklfc

Differential Revision: D108313487

Pulled By: mnorris11

fbshipit-source-id: 4ae6dc3e69363b0c792cd56ad26b01bf6a853d28
2026-07-01 21:53:26 -07:00
Alibek Zhakubayev a6f97750ae Add faiss-gpu-cuvs pip wheel packaging (#5250)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5250

Add pip wheel packaging for `faiss-gpu-cuvs`, enabling
`pip install faiss-gpu-cuvs` from PyPI. Includes cuVS/CAGRA graph-based
GPU search on top of standard FAISS GPU support.

**New files:**
- `pyproject-gpu-cuvs.toml`: scikit-build-core config for faiss-gpu-cuvs.
  Enables CUDA + cuVS support. cuVS dev files (headers, cmake config)
  are installed via micromamba from the rapidsai conda channel at build
  time; runtime .so files come from libcuvs-cu12 pip dependency. Removes
  conda's libstdc++/libgcc_s/libgomp post-install to pass manylinux_2_28
  ABI check.

**Modified files:**
- `.github/workflows/build-pip-gpu.yml`: Added `build-faiss-gpu-cuvs`
  and `publish-gpu-cuvs` jobs. Added `pyproject-gpu-cuvs.toml` to the
  path trigger filter.

Reviewed By: mnorris11

Differential Revision: D97507494

fbshipit-source-id: d30ef814984ee792c47c0009c7203ea9895fe80c
2026-06-25 15:01:40 -07:00
Tia Lim 0f48ae6210 Faiss OSS autofix: force cuVS nightly to break (E2E validation) (#5328)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5328

Deliberately break the cuVS conda nightly build to validate the Faiss OSS autofix sidecar end-to-end: watcher detects nightly failure -> opens session in `manifold://faiss_oss_autofix/tree/sessions/` -> MyClaw generates patch -> pusher applies the patch to a `myclaw/<run>-<attempt>` GitHub branch and dispatches `nightly.yml` on it.

Two changes:

1. **`build_conda/action.yml`**: Revert the `conda config --set solver libmamba` line introduced by D107388234. Without libmamba, the classic conda solver runs against the cuVS resolve (rapidsai + nvidia + conda-forge), which is expected to time out within the GitHub Actions 6h budget.

2. **`build-pull-request.yml`**: Temporarily add the `linux-x86_64-GPU-CUVS-CUDA13-2-0-nightly` job (mirror of the nightly job, with `ANACONDA_API_TOKEN` and `label: nightly` stripped) so PR CI exercises the broken cuVS build and we can confirm the breakage before landing. **This addition must be removed before landing** — leaving it in would run the broken cuVS build on every PR.

Notes:
- D109045137 (token-fallback safety fix) is landed, so the autofix pusher's GitHub identity is safe under Chronos (only honors `FAISS_GITHUB_TOKEN`, not the generic `GITHUB_TOKEN`).
- The watcher and pusher chronos jobs are enabled (https://www.internalfb.com/chronos/job/gp/9007208073320589, https://www.internalfb.com/chronos/job/gp/135107997926649017), so the autofix should pick up the broken nightly without further setup.

Reviewed By: mnorris11

Differential Revision: D109092204

fbshipit-source-id: 16f74ea0fb4322932de5a6f347f8c63fccbba193
2026-06-23 16:10:58 -07:00
Alibek Zhakubayev 0ca9df4792 Update backward compatibility test to v1.14.3 (#5308)
Summary:
- Update backward compatibility test to use faiss-cpu=1.14.3

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5308

Test Plan:
- [ ] CI passes
- [ ] Backward compatibility test uses correct version

Reviewed By: limqiying

Differential Revision: D108450572

Pulled By: alibeklfc

fbshipit-source-id: 466d3e4d45a8a4cbc9e312fe5f7c50872a7bb045
2026-06-12 17:17:30 -07:00
Tia Lim 684a32d040 Add manual Faiss nightly workflow dispatch (#5300)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5300

Add `workflow_dispatch` to the Faiss public nightly workflow so the OSS autofix sidecar can validate generated fixes on short-lived validation branches before asking a human to review them. The scheduled trigger only runs on GitHub's default branch at the cron time, so it does not validate an unlanded Phabricator diff or a candidate branch.

`workflow_dispatch` does not run the nightly by itself; it adds a manual/API entry point. After the sidecar pushes a candidate branch such as `myclaw/<run_id>-<attempt>`, it calls the GitHub Actions workflow dispatch endpoint for `nightly.yml` with `ref` set to that branch. GitHub then checks out and runs the workflow at the commit currently pointed to by that ref.

The dispatch request does not need a separate commit number when using a branch ref: the branch name resolves to its HEAD commit at dispatch time. If we ever want to pin an exact revision instead of a movable branch, the sidecar can dispatch with a more specific Git ref accepted by GitHub, but the current deterministic branch-per-attempt design makes the branch HEAD the validation candidate.

Reviewed By: mnorris11

Differential Revision: D108214872

fbshipit-source-id: 47bfaf0a656e48c277721eec52b82b67f7a6ebb1
2026-06-10 19:54:11 -07:00
Michael Norris 1cdc3709c6 Run CI on push to main to refresh ccache cache (#5291)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5291

TLDR: this runs the build on every merge of a PR. Yes it doubles the cost but it may increase cache hit rate, which is super low right now. Right now the cache is from May 5 when I first integrated it because there's no refresh on main branch. This is supposed to fix that.
--

AI description:

The `Build` workflow only triggered on `pull_request` and tag pushes,
never on pushes to `main`. GitHub Actions caches are scoped per branch:
PR runs read main's cache and write to their own throwaway PR scope.
Main's cache is therefore only refreshed when the workflow runs on
`main` itself, which never happened.

Result: PRs were restoring a month-old ccache (`2026-05-05`) on every
run, with hit rates around ~28%. Cache size sat at ~13 MB out of 2 GB.

This adds `push: branches: [main]` so the cmake build (and only the
cmake build) runs on each merge, populating main's ccache. The pip
wheel jobs are gated to non-push or tag-push events to preserve their
current behavior — they only run on PRs, manual dispatch, or tag
releases, never on plain main pushes. PyPI publish jobs are already
guarded by `startsWith(github.ref, 'refs/tags/v')`, so there is no
risk of accidental publishes.

___

Differential Revision: D107964344

fbshipit-source-id: 14d636c17b38ae476bb9e7edbe5654d21dd74f0e
2026-06-09 09:37:18 -07:00
Michael Norris 15bd823837 Fix cuVS nightly (#5273)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5273

Compilation time is huge because we target a bunch of arches. Reduce number of arches and try libmamba solver.

Had to skip a few new hanging tests.

Reviewed By: junjieqi

Differential Revision: D107388234

fbshipit-source-id: 052f80d215a9da95f5867eb70fc361867f2657a8
2026-06-08 08:28:23 -07:00
Evan Haque 10b6b2a1e5 Add MetalIndexIVFFlat with IVF scan/merge kernels and expanded top-k support (#5202)
Summary:
## Summary
Adds IVFFlat index support to the Metal GPU backend

- Add `MetalIndexIVFFlat` with full train/add/search/reset/copyFrom/copyTo support
- Add IVF scan/merge MSL kernels (`ivf_scan_list`, `ivf_scan_list_small`, `ivf_scan_list_interleaved`, `ivf_merge_lists`) to `MetalDistance.metal`
- Add `MetalDistance.h/.mm` orchestration layer for IVF search dispatch (coarse quantization + scan + merge in a single command buffer)
- Add `compute_norms` and `l2_with_norms` kernels for efficient L2 coarse quantization
- Expand top-k support from k <= 256 to k <= 2048 (`topk_threadgroup_{512,1024,2048}`)
- Raise dimension limit from d <= 512 to d <= 2048 (supports 768, 1024, 1536 embeddings)
- Update `MetalCloner` to support IVFFlat in `index_cpu_to_metal_gpu` / `index_metal_gpu_to_cpu`
- Rename `nil` parameter to `n_il` in `InvertedLists.h/.cpp` to fix Objective-C++ keyword conflict

## Changes
- **New:** `MetalIndexIVFFlat.h/.mm` - IVFFlat index class (train, add, search, reset, cloner support)
- **New:** `impl/MetalIVFFlat.h/.mm` - GPU-resident IVF list storage with segment allocator
- **New:** `MetalDistance.h/.mm` - IVF search dispatch (scan + merge orchestration)
- **New:** `test/TestMetalIndexIVFFlat.mm` - 4 tests (L2, IP, reset, cpu to gpu round trip)
- **Modified:** `MetalDistance.metal` - IVF kernels, compute_norms, l2_with_norms, topk 512/1024/2048
- **Modified:** `MetalKernels.h/.mm` - IVF encode methods, expanded topk variants, kMaxK=2048
- **Modified:** `MetalIndex.h` - added IVF config fields (indicesOptions, interleavedLayout, useFloat16CoarseQuantizer)
- **Modified:** `MetalCloner.mm` - IVFFlat support in cpu <-> gpu cloning
- **Modified:** `CMakeLists.txt` - added new source files
- **Modified:** `.github/actions/build_cmake/action.yml` - added TestMetalIndexIVFFlat to CI
- **Modified:** `faiss/invlists/InvertedLists.h/.cpp` - renamed `nil` parameter to `n_il` (Objective-C++ keyword conflict)

## Differences from CUDA IVFFlat

**Training:** Delegates to CPU (`IndexIVFFlat::train`). CUDA can train on GPU via k-means or cuVS. GPU training is possible with Metal but low priority since training is a one-time cost.

**Add path:** Coarse quantization runs on CPU, then vectors are copied to GPU storage. CUDA does both on GPU. Moving coarse assignment to Metal is doable using the existing flat search kernels; planned for a future optimization.

**Reconstruct:** Reads from CPU host mirror rather than GPU buffers. On Apple Silicon with unified memory, CPU and GPU see the same physical memory, so this is functionally equivalent.

**IVF list storage:** Uses a single contiguous buffer with a segment allocator, rather than CUDA's per-list `DeviceVector` allocations. This avoids managing thousands of small `MTLBuffer` objects and reduces fragmentation; a better fit for Apple Silicon's unified memory pool.

## Notes on other changes
**`nil` → `n_il` rename in `InvertedLists.h/.cpp`:** ObjC++ treats `nil` as a keyword (equivalent to `nullptr` for Objective-C objects). Any `.mm` file that transitively includes `InvertedLists.h` fails to compile because the parameter name `int nil` conflicts with the keyword. This is a declaration only rename, no behavior, ABI, or API change. Does not affect CUDA, CPU, or any other build.

**`centroidsAreFP16` parameter in `runMetalIVFFlatFullSearch`:** The Metal-backend branch passes a `useFloat16CoarseQuantizer` config flag through the search dispatch chain. CUDA handles this differently, FP16 centroid storage is a property of the coarse quantizer object (`GpuIndexFlatConfig::useFloat16`), not a function parameter. The parameter is currently a no-op but is included to maintain the correct function signature and avoid a parameter alignment bug where a trailing `bool` would be misinterpreted as `waitForCompletion`.

## Build and test
```bash
cmake -B build \
  -DFAISS_ENABLE_METAL=ON \
  -DFAISS_ENABLE_GPU=OFF \
  -DFAISS_ENABLE_PYTHON=OFF \
  -DBUILD_TESTING=ON \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_PREFIX_PATH="$(brew --prefix libomp)" \
  .
cmake --build build --target faiss_metal TestMetalIndexFlat TestMetalIndexIVFFlat -j$(sysctl -n hw.logicalcpu)
cd build && ctest -R TestMetalIndex --output-on-failure
```

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5202

Reviewed By: mdouze

Differential Revision: D107120463

Pulled By: mnorris11

fbshipit-source-id: 75a33d233d4844bec046818418ba75c85abb0402
2026-06-04 14:14:58 -07:00
Tarang Jain 7504fc8dde Upgrade CUVS Version to 26.06 (#5240)
Summary:
Apply patches to make this compatible + update install docs to document new 13.2 pkg

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5240

Reviewed By: mnorris11

Differential Revision: D107156965

Pulled By: alibeklfc

fbshipit-source-id: 4eb201a3b15edaecb61957e11d867db8478dff71
2026-06-02 09:00:36 -07:00
ItsPitt ef96e3d25e Updating CI to ROCm 7 (#5196)
Summary:
Updating CI from ROCm 6.2 to 7.2. Also updating PyTorch to version 7.2 for ROCm.

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5196

Reviewed By: limqiying

Differential Revision: D104747603

Pulled By: mnorris11

fbshipit-source-id: 8476de7ebab846d3187893450da79a03c7c25785
2026-05-29 11:08:21 -07:00
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
Alibek Zhakubayev 8f03848667 Disable attestations for prod PyPI publish (#5230)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5230

Disables Sigstore attestations (`attestations: false`) in the prod PyPI publish step. The `pypa/gh-action-pypi-publish` action generates attestation certificates that carry the top-level workflow (`build.yml`) as the Build Config URI, but PyPI verifies attestations against the trusted publisher which is configured as `build-pip.yml` (the reusable workflow where the publish job is defined). This mismatch causes a `400 Invalid attestations` rejection when `build.yml` calls `build-pip.yml` via `workflow_call`.

TestPyPI is unaffected because `workflow_dispatch` triggers `build-pip.yml` directly, so the certificate and publisher both say `build-pip.yml`.

This is a known limitation of `pypa/gh-action-pypi-publish` with reusable workflows. Attestations can be re-enabled once PyPI supports matching against `workflow_ref` in addition to `job_workflow_ref` for attestation verification, or once the publish job is moved out of the reusable workflow.

Reviewed By: mnorris11

Differential Revision: D106110673

fbshipit-source-id: 1fc3b4cf2a0b92839dd0770ee4b78ae01259f990
2026-05-22 11:52:33 -07:00
Alibek Zhakubayev 086bd74fed Add verbose logging to PyPI publish step (#5229)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5229

Adds `verbose: true` to the prod PyPI publish step in `build-pip.yml`. The TestPyPI publish step already has this flag. Without it, upload failures return only `400 Bad Request` with no details, making debugging impossible.

This was discovered during the first attempt to publish `faiss-cpu` to prod PyPI — the upload failed with a `400 Bad Request` and the logs provided no additional context. The TestPyPI publish step has `verbose: true` and `skip-existing: true`, but the prod step had neither.

Reviewed By: junjieqi

Differential Revision: D106046068

fbshipit-source-id: 0c457cef69fd96642fea6537420a985cc9a00f76
2026-05-22 10:05:00 -07:00
Alibek Zhakubayev fd3403ebf2 Update backward compatibility test to v1.14.2 (#5228)
Summary:
- Update backward compatibility test to use faiss-cpu=1.14.2

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5228

Test Plan:
- [ ] CI passes
- [ ] Backward compatibility test uses correct version

Reviewed By: junjieqi

Differential Revision: D105979285

Pulled By: alibeklfc

fbshipit-source-id: b777151894234abe063d712ee147dd4916425d0c
2026-05-21 12:31:37 -07:00
Michael Norris b63f236a52 Upgrade GitHub Actions CI from CUDA 12.6 to CUDA 13.2 (#5207)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5207

Upgrades the GitHub Actions CI workflows to use CUDA 13.2 (from 12.6).

Changes:
- Updated CUDA toolkit version from 12.6 to 13.2 across all CI workflows (nightly, build-release, build-pull-request)
- Updated CUDA_ARCHS to include newer GPU architectures (sm_90/Hopper, sm_100/Blackwell) and drop older ones (sm_70/Volta)
- Upgraded gxx_linux-64 from 12.4 to 14.2 for CUDA builds in build_cmake action
- Uncommented the cuVS CUDA 13.2 nightly job

Reviewed By: junjieqi

Differential Revision: D104863424

fbshipit-source-id: 57dc261bc6560c72e97ee22f1e41fac57129d5f5
2026-05-19 08:37:07 -07:00
Michael Norris 6376bc35e3 Fix CI: (cuVS) conda shards cache lock, (ARM) bump openblas, (SVS) fix LeanVec double-destruction (#5209)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5209

Three fixes for GitHub Actions CI build/test failures:

1. sqlite3 "database is locked" error (cuVS cmake builds)

conda-libmamba-solver 26.4.0 uses a SQLite shards cache for package index
data. When consecutive conda install commands run in the same job step,
the SQLite lock from the first install is not fully released before the
second install begins, causing:
sqlite3.OperationalError: database is locked

Fix: Add conda clean --index-cache between the cuVS and PyTorch conda
installs to flush the shards cache and release the lock.

2. OpenBLAS version pin conflict (ARM64 conda builds)

conda-forge removed openblas 0.3.32, making it unresolvable. The conda
recipes pinned 0.3.32 for non-x86_64 (ARM64) and macOS builds, causing:
package libfaiss requires openblas 0.3.32.*, but none of the providers can be installed

Fix: Bump all openblas/libopenblas pins from 0.3.32 to 0.3.33 in the
conda recipes and from 0.3.29 to 0.3.33 in the cmake CI action.

3. Flaky SVS LeanVec test aborts (SVSLL tests)

IndexSVSVamanaLeanVec::~IndexSVSVamanaLeanVec() explicitly called
IndexSVSVamana::~IndexSVSVamana(), but C++ destructor chaining already
calls the base destructor automatically. This caused double-destruction of
base class members (notably std::vector<float> stored_vectors), resulting
in a double-free and non-deterministic SIGABRT. The IVF variant
(IndexSVSIVFLeanVec) correctly omits this call.

Fix: Remove the explicit base destructor call; let C++ handle it.

Reviewed By: pankajsingh88

Differential Revision: D104902441

fbshipit-source-id: c4ab80a4c1fdeb9976c4e089dfb95814284824a7
2026-05-13 10:12:43 -07:00
Michael Norris f323c0fa11 Fix backward compat test (#5195)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5195

try to pin mkl < 2026 just like https://github.com/facebookresearch/faiss/pull/5192

Reviewed By: alibeklfc

Differential Revision: D104291586

fbshipit-source-id: 14acd9e82174185c6615d6b33cd376491c91895c
2026-05-07 14:47:48 -07:00
Matthijs Douze 7a8e4ddaca CI: cross-compile for riscv64 with RVV dynamic dispatch (#5184)
Summary:
Add a build-only CI job that cross-compiles Faiss for RISC-V 64-bit with RVV support in dynamic dispatch mode.

## Changes

### `cmake/toolchains/riscv64-linux-gnu.cmake` (new)
Reusable CMake toolchain file for the Ubuntu `gcc-riscv64-linux-gnu` cross-compiler. Uses `CMAKE_FIND_ROOT_PATH_MODE_* = ONLY` against the `/usr/riscv64-linux-gnu` sysroot. The CI job creates a symlink to bridge Ubuntu's multiarch layout (`/usr/lib/riscv64-linux-gnu/`) into that sysroot so CMake's library discovery works without risking picking up host amd64 libs.

### `CMakeLists.txt`
`perf_tests` is now skipped when `CMAKE_CROSSCOMPILING` is set — it requires `gflags` and Google Benchmark which are not installed in the cross environment. This mirrors the existing `NOT WIN32` guard.

### `.github/workflows/build-pull-request.yml` — new job `linux-riscv64-DD-cmake`
- `ubuntu-latest` runner, runs immediately in parallel with all other jobs
- Installs `gcc/g++-riscv64-linux-gnu` + `libopenblas-dev:riscv64` via apt multiarch (Ubuntu Ports), plus `qemu-user-static` for the ldd verification step
- Configures with `FAISS_OPT_LEVEL=dd`, `BUILD_SHARED_LIBS=ON`, no Python/GPU/C-API, `BLA_VENDOR=OpenBLAS`, ccache
- Builds `--target faiss_test` (which includes `test_factory_tools.cpp`, exercising `index_factory` and thus preventing the linker from pruning Faiss internals)
- Verifies the output with `qemu-riscv64-static -L /usr/riscv64-linux-gnu <ld.so> --list faiss_test`, which is the cross-compilation equivalent of `ldd`

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5184

Reviewed By: mnorris11

Differential Revision: D104040788

Pulled By: mdouze

fbshipit-source-id: 09721c28b0c15e2eb3deedbf4abeb42a4f7ab0b6
2026-05-07 08:50:12 -07:00
Michael Norris 6cef1bb08c Fix cuVS and ROCm CI conda environment failures (#5180)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5180

finally passes: https://github.com/facebookresearch/faiss/actions/runs/25449492630?pr=5180

Two GitHub Actions CI jobs are failing due to conda environment resolution issues.

**cuVS**: The `cuda-toolkit=12.9` metapackage includes visual tools (nsight-compute) that require `krb5 >=1.21.3,<1.22.0a0`, which conflicts with `mamba`/`libcurl` needing `krb5 >=1.22.2,<1.23.0a0`. It also has Windows-only variants requiring `__win`. Removing `cuda-toolkit=12.9` and keeping only `cuda-version=12.9` lets `libcuvs` pull in just the CUDA packages it actually needs.

**ROCm**: The latest miniforge ships `conda 25.7.0` with `conda-libmamba-solver 25.11.0`, which references `RepodataCache.cache_path_shards` — an attribute that does not exist in `conda 25.7.0`. The previous constraint `"conda<=25.07"` (numerically equal to `<=25.7.0`) did not force a downgrade. Pinning to `"conda<25.5"` along with `"conda-libmamba-solver<25.9"` ensures a compatible version pair.

Reviewed By: alibeklfc

Differential Revision: D103892827

fbshipit-source-id: 88c91a4741950cac4fe1f6ab56ae00fcf19c96cd
2026-05-06 15:15:52 -07:00
Alibek Zhakubayev 715725df36 Enable verbose mode for TestPyPI publish step (#5181)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5181

### THIS DIFF

Adds `verbose: true` to the `publish-testpypi` step of `build-pip.yml` so twine prints the full HTTP request/response body when uploading to TestPyPI. Without verbose mode, a 400 Bad Request from TestPyPI surfaces as the bare line `HTTPError: 400 Bad Request` with no further detail; twine's own warning even instructs the user to retry with `--verbose` for more details.

### CONTEXT

Follow-up to D103739933 (filter wheel artifacts) and D95258115 (pip wheel pipeline, landed). The first end-to-end TestPyPI upload attempt failed with an opaque 400 after wheel validation passed, attestations were generated, and the trusted publisher OIDC handshake succeeded (confirmed via PyPI security email naming environment `testpypi`). Without the response body, the cause cannot be diagnosed without round-tripping through GitHub Actions multiple times. Enabling verbose mode is the lightest-weight diagnostic: no behavior change on success, full error body on failure. We can flip it back off once the upload pipeline is known-good.

Reviewed By: mnorris11

Differential Revision: D103893976

fbshipit-source-id: 7abbf3abfadfc97527dc979957ea99bc14daad77
2026-05-05 12:24:25 -07:00
Alibek Zhakubayev 5e123115f1 Filter wheel artifacts before publishing to PyPI (#5179)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5179

### THIS DIFF

Restrict the artifact download in the `publish` and `publish-testpypi` jobs of `build-pip.yml` to only the wheel artifacts (`pattern: wheels-*`). Without this filter, `actions/download-artifact` pulls every artifact from the workflow run and flattens them into `dist/`. The pypa/gh-action-pypi-publish action then runs twine, which globs all of `dist/*` and rejects any non-wheel/non-sdist entry.

The build-pull-request.yml workflow runs C++ tests via the build_cmake composite action with `GTEST_OUTPUT="xml:.../test-results/googletest/"`, then uploads test-results as artifacts. When the publish jobs downloaded all artifacts, the resulting `dist/googletest` directory caused twine to fail with `InvalidDistribution: Unknown distribution format: 'googletest'`.

### CONTEXT

Follow-up to D95258115 (landed as 3593ed4fa5c1), which introduced the pip wheel build pipeline via scikit-build-core and cibuildwheel. The publish jobs were never exercised end-to-end before merge because they only run on tag push or manual dispatch. First TestPyPI run surfaced the artifact-namespace collision with the test-results uploader.

Reviewed By: mnorris11

Differential Revision: D103739933

fbshipit-source-id: d4ff563d1aa2ef002ef0bd7d972eaa082dcf4f47
2026-05-05 09:03:50 -07:00
Matthijs Douze 4a471eebf9 Pin conda <25.7 to fix Windows build (#5176)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5176

🤖 This diff was automatically generated by myclaw_faiss_monitor

conda 25.7.0 was released today and broke conda-build 25.3.1's plugin
registration. When conda 25.7.0 is installed, the `conda build` subcommand
is no longer recognized, even though conda-build is installed in the same
environment. Root cause: conda-build 25.3.1 was released before conda 25.7.0
and its plugin entry point is incompatible with conda 25.7.0's plugin loader.

Fix: change `<=25.07` to `<25.7` to exclude conda 25.7.0 until conda-build
is updated to support it.

The previous constraint `<=25.07` treated 25.07 and 25.7.0 as equivalent
(PEP 440), so conda 25.7.0 was pulled in. The new constraint `<25.7` pins
below the broken release.

Reviewed By: mnorris11

Differential Revision: D103589106

fbshipit-source-id: 6dfff41daca83b533b916f38ff724c0c1e924853
2026-05-05 07:56:53 -07:00
Matthijs Douze a9c0d4187b Work around GCC 12 miscompilation of AVX2 histogram (#5124)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5124

GCC 12.4 (used in the conda faiss-gpu build) miscompiles the SIMD
histogram_16 code path, causing test_16bin_bounded_bigrange to fail in
the CUDA 12.6 nightly.

Fall back to the scalar implementation when compiling with GCC 12.

🤖 This diff was automatically generated by myclaw_faiss_monitor

Reviewed By: junjieqi

Differential Revision: D101598734

fbshipit-source-id: b33a42df0bc3385cfdc3fc3ab8dabba7e09c9cd8
2026-05-05 00:46:37 -07:00
Alibek Zhakubayev 585ba7954a Add pip install support via scikit-build-core + cibuildwheel (#4862)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4862

Add official pip wheel packaging for `faiss-cpu`, enabling
`pip install faiss-cpu` from PyPI. Builds binary wheels across Linux
x86_64/aarch64, macOS arm64/x86_64, and Windows x86_64 for Python 3.10-3.14.
Linux and macOS use Python Stable ABI (abi3) — a single cp310-abi3 wheel
per platform works on all Python 3.10+ versions without per-version rebuilds.

**BLAS strategy:**
- Linux (x86_64 and aarch64): Threaded OpenBLAS (`libopenblaso`). The
  CMake build prefers `libopenblaso` (OpenMP-threaded) or `libopenblasp`
  (pthreads-threaded) over the serial default on RHEL/Fedora-based
  manylinux containers.
- macOS: Apple Accelerate (found automatically).
- Windows: Prebuilt OpenBLAS from GitHub releases (v0.3.30).

**SIMD optimization strategy:**
- Linux and macOS: Dynamic Dispatch (`FAISS_OPT_LEVEL=dd`) compiles SIMD-hot
  kernel files at multiple ISA levels (generic + AVX2 + AVX-512 on x86_64,
  NEON + SVE on aarch64) into a single library. Runtime CPUID detection
  selects the optimal code path automatically.
- Windows: MSVC does not support DD, so uses `FAISS_OPT_LEVEL=generic`.
  Shared libraries (`BUILD_SHARED_LIBS=ON`) are used to avoid MSVC's
  single-pass static archive scanning issue.

**New files:**
- `pyproject.toml`: scikit-build-core build backend config with cibuildwheel
  settings. Version is dynamically extracted from CMakeLists.txt. Enables
  abi3 on Linux/macOS via SWIG 4.2+ and NumPy 2.0+ Limited API support.
  Enables LTO and dead-code stripping for smaller wheel sizes.
- `.github/workflows/build-pip.yml`: CI workflow using cibuildwheel to build
  binary wheels on 5 platform runners. All GitHub Actions are pinned to
  commit SHAs for supply chain security. Publishes wheels to PyPI via OIDC
  trusted publishers on tag push.
- `THIRD_PARTY_NOTICES`: License notices for bundled dependencies (OpenBLAS,
  LLVM OpenMP).
- `tests/test_wheel_smoke.py`: 12-test smoke suite validating import,
  OpenMP, BLAS (FlatL2/FlatIP), index factory (IVF+PQ), HNSW, serialization
  roundtrip, GC safety, contrib imports, and SIMD level detection.

**Modified files:**
- `faiss/CMakeLists.txt`: Added threaded OpenBLAS fallback — prefers
  `libopenblaso` (OpenMP-threaded) or `libopenblasp` (pthreads-threaded)
  over the serial default on RHEL/Fedora-based manylinux containers.
- `python/CMakeLists.txt`: Added `install()` targets for scikit-build-core
  wheel packaging, including all Dynamic Dispatch SWIG variants
  (avx2/avx512/avx512_spr/sve). Added abi3 support: conditionally uses
  `Python::SABIModule`, defines `Py_LIMITED_API`, and sets `.abi3.so` suffix
  when `SKBUILD_SABI_VERSION` is set.
- `.github/workflows/build.yml`: Wired `build-pip.yml` into the root CI
  trigger so pip builds run alongside conda builds.
- `tests/BUCK`: Added `python_pytest` target for the smoke test.

Reviewed By: mnorris11

Differential Revision: D95258115

fbshipit-source-id: 3593ed4fa5c1d8b7bebfc61c933bb3204c9666eb
2026-05-01 15:26:26 -07:00
Evandabest 66cea52433 Add Metal GPU backend for Apple Silicon (IndexFlat) (#5144)
Summary:
## Summary
Adds a new Metal compute backend so FAISS can run GPU-accelerated similarity search on Apple Silicon (M1/M2/M3/M4/M5). This is just an initial pr, it introduces the build system integration, core Metal infrastructure, and a working `IndexFlat` with L2 and inner product search. I have some follow up prs with more functionality that I plan to submit.

Addresses https://github.com/facebookresearch/faiss/issues/2386 — FAISS currently has no GPU acceleration path on Apple Silicon, forcing CPU-only execution. This Metal backend enables GPU-accelerated search on M-series chips, with follow-up PRs adding IVF indexes, Python bindings, and kernel optimizations.

All Metal code lives in a new `faiss/gpu_metal/` directory, keeping `faiss/gpu/` (CUDA/ROCm) completely untouched. The backend is opt-in via `cmake -DFAISS_ENABLE_METAL=ON -DFAISS_ENABLE_GPU=OFF`.

### What's included
- **Build system**: New `FAISS_ENABLE_METAL` CMake option. When enabled, requires Apple platform, links Metal/MetalKit/MPS/Foundation frameworks, and builds `libfaiss_metal.a`. Three small additions to root `CMakeLists.txt`.
- **MetalResources**: Owns `MTLDevice`, `MTLCommandQueue`, and buffer allocation/deallocation. Mirrors `GpuResources` roles.
- **MetalIndex**: Base class for Metal-backed indexes (mirrors `GpuIndex`). Single-device only (device 0).
- **MetalIndexFlat**: Flat index storing vectors in an `MTLBuffer`. Supports `add`, `add_with_ids`, `reset`, `search` for both `METRIC_L2` and `METRIC_INNER_PRODUCT`.
- **MSL compute kernels**: `l2_squared_matrix`, `ip_matrix` (distance computation), and `topk` (sorted insertion, k ≤ 256). Embedded as a compile-time string in `MetalFlatKernels.mm`.
- **Backend abstraction**: `get_num_gpus()`, `index_cpu_to_metal_gpu()`, `index_metal_gpu_to_cpu()`, `StandardMetalResources`, and a `GpuIndexFlat` typedef for API parity.
- **Tests**: 8 gtest cases in `TestMetalIndexFlat.mm` — L2/IP search correctness vs CPU `IndexFlat`, `add_with_ids`, reset, empty search, `get_num_gpus`, and CPU↔Metal cloning in both directions. All tests skip gracefully if no Metal device is available.
- Python/SWIG bindings

### Planned follow up prs

- Larger k support (tiling, heap-based top-k)
- IVFFlat, IVFPQ, IVFSQ, BinaryFlat
- Kernel optimizations (fused distance+top-k, GEMM-tiled distance, simdgroup/threadgroup parallel selection)

### Build and test

```bash
mkdir -p build_metal && cd build_metal
cmake .. -DFAISS_ENABLE_METAL=ON -DFAISS_ENABLE_GPU=OFF \
         -DBUILD_TESTING=ON -DFAISS_ENABLE_PYTHON=OFF \
         -DCMAKE_PREFIX_PATH="/opt/homebrew/opt/libomp;/opt/homebrew"
cmake --build . --target faiss_metal TestMetalIndexFlat
ctest -R TestMetalIndexFlat
  ```
> The `mkdir -p` avoids the error if the directory exists, and `-DFAISS_ENABLE_PYTHON=OFF` skips the Python dependency that isn't needed for this PR.

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5144

Reviewed By: alibeklfc

Differential Revision: D102284936

Pulled By: mnorris11

fbshipit-source-id: 812fc6ceae251b7b33d25f6861fc37b8d7b475c1
2026-04-30 10:34:43 -07:00
Michael Norris 44c1972aec Enable ccache in GitHub Actions cmake builds (#5157)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5157

TLDR
-
ccache is like how BUCK works with partial cached artifacts for builds, but in the OSS world.

https://github.com/facebookresearch/faiss/actions/runs/25118621287/job/73635614448?pr=5157 it sped up the jobs a lot, cuVS down to 40 minutes!

AI stuff
-

Add ccache to the `build_cmake` composite action to speed up CI builds. Uses `hendrikmuhs/ccache-action@v1` to install ccache, restore/save caches keyed by build configuration (OS, arch, opt level, GPU, cuVS, ROCm, SVS), and set a 2GB max cache size. Passes `CMAKE_C_COMPILER_LAUNCHER`, `CMAKE_CXX_COMPILER_LAUNCHER`, and `CMAKE_CUDA_COMPILER_LAUNCHER` to cmake so all C, C++, and CUDA compilations go through ccache.

On first run the cache will be cold and there is no speedup. Subsequent runs on the same branch (or PRs against main) will see cache hits for unchanged translation units, which should significantly reduce build times for incremental CI runs.

Reviewed By: junjieqi

Differential Revision: D102926935

fbshipit-source-id: b8808a3a48edee271547a0421960261aba6ff425
2026-04-29 12:15:42 -07:00
Matthijs Douze 8d1b964c11 Enable dynamic dispatch build on Windows (#5127)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5127

Attempt to enable FAISS dynamic dispatch (DD) mode on Windows/MSVC.

Changes:
- CMakeLists.txt: Remove if(NOT WIN32) guard from DD section, add MSVC per-file
  SIMD flags (/arch:AVX2, /arch:AVX512, /bigobj) alongside existing GCC/Clang flags
- build-pull-request.yml: Add windows-x86_64-DD-cmake job that runs immediately
  (no dependency on linux-x86_64-cmake), builds with MSVC and FAISS_OPT_LEVEL=dd,
  runs C++ tests and Python tests

This diff is expected to fail on Windows due to MSVC requiring explicit template
specialization declarations (C++ §17.8.3) which GCC/Clang don't enforce. The CI
failure will surface the exact errors to guide the fix.

UPDATE: in fact, MSVC does not seem to require this. After fixing build scripts and a few classical Windows error, the C++ and python tests pass.

Reviewed By: algoriddle

Differential Revision: D101649751

fbshipit-source-id: 765ef8483d02652ce58625cd22baab8870acf718
2026-04-23 13:31:11 -07:00
Michael Norris 364749e886 Re-enable ROCm runner for AMD GPU CI (#4854)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4854

This re-enables the AMD ROCm runner that was previously disabled in D86250489.

Changes from the original configuration:
- Updated runner from `faiss-amd-MI200` to `linux-amd-rocm-mi325-ubuntu-24` to match the currently available GitHub Actions runner
- Updated container image from Ubuntu 22.04 to Ubuntu 24.04 to align with the runner environment

Test change:
- seems like cuda and hip disagree about some small rounding errors, so AI updated the test.

Reviewed By: subhadeepkaran

Differential Revision: D94941142

fbshipit-source-id: d5158b7939e3b7327432aa89a9a0d2e5ed1ad190
2026-04-07 13:08:22 -07:00
Michael Norris 8177a3bca6 Add nvidia-smi diagnostic call (#4960)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4960

NVIDIA recommended we add this step for easier debugging.

Reviewed By: junjieqi

Differential Revision: D97312954

fbshipit-source-id: 4c34c4d829c85c3abf4b0e1eec718e68a720f24c
2026-03-19 15:02:59 -07:00
Michael Norris 645a742b51 Re add cuvs to cmakelists.txt (#4953)
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4953

Reviewed By: scsiguy

Differential Revision: D97118209

fbshipit-source-id: f29135b7801664fbbf8cb65c836ad1a92b2193db
2026-03-19 08:06:00 -07:00
Tarang Jain 02d609caff Upgrade cuVS Version to 26.02 (#4945)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4945

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4788

Reviewed By: yingufan

Differential Revision: D96931953

Pulled By: mnorris11

fbshipit-source-id: 7d7a9b563048dc10bd44d22035216c7aa98b0003
2026-03-17 21:58:50 -07:00
Akshay Mahesh c24598a4c4 Revert D94939843: Upgrade cuVS Version to 26.02, switch various BUCK files over to 26.02
Differential Revision:
D94939843

Original commit changeset: 05a287aaaaa9

Original Phabricator Diff: D94939843

fbshipit-source-id: 4207d5d7b37d644a8e8d2d1c1ad9b26723e07d73
2026-03-17 02:38:50 -07:00
Tarang Jain 55a47c927c Upgrade cuVS Version to 26.02, switch various BUCK files over to 26.02 (#4788)
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4788

Reviewed By: subhadeepkaran, junjieqi

Differential Revision: D94939843

Pulled By: mnorris11

fbshipit-source-id: 05a287aaaaa9a27228cf77f0f753afc097abf489
2026-03-16 21:08:28 -07:00
Michael Norris 47e53b4468 Fix backward compatibility to use latest version (#4855)
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4855

Reviewed By: zoeyeye

Differential Revision: D95003637

fbshipit-source-id: 8def3429aa3890960c5b5b82431ad2878bac5c85
2026-03-06 19:10:08 -08:00
Michael Norris 5622e93733 v1.14.1 Fix build-release (#4876)
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4876

Reviewed By: alibeklfc

Differential Revision: D95420200

fbshipit-source-id: b30d0c9c0342460187c3b8dcffbbc3df88f4a11d
2026-03-06 09:33:08 -08:00
ethanglaser 6cf2c63bc3 Update SVS to v0.2.0 and install from conda forge (#4860)
Summary:
Installs [SVS v0.2.0](https://github.com/intel/ScalableVectorSearch/releases/tag/v0.2.0) which includes updates for LeanVec OOD and IVF to be integrated in subsequent PRs. Also removes intel conda channel logic as libsvs-runtime is now available on conda-forge.

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4860

Reviewed By: alibeklfc

Differential Revision: D95164622

Pulled By: mnorris11

fbshipit-source-id: 3b2bbaa8c5283e6aa5ac5ee250e8eac4ccba0e5a
2026-03-06 09:20:55 -08:00
Michael Norris c90c9dc544 Update python to include 3.13 and 3.14 (#4859)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4859

Needed because svs min version is 3.14 which is blocking D95003637 which is blocking Alibek from uncommenting the backward compat

Reviewed By: subhadeepkaran

Differential Revision: D95087382

fbshipit-source-id: f06c87dd896d2dcbec77e935cf8fb6d321a6a0ab
2026-03-03 17:19:33 -08:00
Gergely Szilvasy 089dc95b6d Fix backward compat CI: use isolated conda environments (#4799)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4799

The "CMake Write -> Conda Read" backward compatibility CI job fails on
ubuntu-latest because it tries to mutate the cmake build conda environment by
removing packages and then installing faiss-cpu=1.13.2. After package removal,
the Python 3.11 pin is lost and the solver picks up the runner's system
Python 3.13, which has no compatible faiss-cpu=1.13.2 package.

The "Conda Write -> CMake Read" job worked by accident because it happened to
call setup-miniconda with python-version 3.11 before installing faiss-cpu, but
it also relied on fragile environment mutation (conda uninstall) for the
transition to cmake.

Both jobs now use the same robust pattern: conda create a dedicated named
environment (faiss_conda_read / faiss_conda_write) with an explicit python=3.11
pin. This completely isolates the conda faiss-cpu environment from the cmake
build environment, eliminating environment mutation and solver pin issues.

Reviewed By: subhadeepkaran

Differential Revision: D92862355

fbshipit-source-id: 19052286b0e39519056f153913a7171052583ee2
2026-02-10 17:38:32 -08:00
Gergely Szilvasy 123e37143f Add Dynamic Dispatch OSS CI workflow (#4779)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4779

Add a new GitHub Actions job to build and test faiss DD target on
SPR hardware (faiss-aws-m7i.large) and ARM. These tests the DD build with opt_level=dd, which enables runtime SIMD detection.

Reviewed By: junjieqi

Differential Revision: D91795209

fbshipit-source-id: f5163efad57133fc061b8e7987eca41937e207f5
2026-02-09 01:19:35 -08:00
Matthijs Douze a73f22ee53 Demo for a diversity filter (#4765)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/4765

 There are use cases where there is a group id associated to each vector id.

 We want no more than max_per_group results per group but of course we also want to keep the best results for each group.

 This diff demonstrates how to obtain this functionality, using a custom result handler.

Differential Revision: D91020690

fbshipit-source-id: 92669cf8396ad8b11faa87c4420b35a3db2de7f9
2026-02-02 11:16:50 -08:00