Skip to content

Add configurable IVF centroid routing with persisted initializer types - #134

Merged
gouyt13 merged 1 commit into
mainfrom
feat/ivf-initializer-selection
Oct 8, 2026
Merged

gouyt13 merged 1 commit into
mainfrom
feat/ivf-initializer-selection

Conversation

@gouyt13

@gouyt13 gouyt13 commented Oct 8, 2026

Copy link
Copy Markdown
Member

Summary

IVF centroid routing was inferred solely from cluster count. Add explicit auto, flat, flat_rabitq, and hnsw selection in C++ and Python, and persist the resolved initializer in the v2 index header. Flat RaBitQ scans one-bit centroid codes before exact refinement of retained candidates and supports L2/IP. It remains an approximate router.

auto selects Flat below 5,000 clusters, Flat RaBitQ below 60,000, and HNSW otherwise. Existing constructor call syntax remains valid, but new builds can produce different results. C++ consumers must rebuild against matching headers and the core library.

Old indexes retain their historical routing, padding, and rotation state when loaded. Newly saved v2 files require the updated reader. HNSW sidecar writes now report open, write, and close failures; the dependency version and sidecar layout are unchanged.

Testing

  • Portable Release build (RABITQ_ENABLE_NATIVE_OPTIMIZATION=OFF): 318 C++ tests passed, one placement-specific case skipped; its separate OpenMP-bound test passed.
  • Rebuilt/installed Python extension in the existing environment: 938 tests passed, two platform-specific wheel checks skipped.
  • 39 focused ASan/UBSan/LeakSanitizer checks passed.
  • Baseline 5a3ae78 generated 12 real v1 indexes covering Flat/HNSW, L2/IP, 1/5/32 bits and padded dimension 96. Updated reader preserved query IDs/distances bit-for-bit. Resaving preserved payloads and six sidecars. Old reader rejected all new v2 files explicitly.
  • All initializer modes across 1-9/32 bits, boundary counts, malformed headers, failed reload preservation, concurrent queries, add/remove, save failures/retry, and round trips covered.
  • Installed CMake consumer, full clang-tidy, C++/Python formatting, Ruff, strict MkDocs build, and diff checks passed.
  • Paired local benchmark of the routing implementation: Xeon Gold 6418H, GCC 14.3, AVX-512, one thread, 50k-point subsets, 4,096 centroids, 5 bits, 256 queries, nprobe=64, median of three runs. Flat -> Flat RaBitQ microseconds/query: SIFT 82.3 -> 59.8; GIST 506.4 -> 120.1; Contriever (IP) 432.4 -> 166.6. Recall@10 was unchanged in each pair (0.89375, 0.7875, 0.9171875). Workload-specific results, not a general speed guarantee.
  • Native Windows and ARM64 checks were not run locally and remain for CI.

@gouyt13
gouyt13 merged commit 2ab57a4 into main Oct 8, 2026
37 checks passed
@gouyt13
gouyt13 deleted the feat/ivf-initializer-selection branch October 8, 2026 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant