faiss 0.6.1 → 0.6.3

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 (186) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/lib/faiss/version.rb +1 -1
  4. data/vendor/faiss/faiss/AutoTune.cpp +3 -1
  5. data/vendor/faiss/faiss/Clustering.cpp +9 -1
  6. data/vendor/faiss/faiss/IVFlib.cpp +14 -3
  7. data/vendor/faiss/faiss/Index.h +2 -2
  8. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +9 -10
  9. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +2 -3
  10. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +1 -2
  11. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +10 -12
  12. data/vendor/faiss/faiss/IndexBinaryHash.cpp +5 -9
  13. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +5 -7
  14. data/vendor/faiss/faiss/IndexEDEN.cpp +273 -0
  15. data/vendor/faiss/faiss/IndexEDEN.h +57 -0
  16. data/vendor/faiss/faiss/IndexFastScan.cpp +15 -4
  17. data/vendor/faiss/faiss/IndexFlat.cpp +13 -50
  18. data/vendor/faiss/faiss/IndexHNSW.cpp +177 -148
  19. data/vendor/faiss/faiss/IndexIDMap.cpp +16 -3
  20. data/vendor/faiss/faiss/IndexIDMap.h +2 -0
  21. data/vendor/faiss/faiss/IndexIVF.cpp +19 -8
  22. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +3 -3
  23. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +3 -4
  24. data/vendor/faiss/faiss/IndexIVFEDEN.cpp +302 -0
  25. data/vendor/faiss/faiss/IndexIVFEDEN.h +70 -0
  26. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +5 -6
  27. data/vendor/faiss/faiss/IndexIVFFlat.cpp +6 -5
  28. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +3 -3
  29. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +1 -1
  30. data/vendor/faiss/faiss/IndexIVFPQ.cpp +42 -25
  31. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +0 -1
  32. data/vendor/faiss/faiss/IndexIVFPQR.cpp +2 -3
  33. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +23 -62
  34. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +180 -76
  35. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +5 -4
  36. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +8 -6
  37. data/vendor/faiss/faiss/IndexLSH.cpp +2 -3
  38. data/vendor/faiss/faiss/IndexLattice.cpp +5 -0
  39. data/vendor/faiss/faiss/IndexNNDescent.cpp +10 -3
  40. data/vendor/faiss/faiss/IndexNSG.cpp +8 -4
  41. data/vendor/faiss/faiss/IndexPQ.cpp +6 -8
  42. data/vendor/faiss/faiss/IndexPreTransform.cpp +15 -0
  43. data/vendor/faiss/faiss/IndexRaBitQ.cpp +2 -2
  44. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +1 -2
  45. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +5 -1
  46. data/vendor/faiss/faiss/IndexRefine.cpp +30 -1
  47. data/vendor/faiss/faiss/IndexReplicas.cpp +1 -2
  48. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +68 -6
  49. data/vendor/faiss/faiss/IndexScalarQuantizer.h +10 -0
  50. data/vendor/faiss/faiss/IndexShards.cpp +2 -2
  51. data/vendor/faiss/faiss/IndexShardsIVF.cpp +2 -2
  52. data/vendor/faiss/faiss/MetaIndexes.cpp +2 -4
  53. data/vendor/faiss/faiss/SuperKMeans.cpp +256 -240
  54. data/vendor/faiss/faiss/SuperKMeans.h +30 -0
  55. data/vendor/faiss/faiss/VectorTransform.cpp +33 -2
  56. data/vendor/faiss/faiss/clone_index.cpp +5 -0
  57. data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +1 -1
  58. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +902 -12
  59. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +702 -10
  60. data/vendor/faiss/faiss/factory_tools.cpp +51 -4
  61. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +11 -11
  62. data/vendor/faiss/faiss/gpu/GpuIndex.h +34 -11
  63. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +47 -0
  64. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +17 -0
  65. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +16 -0
  66. data/vendor/faiss/faiss/gpu/GpuResources.h +3 -2
  67. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +11 -12
  68. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +3 -3
  69. data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +1 -1
  70. data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +2 -2
  71. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +180 -0
  72. data/vendor/faiss/faiss/gpu_metal/MetalDistance.h +87 -0
  73. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +7 -0
  74. data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +177 -0
  75. data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFPQ.h +88 -0
  76. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +48 -3
  77. data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +45 -0
  78. data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFFlat.h +193 -0
  79. data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFPQ.h +134 -0
  80. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +2 -2
  81. data/vendor/faiss/faiss/impl/DistanceComputer.h +34 -0
  82. data/vendor/faiss/faiss/impl/EDENQuantizer.h +119 -0
  83. data/vendor/faiss/faiss/impl/HNSW.cpp +658 -344
  84. data/vendor/faiss/faiss/impl/HNSW.h +51 -13
  85. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +2 -2
  86. data/vendor/faiss/faiss/impl/NSG.cpp +18 -12
  87. data/vendor/faiss/faiss/impl/Panorama.h +20 -7
  88. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +152 -84
  89. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +59 -24
  90. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +45 -37
  91. data/vendor/faiss/faiss/impl/RaBitQUtils.h +35 -0
  92. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +175 -68
  93. data/vendor/faiss/faiss/impl/RaBitQuantizer.h +19 -0
  94. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +2 -11
  95. data/vendor/faiss/faiss/impl/ResultHandler.h +26 -31
  96. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +522 -58
  97. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +70 -0
  98. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +2 -2
  99. data/vendor/faiss/faiss/impl/VisitedTable.cpp +33 -13
  100. data/vendor/faiss/faiss/impl/VisitedTable.h +88 -33
  101. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +1 -1
  102. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +4 -4
  103. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +38 -3
  104. data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +1 -1
  105. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +35 -43
  106. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -15
  107. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +86 -40
  108. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +81 -50
  109. data/vendor/faiss/faiss/impl/index_read.cpp +476 -75
  110. data/vendor/faiss/faiss/impl/index_write.cpp +56 -4
  111. data/vendor/faiss/faiss/impl/io_macros.h +25 -0
  112. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +8 -9
  113. data/vendor/faiss/faiss/impl/platform_macros.h +15 -9
  114. data/vendor/faiss/faiss/impl/polysemous_training/avx512.cpp +284 -0
  115. data/vendor/faiss/faiss/impl/polysemous_training/dispatch.h +115 -0
  116. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +0 -1
  117. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +26 -15
  118. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +6 -4
  119. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +2 -0
  120. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +2 -0
  121. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +20 -0
  122. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +36 -0
  123. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +5 -0
  124. data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +105 -0
  125. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +2 -0
  126. data/vendor/faiss/faiss/impl/result_handler/ResultHandler.cpp +195 -0
  127. data/vendor/faiss/faiss/impl/result_handler/avx2.cpp +133 -0
  128. data/vendor/faiss/faiss/impl/result_handler/avx512.cpp +281 -0
  129. data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx2.cpp +72 -0
  130. data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx512.cpp +228 -0
  131. data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer.cpp +882 -0
  132. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +6 -0
  133. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +336 -26
  134. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +331 -32
  135. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +553 -0
  136. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +558 -0
  137. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +284 -45
  138. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +502 -3
  139. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +157 -32
  140. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +26 -0
  141. data/vendor/faiss/faiss/impl/simd_dispatch.h +86 -8
  142. data/vendor/faiss/faiss/index_factory.cpp +37 -7
  143. data/vendor/faiss/faiss/index_io.h +16 -0
  144. data/vendor/faiss/faiss/invlists/DirectMap.cpp +5 -2
  145. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +15 -15
  146. data/vendor/faiss/faiss/invlists/InvertedLists.h +2 -2
  147. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +19 -4
  148. data/vendor/faiss/faiss/python/python_callbacks.cpp +3 -1
  149. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +60 -0
  150. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +26 -1
  151. data/vendor/faiss/faiss/svs/IndexSVSFlat.h +13 -0
  152. data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +1 -1
  153. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +1 -1
  154. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +150 -23
  155. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +30 -7
  156. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +3 -2
  157. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
  158. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +65 -25
  159. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +3 -2
  160. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +1 -1
  161. data/vendor/faiss/faiss/utils/bf16.h +34 -0
  162. data/vendor/faiss/faiss/utils/distances.cpp +14 -2
  163. data/vendor/faiss/faiss/utils/distances_simd.cpp +4 -4
  164. data/vendor/faiss/faiss/utils/extra_distances.cpp +4 -14
  165. data/vendor/faiss/faiss/utils/extra_distances.h +1 -2
  166. data/vendor/faiss/faiss/utils/hamming.cpp +9 -9
  167. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +2 -1
  168. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +15 -0
  169. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +6 -30
  170. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_spr.h +171 -0
  171. data/vendor/faiss/faiss/utils/partitioning.cpp +0 -2
  172. data/vendor/faiss/faiss/utils/quantize_lut.cpp +29 -8
  173. data/vendor/faiss/faiss/utils/rabitq_simd.h +202 -0
  174. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +0 -1
  175. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +263 -15
  176. data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +160 -18
  177. data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +14 -68
  178. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +245 -0
  179. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +273 -0
  180. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512_spr.cpp +435 -0
  181. data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +11 -0
  182. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +143 -6
  183. data/vendor/faiss/faiss/utils/simd_levels.cpp +56 -2
  184. data/vendor/faiss/faiss/utils/simd_levels.h +14 -0
  185. data/vendor/faiss/faiss/utils/utils.cpp +9 -27
  186. metadata +27 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08fc3bcca329e78e913982923c3fb3743e07591ffd717f5f3027e0609037b5de'
