faiss 0.6.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/faiss/version.rb +1 -1
  4. data/vendor/faiss/faiss/Index.h +1 -1
  5. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +6 -7
  6. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +3 -3
  7. data/vendor/faiss/faiss/IndexHNSW.cpp +173 -143
  8. data/vendor/faiss/faiss/IndexIVF.cpp +2 -2
  9. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +2 -2
  10. data/vendor/faiss/faiss/IndexIVFFlat.cpp +3 -1
  11. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +3 -3
  12. data/vendor/faiss/faiss/IndexIVFPQ.cpp +2 -3
  13. data/vendor/faiss/faiss/IndexIVFPQR.cpp +2 -3
  14. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +4 -13
  15. data/vendor/faiss/faiss/IndexNNDescent.cpp +1 -1
  16. data/vendor/faiss/faiss/IndexNSG.cpp +1 -2
  17. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +68 -6
  18. data/vendor/faiss/faiss/IndexScalarQuantizer.h +10 -0
  19. data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +1 -1
  20. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +902 -12
  21. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +702 -10
  22. data/vendor/faiss/faiss/factory_tools.cpp +4 -0
  23. data/vendor/faiss/faiss/gpu/GpuResources.h +3 -2
  24. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +11 -12
  25. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +3 -3
  26. data/vendor/faiss/faiss/gpu_metal/MetalDistance.h +87 -0
  27. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +7 -0
  28. data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +181 -0
  29. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +48 -3
  30. data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +45 -0
  31. data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFFlat.h +193 -0
  32. data/vendor/faiss/faiss/impl/HNSW.cpp +556 -199
  33. data/vendor/faiss/faiss/impl/HNSW.h +51 -13
  34. data/vendor/faiss/faiss/impl/NSG.cpp +15 -11
  35. data/vendor/faiss/faiss/impl/Panorama.h +11 -0
  36. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +25 -2
  37. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +1 -1
  38. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +7 -1
  39. data/vendor/faiss/faiss/impl/ResultHandler.h +1 -0
  40. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +271 -8
  41. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +50 -0
  42. data/vendor/faiss/faiss/impl/VisitedTable.cpp +10 -10
  43. data/vendor/faiss/faiss/impl/VisitedTable.h +69 -34
  44. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +3 -1
  45. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +35 -43
  46. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -15
  47. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +86 -40
  48. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +81 -50
  49. data/vendor/faiss/faiss/impl/index_read.cpp +100 -39
  50. data/vendor/faiss/faiss/impl/index_write.cpp +1 -0
  51. data/vendor/faiss/faiss/impl/io_macros.h +25 -0
  52. data/vendor/faiss/faiss/impl/platform_macros.h +12 -8
  53. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +2 -0
  54. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +2 -0
  55. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +2 -0
  56. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +20 -0
  57. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +36 -0
  58. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +5 -0
  59. data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +105 -0
  60. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +2 -0
  61. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +6 -0
  62. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +327 -18
  63. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +264 -27
  64. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +553 -0
  65. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +559 -0
  66. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +199 -27
  67. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +366 -3
  68. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +144 -19
  69. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +26 -0
  70. data/vendor/faiss/faiss/impl/simd_dispatch.h +65 -8
  71. data/vendor/faiss/faiss/index_factory.cpp +5 -1
  72. data/vendor/faiss/faiss/index_io.h +16 -0
  73. data/vendor/faiss/faiss/invlists/DirectMap.cpp +4 -1
  74. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +13 -13
  75. data/vendor/faiss/faiss/invlists/InvertedLists.h +2 -2
  76. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +119 -22
  77. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +15 -5
  78. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +3 -2
  79. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
  80. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +65 -24
  81. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +3 -2
  82. data/vendor/faiss/faiss/utils/bf16.h +34 -0
  83. data/vendor/faiss/faiss/utils/distances_simd.cpp +0 -1
  84. data/vendor/faiss/faiss/utils/hamming.cpp +8 -8
  85. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +2 -1
  86. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +15 -0
  87. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +6 -30
  88. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_spr.h +171 -0
  89. data/vendor/faiss/faiss/utils/partitioning.cpp +0 -2
  90. data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +14 -68
  91. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512_spr.cpp +343 -0
  92. data/vendor/faiss/faiss/utils/simd_levels.cpp +12 -2
  93. metadata +12 -2
