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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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