4
- data.tar.gz: 2a1a79aeaef1756a974fe7e9c3448794496ef145046da39aae3b6ce04a9bf131
3
+ metadata.gz: 0ab0ef0079ca7056c6d303b95882757645a81bee9b4c13862f4337dbec1b105a
4
+ data.tar.gz: d61339d723153ed333a6719001de98fa1742606334684b0f7db26f26ad001b09
5
5
  SHA512:
6
- metadata.gz: 86e6528125608c64ab9bec3f289019cc0a4125e6719d8c43ca7e9f8eb09cb57ce42f9e040fd0290969f45f70fb25c789a50de7aceef07c38b0acb5ca5e674c49
7
- data.tar.gz: 4efe37e9e855ab4da2e620e391ac817e6bfa808ca227ea047b55eaff4e7cfdae4c5af59d35b57963653d208e50334edc048fc168fd6d49f805cdb07d3dbc115e
6
+ metadata.gz: 20ce33982905751c82f05241b94ca500b241ac15f18245e8e14dad29d2fe5f162c7d4fe4e5441e92f79e06eb9519538831fa2c857050e6b3ea8ad5d0b8e63366
7
+ data.tar.gz: cfd073d25d3067488fdde88e06c5c68eeec6840ea57b9e6222129f4594279a27148b62361bcbd0dcc57727053acd35e4f202558adef03de648d0c8179f05ce07
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.6.3 (2026-08-03)
2
+
3
+ - Updated Faiss to 1.15.0
4
+
5
+ ## 0.6.2 (2026-06-13)
6
+
7
+ - Updated Faiss to 1.14.3
8
+
1
9
  ## 0.6.1 (2026-05-23)