@@ -309,12 +309,12 @@ void IndexIVFRaBitQ::reconstruct_from_offset(
309
309
  int64_t list_no,
310
310
  int64_t offset,
311
311
  float* recons) const {
312
- const uint8_t* code = invlists->get_single_code(list_no, offset);
312
+ InvertedLists::ScopedCodes sc(invlists, list_no, offset);
313
313
 
314
314
  std::vector<float> centroid(d);
315
315
  quantizer->reconstruct(list_no, centroid.data());
316
316
 
317
- rabitq.decode_core(code, recons, 1, centroid.data());
317
+ rabitq.decode_core(sc.get(), recons, 1, centroid.data());
318
318
  }
319
319
 
320
320
  void IndexIVFRaBitQ::sa_decode(idx_t n, const uint8_t* codes, float* x) const {
@@ -357,26 +357,17 @@ float IVFRaBitDistanceComputer::operator()(idx_t i) {
357
357
  uint64_t list_no = lo_listno(lo);
358
358
  uint64_t offset = lo_offset(lo);
359
359
 
360
- const uint8_t* code = parent->invlists->get_single_code(list_no, offset);
360
+ InvertedLists::ScopedCodes sc(parent->invlists, list_no, offset);
361
361
 
362
362
  // ok, we know the appropriate cluster that we need
363
363
  std::vector<float> centroid(parent->d);
364
364
  parent->quantizer->reconstruct(list_no, centroid.data());
365
365
 
366
- // compute the distance
367
- float distance = 0;
368
-
369
366
  std::unique_ptr<FlatCodesDistanceComputer> dc(
370
367
  parent->rabitq.get_distance_computer(
371
368
  parent->qb, centroid.data(), /*centered=*/false));
372
369
  dc->set_query(q);
373
- distance = dc->distance_to_code(code);
374
-
375
- // deallocate
376
- parent->invlists->release_codes(list_no, code);
377
-
378
- // done
379
- return distance;
370
+ return dc->distance_to_code(sc.get());
380
371
  }
381
372
 
382
373
  float IVFRaBitDistanceComputer::symmetric_dis(idx_t /*i*/, idx_t /*j*/) {
@@ -126,7 +126,7 @@ void IndexNNDescent::search(
126
126
  std::unique_ptr<DistanceComputer> dis;
127
127
  std::unique_ptr<VisitedTable> vt;
128
128
  try {
129
- vt = std::make_unique<VisitedTable>(ntotal);
129
+ vt = VisitedTable::create(ntotal);
130
130
  dis.reset(storage_distance_computer(storage));
131
131
  } catch (...) {
132
132
  omp_capture_exception(ex, [&] { interrupt = true; });
@@ -81,8 +81,7 @@ void IndexNSG::search(
81
81
  std::unique_ptr<DistanceComputer> dis;
82
82
  std::unique_ptr<VisitedTable> vt;
83
83
  try {
84
- vt = std::make_unique<VisitedTable>(
85
- ntotal, nsg.use_visited_hashset);
84
+ vt = VisitedTable::create(ntotal, nsg.use_visited_hashset);
86
85
  dis.reset(storage_distance_computer(storage));
87
86
  } catch (...) {
88
87
  omp_capture_exception(ex, [&] { interrupt = true; });
@@ -14,6 +14,9 @@
14
14
 
15
15
  #include <omp.h>
16
16
 
17
+ #include <faiss/impl/ResultHandler.h>
18
+ #include <faiss/impl/expanded_scanners.h>
19
+
17
20
  #include <faiss/impl/FaissAssert.h>
18
21
  #include <faiss/impl/IDSelector.h>
19
22
  #include <faiss/impl/ScalarQuantizer.h>
@@ -137,6 +140,9 @@ IndexIVFScalarQuantizer::IndexIVFScalarQuantizer(
137
140
  by_residual = false;
138
141
  is_trained = true; // no training needed
139
142
  }
143
+ if (ScalarQuantizer::TurboQuantRefine::is_turboq_full(qtype)) {
144
+ by_residual = false;
145
+ }
140
146
  }
141
147
 
142
148
  IndexIVFScalarQuantizer::IndexIVFScalarQuantizer() : IndexIVF() {
@@ -330,9 +336,65 @@ void IndexIVFScalarQuantizer::add_core(
330
336
  InvertedListScanner* IndexIVFScalarQuantizer::get_InvertedListScanner(
331
337
  bool store_pairs,
332
338
  const IDSelector* sel,
333
- const IVFSearchParameters*) const {
334
- return sq.select_InvertedListScanner(
335
- metric_type, quantizer, store_pairs, sel, by_residual);
339
+ const IVFSearchParameters* search_params) const {
340
+ if (!ScalarQuantizer::TurboQuantRefine::is_turboq_full(sq.qtype)) {
341
+ return sq.select_InvertedListScanner(
342
+ metric_type, quantizer, store_pairs, sel, by_residual);
343
+ }
344
+
345
+ // TurboQ full types: create a TQ-specific scanner that supports
346
+ // search params (qb, int_qjl) and pre-screening.
347
+ uint8_t tq_qb = 0;
348
+ bool tq_int_qjl = false;
349
+ if (auto* tp = dynamic_cast<const IVFSQTurboQSearchParameters*>(
350
+ search_params)) {
351
+ tq_qb = tp->qb;
352
+ tq_int_qjl = tp->int_qjl;
353
+ }
354
+ using TurboQDC = ScalarQuantizer::TurboQuantRefine::DistanceComputer;
355
+ auto* dc = static_cast<TurboQDC*>(sq.get_distance_computer(metric_type));
356
+ dc->configure(tq_qb, tq_int_qjl);
357
+
358
+ struct TQScanner : InvertedListScanner {
359
+ std::unique_ptr<TurboQDC> dc;
360
+
361
+ explicit TQScanner(
362
+ TurboQDC* dc_in,
363
+ bool store_pairs_in,
364
+ const IDSelector* sel_in,
365
+ bool keep_max_in)
366
+ : InvertedListScanner(store_pairs_in, sel_in), dc(dc_in) {
367
+ this->keep_max = keep_max_in;
368
+ }
369
+
370
+ void set_query(const float* query) override {
371
+ dc->set_query(query);
372
+ }
373
+
374
+ void set_list(idx_t list_no_in, float) override {
375
+ this->list_no = list_no_in;
376
+ }
377
+
378
+ float distance_to_code(const uint8_t* code) const final {
379
+ return dc->distance_to_code(code);
380
+ }
381
+
382
+ size_t scan_codes(
383
+ size_t list_size,
384
+ const uint8_t* codes,
385
+ const idx_t* ids,
386
+ ResultHandler& handler) const override {
387
+ dc->set_prescreen_threshold(&handler.threshold, !keep_max);
388
+ size_t nup = run_scan_codes(*this, list_size, codes, ids, handler);
389
+ dc->clear_prescreen_threshold();
390
+ return nup;
391
+ }
392
+ };
393
+
394
+ auto* scanner = new TQScanner(
395
+ dc, store_pairs, sel, is_similarity_metric(metric_type));
396
+ scanner->code_size = code_size;
397
+ return scanner;
336
398
  }
337
399
 
338
400
  void IndexIVFScalarQuantizer::reconstruct_from_offset(
@@ -344,18 +406,18 @@ void IndexIVFScalarQuantizer::reconstruct_from_offset(
344
406
  quantizer->reconstruct(list_no, recons);
345
407
  return;
346
408
  }
347
- const uint8_t* code = invlists->get_single_code(list_no, offset);
409
+ InvertedLists::ScopedCodes sc(invlists, list_no, offset);
348
410
 
349
411
  if (by_residual) {
350
412
  std::vector<float> centroid(d);
351
413
  quantizer->reconstruct(list_no, centroid.data());
352
414
 
353
- sq.decode(code, recons, 1);
415
+ sq.decode(sc.get(), recons, 1);
354
416
  for (int i = 0; i < d; ++i) {
355
417
  recons[i] += centroid[i];
356
418
  }
357
419
  } else {
358
- sq.decode(code, recons, 1);
420
+ sq.decode(sc.get(), recons, 1);
359
421
  }
360
422
  }
361
423
 
@@ -63,6 +63,16 @@ struct IndexScalarQuantizer : IndexFlatCodes {
63
63
  * distances are computed.
64
64
  */
65
65
 
66
+ /// Search parameters for TurboQuant full types (QT_*_tq).
67
+ struct IVFSQTurboQSearchParameters : IVFSearchParameters {
68
+ /// Query quantization bits for integer MSE pre-screening.
69
+ /// 0 = float path (default), 1-8 = integer popcount path.
70
+ uint8_t qb = 0;
71
+
72
+ /// Also use integer popcount for QJL stage (requires qb > 0).
73
+ bool int_qjl = false;
74
+ };
75
+
66
76
  struct IndexIVFScalarQuantizer : IndexIVF {
67
77
  ScalarQuantizer sq;
68
78
 
@@ -313,7 +313,7 @@
313
313
  #ifdef __AVX2__
314
314
  #include <faiss/cppcontrib/sa_decode/Level2-avx2-inl.h>
315
315
  #include <faiss/cppcontrib/sa_decode/PQ-avx2-inl.h>
316
- #elif defined(__ARM_NEON)
316
+ #elif defined(__ARM_NEON) || defined(__aarch64__)
317
317
  #include <faiss/cppcontrib/sa_decode/Level2-neon-inl.h>
318
318
  #include <faiss/cppcontrib/sa_decode/PQ-neon-inl.h>
319
319
  #else