2
10
 
3
11
  - Updated Faiss to 1.14.2
data/lib/faiss/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Faiss
2
- VERSION = "0.6.1"
2
+ VERSION = "0.6.3"
3
3
  end
@@ -45,6 +45,8 @@ void AutoTuneCriterion::set_groundtruth(
45
45
  gt_D.resize(nq * gt_nnn_in);
46
46
  memcpy(gt_D.data(), gt_D_in, sizeof(gt_D[0]) * nq * gt_nnn_in);
47
47
  }
48
+ FAISS_THROW_IF_NOT_MSG(
49
+ gt_I_in != nullptr, "set_groundtruth: gt_I must be non-null");
48
50
  gt_I.resize(nq * gt_nnn_in);
49
51
  memcpy(gt_I.data(), gt_I_in, sizeof(gt_I[0]) * nq * gt_nnn_in);
50
52
  }
@@ -148,7 +150,7 @@ bool OperatingPoints::add(
148
150
  }
149
151
  // remove non-optimal points from array
150
152
  for (size_t i = a.size() - 1; i > 0; --i) {
151
- if (a[i].t < a[i - 1].t) {
153
+ if (a[i].t <= a[i - 1].t) {
152
154
  a.erase(a.begin() + (i - 1));
153
155
  }
154
156
  }
@@ -367,7 +367,7 @@ void Clustering::train_encoded(
367
367
  ? std::numeric_limits<double>::max()
368
368
  : std::abs(prev_obj - obj) / std::abs(prev_obj);
369
369
 
370
- if (change >= 0 && change <= early_stop_threshold) {
370
+ if (change <= early_stop_threshold) {
371
371
  if (verbose) {
372
372
  printf("\n Converged at iteration %d: "
373
373
  "objective did not change\n",
@@ -439,6 +439,14 @@ float kmeans_clustering(
439
439
  size_t k,
440
440
  const float* x,
441
441
  float* centroids) {
442
+ FAISS_THROW_IF_NOT_FMT(
443
+ d <= static_cast<size_t>(std::numeric_limits<int>::max()),
444
+ "kmeans_clustering: d=%zu exceeds INT_MAX",
445
+ d);
446
+ FAISS_THROW_IF_NOT_FMT(
447
+ k <= static_cast<size_t>(std::numeric_limits<int>::max()),
448
+ "kmeans_clustering: k=%zu exceeds INT_MAX",
449
+ k);
442
450
  Clustering clus(static_cast<int>(d), static_cast<int>(k));
443
451
  clus.verbose = d * n * k > (size_t(1) << 30);
444
452
  // display logs if > 1Gflop per iteration
@@ -592,8 +592,12 @@ void handle_ivf(
592
592
  static_cast<faiss::IndexIVF*>(faiss::clone_index(clone));
593
593
  if (generate_ids) {
594
594
  // Assume the quantizer does not natively support add_with_ids.
595
- sharded_index->quantizer =
596
- new IndexIDMap2(sharded_index->quantizer);
595
+ // The IDMap wraps the cloned quantizer; own_fields makes it delete
596
+ // that quantizer when sharded_index (which owns the IDMap) is
597
+ // freed.
598
+ auto* id_quantizer = new IndexIDMap2(sharded_index->quantizer);
599
+ id_quantizer->own_fields = true;
600
+ sharded_index->quantizer = id_quantizer;
597
601
  sharded_index->quantizer->add_with_ids(
598
602
  sharded_centroids[i].size() / index->quantizer->d,
599
603
  sharded_centroids[i].data(),
@@ -615,6 +619,7 @@ void handle_ivf(
615
619
  faiss::write_index(sharded_index, fname);
616
620
  delete sharded_index;
617
621
  }
622
+ delete clone;
618
623
  }
619
624
 
620
625
  void handle_binary_ivf(
@@ -650,8 +655,13 @@ void handle_binary_ivf(
650
655
  faiss::clone_binary_index(clone));
651
656
  if (generate_ids) {
652
657
  // Assume the quantizer does not natively support add_with_ids.
653
- sharded_index->quantizer =
658
+ // The IDMap wraps the cloned quantizer; own_fields makes it delete
659
+ // that quantizer when sharded_index (which owns the IDMap) is
660
+ // freed.
661
+ auto* id_quantizer =
654
662
  new IndexBinaryIDMap2(sharded_index->quantizer);
663
+ id_quantizer->own_fields = true;
664
+ sharded_index->quantizer = id_quantizer;
655
665
  sharded_index->quantizer->add_with_ids(
656
666
  sharded_centroids[i].size() / reconstruction_size,
657
667
  sharded_centroids[i].data(),
@@ -673,6 +683,7 @@ void handle_binary_ivf(
673
683
  faiss::write_index_binary(sharded_index, fname);
674
684
  delete sharded_index;
675
685
  }
686
+ delete clone;
676
687
  }
677
688
 
678
689
  template <typename IndexType>
@@ -16,8 +16,8 @@
16
16
  #include <cstdio>
17
17
 
18
18
  #define FAISS_VERSION_MAJOR 1
19
- #define FAISS_VERSION_MINOR 14
20
- #define FAISS_VERSION_PATCH 2
19
+ #define FAISS_VERSION_MINOR 15
20
+ #define FAISS_VERSION_PATCH 0
21
21
 
22
22
  // Macro to combine the version components into a single string
23
23
  #ifndef FAISS_STRINGIFY
@@ -58,8 +58,8 @@ struct AQDistanceComputerDecompress : FlatCodesDistanceComputer {
58
58
  }
59
59
 
60
60
  float symmetric_dis(idx_t i, idx_t j) final {
61
- aq.decode(codes + i * d, tmp.data(), 1);
62
- aq.decode(codes + j * d, tmp.data() + d, 1);
61
+ aq.decode(codes + i * code_size, tmp.data(), 1);
62
+ aq.decode(codes + j * code_size, tmp.data() + d, 1);
63
63
  return vd(tmp.data(), tmp.data() + d);
64
64
  }
65
65
 
@@ -79,7 +79,8 @@ struct AQDistanceComputerLUT : FlatCodesDistanceComputer {
79
79
 
80
80
  explicit AQDistanceComputerLUT(const IndexAdditiveQuantizer& iaq)
81
81
  : FlatCodesDistanceComputer(iaq.codes.data(), iaq.code_size),
82
- LUT(iaq.aq->total_codebook_size + iaq.d * 2),
82
+ LUT(iaq.aq->total_codebook_size // Storage for LUT.
83
+ + size_t(iaq.d) * 2), // tmp storage for symmetric distance.
83
84
  aq(*iaq.aq),
84
85
  d(iaq.d) {}
85
86
 
@@ -96,9 +97,9 @@ struct AQDistanceComputerLUT : FlatCodesDistanceComputer {
96
97
  }
97
98
 
98
99
  float symmetric_dis(idx_t i, idx_t j) final {
99
- float* tmp = LUT.data();
100
- aq.decode(codes + i * d, tmp, 1);
101
- aq.decode(codes + j * d, tmp + d, 1);
100
+ float* tmp = LUT.data() + aq.total_codebook_size;
101
+ aq.decode(codes + i * code_size, tmp, 1);
102
+ aq.decode(codes + j * code_size, tmp + d, 1);
102
103
  return fvec_L2sqr(tmp, tmp + d, d);
103
104
  }
104
105
 
@@ -234,8 +235,7 @@ void IndexAdditiveQuantizer::search(
234
235
  float* distances,
235
236
  idx_t* labels,
236
237
  const SearchParameters* params) const {
237
- FAISS_THROW_IF_NOT_MSG(
238
- !params, "search params not supported for this index");
238
+ FAISS_THROW_IF_MSG(params, "search params not supported for this index");
239
239
 
240
240
  if (aq->search_type == AdditiveQuantizer::ST_decompress) {
241
241
  with_VectorDistance(d, metric_type, metric_arg, [&](auto vd) {
@@ -458,8 +458,7 @@ void AdditiveCoarseQuantizer::search(
458
458
  float* distances,
459
459
  idx_t* labels,
460
460
  const SearchParameters* params) const {
461
- FAISS_THROW_IF_NOT_MSG(
462
- !params, "search params not supported for this index");
461
+ FAISS_THROW_IF_MSG(params, "search params not supported for this index");
463
462
 
464
463
  if (metric_type == METRIC_INNER_PRODUCT) {
465
464
  aq->knn_centroids_inner_product(n, x, k, distances, labels);
@@ -36,7 +36,7 @@ void IndexAdditiveQuantizerFastScan::init(
36
36
  MetricType metric,
37
37
  int bbs_) {
38
38
  FAISS_THROW_IF_NOT(aq_init != nullptr);
39
- FAISS_THROW_IF_NOT(!aq_init->nbits.empty());
39
+ FAISS_THROW_IF_MSG(aq_init->nbits.empty(), "nbits must not be empty");
40
40
  FAISS_THROW_IF_NOT(aq_init->nbits[0] == 4);
41
41
  if (metric == METRIC_INNER_PRODUCT) {
42
42
  FAISS_THROW_IF_NOT_MSG(
@@ -192,8 +192,7 @@ void IndexAdditiveQuantizerFastScan::search(
192
192
  float* distances,
193
193
  idx_t* labels,
194
194
  const SearchParameters* params) const {
195
- FAISS_THROW_IF_NOT_MSG(
196
- !params, "search params not supported for this index");
195
+ FAISS_THROW_IF_MSG(params, "search params not supported for this index");
197
196
  FAISS_THROW_IF_NOT(k > 0);
198
197
  bool rescale = (rescale_norm && norm_scale > 1 && metric_type == METRIC_L2);
199
198
  if (!rescale) {
@@ -55,8 +55,7 @@ void IndexBinaryFromFloat::search(
55
55
  int32_t* distances,
56
56
  idx_t* labels,
57
57
  const SearchParameters* params) const {
58
- FAISS_THROW_IF_NOT_MSG(
59
- !params, "search params not supported for this index");
58
+ FAISS_THROW_IF_MSG(params, "search params not supported for this index");
60
59
  FAISS_THROW_IF_NOT(k > 0);
61
60
 
62
61
  constexpr idx_t bs = 32768;
@@ -24,7 +24,6 @@
24
24
  #include <faiss/impl/ResultHandler.h>
25
25
  #include <faiss/impl/VisitedTable.h>
26
26
  #include <faiss/utils/Heap.h>
27
- #include <faiss/utils/hamming.h>
28
27
  #include <faiss/utils/random.h>
29
28
 
30
29
  #include <faiss/impl/simd_dispatch.h>
@@ -36,7 +35,6 @@
36
35
  // NOLINTNEXTLINE(facebook-hte-InlineHeader)
37
36
  // NOLINTNEXTLINE(facebook-hte-InlineHeader)
38
37
  #include <faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h>
39
- #include <faiss/utils/hamming_distance/hamming_computer-generic.h>
40
38
  #undef THE_SIMD_LEVEL
41
39
 
42
40
  namespace faiss {
@@ -129,7 +127,7 @@ void hnsw_add_vertices(
129
127
 
130
128
  #pragma omp parallel
131
129
  {
132
- VisitedTable vt(ntotal);
130
+ std::unique_ptr<VisitedTable> vt = VisitedTable::create(ntotal);
133
131
 
134
132
  std::unique_ptr<DistanceComputer> dis(
135
133
  index_hnsw.get_distance_computer());
@@ -147,7 +145,7 @@ void hnsw_add_vertices(
147
145
  pt_level,
148
146
  pt_id,
149
147
  locks,
150
- vt,
148
+ *vt,
151
149
  index_hnsw.keep_max_size_level0 && (pt_level == 0));
152
150
 
153
151
  if (do_display && i - i0 > prev_display + 10000) {
@@ -237,7 +235,7 @@ void IndexBinaryHNSW::search(
237
235
 
238
236
  #pragma omp parallel
239
237
  {
240
- VisitedTable vt(ntotal);
238
+ std::unique_ptr<VisitedTable> vt = VisitedTable::create(ntotal);
241
239
  std::unique_ptr<DistanceComputer> dis(get_distance_computer());
242
240
  RH::SingleResultHandler res(bres);
243
241
 
@@ -249,7 +247,7 @@ void IndexBinaryHNSW::search(
249
247
  // as the index parameter. This state does not get used in the
250
248
  // search function, as it is merely there to enable Panorama
251
249
  // execution for IndexHNSWFlatPanorama.
252
- HNSWStats stats = hnsw.search(*dis, nullptr, res, vt, params_in);
250
+ HNSWStats stats = hnsw.search(*dis, nullptr, res, *vt, params_in);
253
251
  n1 += stats.n1;
254
252
  n2 += stats.n2;
255
253
  ndis += stats.ndis;
@@ -294,8 +292,8 @@ void IndexBinaryHNSW::reconstruct(idx_t key, uint8_t* recons) const {
294
292
 
295
293
  DistanceComputer* IndexBinaryHNSW::get_distance_computer() const {
296
294
  IndexBinaryFlat* flat_storage = dynamic_cast<IndexBinaryFlat*>(storage);
297
- FAISS_THROW_IF_NOT_MSG(
298
- flat_storage != nullptr,
295
+ FAISS_THROW_IF_MSG(
296
+ flat_storage == nullptr,
299
297
  "IndexBinaryHNSW requires IndexBinaryFlat storage");
300
298
  return with_simd_level([&]<SIMDLevel SL>() {
301
299
  return make_binary_hnsw_distance_computer_fixSL<SL>(
@@ -318,8 +316,8 @@ IndexBinaryHNSWCagra::IndexBinaryHNSWCagra(int d_, int M)
318
316
  }
319
317
 
320
318
  void IndexBinaryHNSWCagra::add(idx_t n, const uint8_t* x) {
321
- FAISS_THROW_IF_NOT_MSG(
322
- !base_level_only,
319
+ FAISS_THROW_IF_MSG(
320
+ base_level_only,
323
321
  "Cannot add vectors when base_level_only is set to True");
324
322
 
325
323
  IndexBinaryHNSW::add(n, x);
@@ -377,7 +375,7 @@ void IndexBinaryHNSWCagra::search(
377
375
 
378
376
  #pragma omp parallel
379
377
  {
380
- VisitedTable vt(ntotal);
378
+ std::unique_ptr<VisitedTable> vt = VisitedTable::create(ntotal);
381
379
  std::unique_ptr<DistanceComputer> dis(get_distance_computer());
382
380
  HNSWStats search_stats;
383
381
  RH::SingleResultHandler res(bres);
@@ -395,7 +393,7 @@ void IndexBinaryHNSWCagra::search(
395
393
  &nearest_d[i],
396
394
  1, // search_type
397
395
  search_stats,
398
- vt,
396
+ *vt,
399
397
  params);
400
398
 
401
399
  res.end();
@@ -27,7 +27,7 @@
27
27
  // NOLINTNEXTLINE(facebook-hte-InlineHeader)
28
28
  // NOLINTNEXTLINE(facebook-hte-InlineHeader)
29
29
  #include <faiss/impl/binary_hamming/IndexBinaryHash_impl.h>
30
- #include <faiss/utils/hamming_distance/hamming_computer-generic.h>
30
+ #include <faiss/utils/hamming_distance/hamming_computer-generic.h> // IWYU pragma: keep
31
31
  #undef THE_SIMD_LEVEL
32
32
 
33
33
  namespace faiss {
@@ -83,8 +83,7 @@ void IndexBinaryHash::range_search(
83
83
  int radius,
84
84
  RangeSearchResult* result,
85
85
  const SearchParameters* params) const {
86
- FAISS_THROW_IF_NOT_MSG(
87
- !params, "search params not supported for this index");
86
+ FAISS_THROW_IF_MSG(params, "search params not supported for this index");
88
87
  size_t nlist = 0, ndis = 0, n0 = 0;
89
88
 
90
89
  #pragma omp parallel if (n > 100) reduction(+ : ndis, n0, nlist)
@@ -116,8 +115,7 @@ void IndexBinaryHash::search(
116
115
  int32_t* distances,
117
116
  idx_t* labels,
118
117
  const SearchParameters* params) const {
119
- FAISS_THROW_IF_NOT_MSG(
120
- !params, "search params not supported for this index");
118
+ FAISS_THROW_IF_MSG(params, "search params not supported for this index");
121
119
  FAISS_THROW_IF_NOT(k > 0);
122
120
 
123
121
  using HeapForL2 = CMax<int32_t, idx_t>;
@@ -216,8 +214,7 @@ void IndexBinaryMultiHash::range_search(
216
214
  int radius,
217
215
  RangeSearchResult* result,
218
216
  const SearchParameters* params) const {
219
- FAISS_THROW_IF_NOT_MSG(
220
- !params, "search params not supported for this index");
217
+ FAISS_THROW_IF_MSG(params, "search params not supported for this index");
221
218
  size_t nlist = 0, ndis = 0, n0 = 0;
222
219
 
223
220
  #pragma omp parallel if (n > 100) reduction(+ : ndis, n0, nlist)
@@ -249,8 +246,7 @@ void IndexBinaryMultiHash::search(
249
246
  int32_t* distances,
250
247
  idx_t* labels,
251
248
  const SearchParameters* params) const {
252
- FAISS_THROW_IF_NOT_MSG(
253
- !params, "search params not supported for this index");
249
+ FAISS_THROW_IF_MSG(params, "search params not supported for this index");
254
250
  FAISS_THROW_IF_NOT(k > 0);
255
251
 
256
252
  using HeapForL2 = CMax<int32_t, idx_t>;
@@ -22,7 +22,6 @@
22
22
  #include <faiss/impl/AuxIndexStructures.h>
23
23
  #include <faiss/impl/FaissAssert.h>
24
24
  #include <faiss/utils/hamming.h>
25
- #include <faiss/utils/sorting.h>
26
25
  #include <faiss/utils/utils.h>
27
26
 
28
27
  #include <faiss/impl/simd_dispatch.h>
@@ -32,7 +31,6 @@
32
31
  // NOLINTNEXTLINE(facebook-hte-InlineHeader)
33
32
  // NOLINTNEXTLINE(facebook-hte-InlineHeader)
34
33
  #include <faiss/impl/binary_hamming/IndexBinaryIVF_impl.h>
35
- #include <faiss/utils/hamming_distance/hamming_computer-generic.h>
36
34
  #undef THE_SIMD_LEVEL
37
35
 
38
36
  namespace faiss {
@@ -208,8 +206,7 @@ void IndexBinaryIVF::search_and_reconstruct(
208
206
  idx_t* __restrict labels,
209
207
  uint8_t* __restrict recons,
210
208
  const SearchParameters* params) const {
211
- FAISS_THROW_IF_NOT_MSG(
212
- !params, "search params not supported for this index");
209
+ FAISS_THROW_IF_MSG(params, "search params not supported for this index");
213
210
  const size_t nprobe_2 = std::min(nlist, this->nprobe);
214
211
  FAISS_THROW_IF_NOT(k > 0);
215
212
  FAISS_THROW_IF_NOT(nprobe_2 > 0);
@@ -257,7 +254,9 @@ void IndexBinaryIVF::reconstruct_from_offset(
257
254
  idx_t list_no,
258
255
  idx_t offset,
259
256
  uint8_t* recons) const {
260
- memcpy(recons, invlists->get_single_code(list_no, offset), code_size);
257
+ memcpy(recons,
258
+ InvertedLists::ScopedCodes(invlists, list_no, offset).get(),
259
+ code_size);
261
260
  }
262
261
 
263
262
  void IndexBinaryIVF::reset() {
@@ -524,8 +523,7 @@ void IndexBinaryIVF::range_search(
524
523
  int radius,
525
524
  RangeSearchResult* __restrict res,
526
525
  const SearchParameters* params) const {
527
- FAISS_THROW_IF_NOT_MSG(
528
- !params, "search params not supported for this index");
526
+ FAISS_THROW_IF_MSG(params, "search params not supported for this index");
529
527
  const size_t nprobe_2 = std::min(nlist, this->nprobe);
530
528
  std::unique_ptr<idx_t[]> idx(new idx_t[n * nprobe_2]);
531
529
  std::unique_ptr<int32_t[]> coarse_dis(new int32_t[n * nprobe_2]);
@@ -0,0 +1,273 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #include <faiss/IndexEDEN.h>
9
+
10
+ #include <faiss/impl/FaissAssert.h>
11
+ #include <faiss/impl/ResultHandler.h>
12
+ #include <memory>
13
+
14
+ namespace faiss {
15
+
16
+ IndexEDEN::IndexEDEN() = default;
17
+
18
+ IndexEDEN::IndexEDEN(
19
+ idx_t d_in,
20
+ MetricType metric,
21
+ uint8_t nb_bits_in,
22
+ EDENScaleType scale_type_in)
23
+ : IndexFlatCodes(0, d_in, metric),
24
+ sq(d_in, eden_utils::quantizer_type_for_bits(nb_bits_in)),
25
+ scale_type(scale_type_in) {
26
+ FAISS_THROW_IF_NOT_MSG(
27
+ scale_type == EDENScaleType_UNBIASED ||
28
+ scale_type == EDENScaleType_BIASED,
29
+ "invalid EDEN scale type");
30
+ sq.train(0, nullptr);
31
+ code_size = eden_utils::code_size(d, sq.bits);
32
+ is_trained = false;
33
+ }
34
+
35
+ void IndexEDEN::train(idx_t n, const float* x) {
36
+ std::vector<float> centroid(d, 0.0f);
37
+ for (idx_t i = 0; i < n; i++) {
38
+ for (size_t j = 0; j < static_cast<size_t>(d); j++) {
39
+ centroid[j] += x[i * d + j];
40
+ }
41
+ }
42
+
43
+ if (n != 0) {
44
+ for (size_t j = 0; j < static_cast<size_t>(d); j++) {
45
+ centroid[j] /= static_cast<float>(n);
46
+ }
47
+ }
48
+
49
+ center = std::move(centroid);
50
+ sq.train(n, x);
51
+ is_trained = true;
52
+ }
53
+
54
+ void IndexEDEN::sa_encode(idx_t n, const float* x, uint8_t* bytes) const {
55
+ FAISS_THROW_IF_NOT(is_trained);
56
+ eden_utils::compute_codes(
57
+ sq, metric_type, scale_type, x, bytes, n, center.data());
58
+ }
59
+
60
+ void IndexEDEN::sa_decode(idx_t n, const uint8_t* bytes, float* x) const {
61
+ FAISS_THROW_IF_NOT(is_trained);
62
+ eden_utils::decode(sq, bytes, x, n, center.data());
63
+ }
64
+
65
+ FlatCodesDistanceComputer* IndexEDEN::get_FlatCodesDistanceComputer() const {
66
+ FlatCodesDistanceComputer* dc =
67
+ eden_utils::get_distance_computer(sq, metric_type, center.data());
68
+ dc->code_size = code_size;
69
+ dc->codes = codes.data();
70
+ return dc;
71
+ }
72
+
73
+ namespace {
74
+
75
+ bool use_eden_batch_scan(size_t d, size_t nb_bits) {
76
+ const size_t values_per_byte = 8 / nb_bits;
77
+ const size_t num_bytes = (d + values_per_byte - 1) / values_per_byte;
78
+ if (nb_bits == 1) {
79
+ return num_bytes >= 32;
80
+ }
81
+ if (nb_bits == 2) {
82
+ return num_bytes >= 16;
83
+ }
84
+ if (nb_bits == 4) {
85
+ return num_bytes >= 128;
86
+ }
87
+ return false;
88
+ }
89
+
90
+ struct Run_search_with_eden_dc {
91
+ using T = void;
92
+
93
+ template <class BlockResultHandler>
94
+ void f(BlockResultHandler& res, const IndexEDEN* index, const float* xq) {
95
+ const size_t ntotal = index->ntotal;
96
+ using SingleResultHandler =
97
+ typename BlockResultHandler::SingleResultHandler;
98
+ const int d = index->d;
99
+ const bool use_batch_scan = use_eden_batch_scan(d, index->sq.bits);
100
+
101
+ #pragma omp parallel
102
+ {
103
+ std::unique_ptr<EDENFlatCodesDistanceComputer> dc(
104
+ eden_utils::get_distance_computer(
105
+ index->sq,
106
+ index->metric_type,
107
+ index->center.data()));
108
+ dc->code_size = index->code_size;
109
+ dc->codes = index->codes.data();
110
+ SingleResultHandler resi(res);
111
+
112
+ #pragma omp for
113
+ for (int64_t q = 0; q < static_cast<int64_t>(res.nq); q++) {
114
+ resi.begin(q);
115
+ dc->set_query(xq + d * q);
116
+
117
+ if (use_batch_scan) {
118
+ size_t i = 0;
119
+ for (; i + 16 <= ntotal; i += 16) {
120
+ bool keep[16];
121
+ bool keep_all = true;
122
+ for (size_t j = 0; j < 16; j++) {
123
+ keep[j] = res.is_in_selection(i + j);
124
+ keep_all &= keep[j];
125
+ }
126
+
127
+ if (keep_all) {
128
+ float dis[16];
129
+ dc->consecutive_distances_batch_16(i, dis);
130
+ for (size_t j = 0; j < 16; j++) {
131
+ resi.add_result(dis[j], i + j);
132
+ }
133
+ } else {
134
+ for (size_t j = 0; j < 16; j++) {
135
+ if (keep[j]) {
136
+ resi.add_result((*dc)(i + j), i + j);
137
+ }
138
+ }
139
+ }
140
+ }
141
+ for (; i + 8 <= ntotal; i += 8) {
142
+ const bool keep0 = res.is_in_selection(i);
143
+ const bool keep1 = res.is_in_selection(i + 1);
144
+ const bool keep2 = res.is_in_selection(i + 2);
145
+ const bool keep3 = res.is_in_selection(i + 3);
146
+ const bool keep4 = res.is_in_selection(i + 4);
147
+ const bool keep5 = res.is_in_selection(i + 5);
148
+ const bool keep6 = res.is_in_selection(i + 6);
149
+ const bool keep7 = res.is_in_selection(i + 7);
150
+ if (keep0 && keep1 && keep2 && keep3 && keep4 &&
151
+ keep5 && keep6 && keep7) {
152
+ float dis[8];
153
+ dc->consecutive_distances_batch_8(i, dis);
154
+ resi.add_result(dis[0], i);
155
+ resi.add_result(dis[1], i + 1);
156
+ resi.add_result(dis[2], i + 2);
157
+ resi.add_result(dis[3], i + 3);
158
+ resi.add_result(dis[4], i + 4);
159
+ resi.add_result(dis[5], i + 5);
160
+ resi.add_result(dis[6], i + 6);
161
+ resi.add_result(dis[7], i + 7);
162
+ } else {
163
+ if (keep0) {
164
+ resi.add_result((*dc)(i), i);
165
+ }
166
+ if (keep1) {
167
+ resi.add_result((*dc)(i + 1), i + 1);
168
+ }
169
+ if (keep2) {
170
+ resi.add_result((*dc)(i + 2), i + 2);
171
+ }
172
+ if (keep3) {
173
+ resi.add_result((*dc)(i + 3), i + 3);
174
+ }
175
+ if (keep4) {
176
+ resi.add_result((*dc)(i + 4), i + 4);
177
+ }
178
+ if (keep5) {
179
+ resi.add_result((*dc)(i + 5), i + 5);
180
+ }
181
+ if (keep6) {
182
+ resi.add_result((*dc)(i + 6), i + 6);
183
+ }
184
+ if (keep7) {
185
+ resi.add_result((*dc)(i + 7), i + 7);
186
+ }
187
+ }
188
+ }
189
+ for (; i + 4 <= ntotal; i += 4) {
190
+ const bool keep0 = res.is_in_selection(i);
191
+ const bool keep1 = res.is_in_selection(i + 1);
192
+ const bool keep2 = res.is_in_selection(i + 2);
193
+ const bool keep3 = res.is_in_selection(i + 3);
194
+ if (keep0 && keep1 && keep2 && keep3) {
195
+ float dis0;
196
+ float dis1;
197
+ float dis2;
198
+ float dis3;
199
+ dc->distances_batch_4(
200
+ i,
201
+ i + 1,
202
+ i + 2,
203
+ i + 3,
204
+ dis0,
205
+ dis1,
206
+ dis2,
207
+ dis3);
208
+ resi.add_result(dis0, i);
209
+ resi.add_result(dis1, i + 1);
210
+ resi.add_result(dis2, i + 2);
211
+ resi.add_result(dis3, i + 3);
212
+ } else {
213
+ if (keep0) {
214
+ resi.add_result((*dc)(i), i);
215
+ }
216
+ if (keep1) {
217
+ resi.add_result((*dc)(i + 1), i + 1);
218
+ }
219
+ if (keep2) {
220
+ resi.add_result((*dc)(i + 2), i + 2);
221
+ }
222
+ if (keep3) {
223
+ resi.add_result((*dc)(i + 3), i + 3);
224
+ }
225
+ }
226
+ }
227
+ for (; i < ntotal; i++) {
228
+ if (res.is_in_selection(i)) {
229
+ resi.add_result((*dc)(i), i);
230
+ }
231
+ }
232
+ } else {
233
+ for (size_t i = 0; i < ntotal; i++) {
234
+ if (res.is_in_selection(i)) {
235
+ resi.add_result((*dc)(i), i);
236
+ }
237
+ }
238
+ }
239
+
240
+ resi.end();
241
+ }
242
+ }
243
+ }
244
+ };
245
+
246
+ } // namespace
247
+
248
+ void IndexEDEN::search(
249
+ idx_t n,
250
+ const float* x,
251
+ idx_t k,
252
+ float* distances,
253
+ idx_t* labels,
254
+ const SearchParameters* params) const {
255
+ FAISS_THROW_IF_NOT(is_trained);
256
+ const IDSelector* sel = params != nullptr ? params->sel : nullptr;
257
+ Run_search_with_eden_dc r;
258
+ dispatch_knn_ResultHandler(
259
+ n, distances, labels, k, metric_type, sel, r, this, x);
260
+ }
261
+
262
+ void IndexEDEN::range_search(
263
+ idx_t /*n*/,
264
+ const float* x,
265
+ float radius,
266
+ RangeSearchResult* result,
267
+ const SearchParameters* params) const {
268
+ const IDSelector* sel = params != nullptr ? params->sel : nullptr;
269
+ Run_search_with_eden_dc r;
270
+ dispatch_range_ResultHandler(result, radius, metric_type, sel, r, this, x);
271
+ }
272
+
273
+ } // namespace faiss