faiss 0.5.3 → 0.6.0

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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/ext/faiss/ext.cpp +1 -1
  4. data/ext/faiss/extconf.rb +5 -6
  5. data/ext/faiss/index_binary.cpp +38 -28
  6. data/ext/faiss/{index.cpp → index_rb.cpp} +64 -46
  7. data/ext/faiss/kmeans.cpp +10 -9
  8. data/ext/faiss/pca_matrix.cpp +10 -8
  9. data/ext/faiss/product_quantizer.cpp +14 -12
  10. data/ext/faiss/{utils.cpp → utils_rb.cpp} +5 -3
  11. data/ext/faiss/{utils.h → utils_rb.h} +4 -0
  12. data/lib/faiss/version.rb +1 -1
  13. data/lib/faiss.rb +1 -1
  14. data/vendor/faiss/faiss/AutoTune.cpp +130 -11
  15. data/vendor/faiss/faiss/AutoTune.h +14 -1
  16. data/vendor/faiss/faiss/Clustering.cpp +59 -10
  17. data/vendor/faiss/faiss/Clustering.h +12 -0
  18. data/vendor/faiss/faiss/IVFlib.cpp +31 -28
  19. data/vendor/faiss/faiss/Index.cpp +20 -8
  20. data/vendor/faiss/faiss/Index.h +25 -3
  21. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +19 -24
  22. data/vendor/faiss/faiss/IndexBinary.cpp +1 -0
  23. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +9 -4
  24. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +45 -11
  25. data/vendor/faiss/faiss/IndexFastScan.cpp +35 -22
  26. data/vendor/faiss/faiss/IndexFastScan.h +10 -1
  27. data/vendor/faiss/faiss/IndexFlat.cpp +193 -136
  28. data/vendor/faiss/faiss/IndexFlat.h +16 -1
  29. data/vendor/faiss/faiss/IndexFlatCodes.cpp +46 -22
  30. data/vendor/faiss/faiss/IndexFlatCodes.h +7 -1
  31. data/vendor/faiss/faiss/IndexHNSW.cpp +24 -50
  32. data/vendor/faiss/faiss/IndexHNSW.h +14 -12
  33. data/vendor/faiss/faiss/IndexIDMap.cpp +1 -1
  34. data/vendor/faiss/faiss/IndexIVF.cpp +76 -49
  35. data/vendor/faiss/faiss/IndexIVF.h +14 -4
  36. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +11 -8
  37. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +2 -2
  38. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +25 -14
  39. data/vendor/faiss/faiss/IndexIVFFastScan.h +26 -22
  40. data/vendor/faiss/faiss/IndexIVFFlat.cpp +10 -61
  41. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +39 -111
  42. data/vendor/faiss/faiss/IndexIVFPQ.cpp +89 -147
  43. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +37 -5
  44. data/vendor/faiss/faiss/IndexIVFPQR.cpp +2 -1
  45. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +42 -30
  46. data/vendor/faiss/faiss/IndexIVFRaBitQ.h +2 -2
  47. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +246 -97
  48. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +32 -29
  49. data/vendor/faiss/faiss/IndexLSH.cpp +8 -6
  50. data/vendor/faiss/faiss/IndexLattice.cpp +29 -24
  51. data/vendor/faiss/faiss/IndexNNDescent.cpp +1 -0
  52. data/vendor/faiss/faiss/IndexNSG.cpp +2 -1
  53. data/vendor/faiss/faiss/IndexNSG.h +0 -2
  54. data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +1 -1
  55. data/vendor/faiss/faiss/IndexPQ.cpp +19 -10
  56. data/vendor/faiss/faiss/IndexRaBitQ.cpp +26 -13
  57. data/vendor/faiss/faiss/IndexRaBitQ.h +2 -2
  58. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +132 -78
  59. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +14 -12
  60. data/vendor/faiss/faiss/IndexRefine.cpp +0 -30
  61. data/vendor/faiss/faiss/IndexShards.cpp +3 -4
  62. data/vendor/faiss/faiss/MetricType.h +16 -0
  63. data/vendor/faiss/faiss/VectorTransform.cpp +120 -0
  64. data/vendor/faiss/faiss/VectorTransform.h +23 -0
  65. data/vendor/faiss/faiss/clone_index.cpp +7 -4
  66. data/vendor/faiss/faiss/{cppcontrib/factory_tools.cpp → factory_tools.cpp} +1 -1
  67. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +1 -1
  68. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +37 -11
  69. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +0 -28
  70. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +367 -0
  71. data/vendor/faiss/faiss/impl/ClusteringInitialization.h +107 -0
  72. data/vendor/faiss/faiss/impl/CodePacker.cpp +4 -0
  73. data/vendor/faiss/faiss/impl/CodePacker.h +11 -3
  74. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +83 -0
  75. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.h +47 -0
  76. data/vendor/faiss/faiss/impl/FaissAssert.h +60 -2
  77. data/vendor/faiss/faiss/impl/HNSW.cpp +25 -34
  78. data/vendor/faiss/faiss/impl/HNSW.h +8 -6
  79. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +34 -27
  80. data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -1
  81. data/vendor/faiss/faiss/impl/NSG.cpp +6 -5
  82. data/vendor/faiss/faiss/impl/NSG.h +17 -7
  83. data/vendor/faiss/faiss/impl/Panorama.cpp +53 -46
  84. data/vendor/faiss/faiss/impl/Panorama.h +22 -6
  85. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +16 -5
  86. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +70 -58
  87. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +92 -0
  88. data/vendor/faiss/faiss/impl/RaBitQUtils.h +93 -31
  89. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +12 -28
  90. data/vendor/faiss/faiss/impl/RaBitQuantizer.h +3 -10
  91. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +15 -41
  92. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.h +0 -4
  93. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +14 -9
  94. data/vendor/faiss/faiss/impl/ResultHandler.h +131 -50
  95. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +67 -2358
  96. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +0 -2
  97. data/vendor/faiss/faiss/impl/VisitedTable.cpp +42 -0
  98. data/vendor/faiss/faiss/impl/VisitedTable.h +69 -0
  99. data/vendor/faiss/faiss/impl/expanded_scanners.h +158 -0
  100. data/vendor/faiss/faiss/impl/index_read.cpp +829 -471
  101. data/vendor/faiss/faiss/impl/index_read_utils.h +0 -1
  102. data/vendor/faiss/faiss/impl/index_write.cpp +17 -8
  103. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +47 -20
  104. data/vendor/faiss/faiss/impl/mapped_io.cpp +9 -2
  105. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +7 -2
  106. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +11 -3
  107. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +19 -13
  108. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +29 -21
  109. data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx2.h → pq_code_distance/pq_code_distance-avx2.cpp} +42 -215
  110. data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx512.h → pq_code_distance/pq_code_distance-avx512.cpp} +68 -107
  111. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +141 -0
  112. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +23 -0
  113. data/vendor/faiss/faiss/impl/{code_distance/code_distance-sve.h → pq_code_distance/pq_code_distance-sve.cpp} +57 -144
  114. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +9 -6
  115. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +121 -0
  116. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +136 -0
  117. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +280 -0
  118. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +164 -0
  119. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +94 -0
  120. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +455 -0
  121. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +430 -0
  122. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +329 -0
  123. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +467 -0
  124. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +203 -0
  125. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +42 -0
  126. data/vendor/faiss/faiss/impl/simd_dispatch.h +139 -0
  127. data/vendor/faiss/faiss/impl/simd_result_handlers.h +18 -18
  128. data/vendor/faiss/faiss/index_factory.cpp +35 -16
  129. data/vendor/faiss/faiss/index_io.h +29 -3
  130. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +7 -4
  131. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +1 -1
  132. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +9 -19
  133. data/vendor/faiss/faiss/svs/IndexSVSFlat.h +2 -0
  134. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +2 -1
  135. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +9 -1
  136. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +9 -0
  137. data/vendor/faiss/faiss/utils/Heap.cpp +46 -0
  138. data/vendor/faiss/faiss/utils/Heap.h +21 -0
  139. data/vendor/faiss/faiss/utils/NeuralNet.cpp +10 -7
  140. data/vendor/faiss/faiss/utils/distances.cpp +141 -23
  141. data/vendor/faiss/faiss/utils/distances.h +98 -0
  142. data/vendor/faiss/faiss/utils/distances_dispatch.h +170 -0
  143. data/vendor/faiss/faiss/utils/distances_simd.cpp +74 -3511
  144. data/vendor/faiss/faiss/utils/extra_distances-inl.h +164 -157
  145. data/vendor/faiss/faiss/utils/extra_distances.cpp +52 -95
  146. data/vendor/faiss/faiss/utils/extra_distances.h +47 -1
  147. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -1
  148. data/vendor/faiss/faiss/utils/partitioning.cpp +1 -1
  149. data/vendor/faiss/faiss/utils/pq_code_distance.h +251 -0
  150. data/vendor/faiss/faiss/utils/rabitq_simd.h +260 -0
  151. data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +150 -0
  152. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +568 -0
  153. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +153 -0
  154. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +1185 -0
  155. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +1092 -0
  156. data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +391 -0
  157. data/vendor/faiss/faiss/utils/simd_levels.cpp +322 -0
  158. data/vendor/faiss/faiss/utils/simd_levels.h +91 -0
  159. data/vendor/faiss/faiss/utils/simdlib_avx2.h +12 -1
  160. data/vendor/faiss/faiss/utils/simdlib_avx512.h +69 -0
  161. data/vendor/faiss/faiss/utils/simdlib_neon.h +6 -0
  162. data/vendor/faiss/faiss/utils/sorting.cpp +4 -4
  163. data/vendor/faiss/faiss/utils/utils.cpp +16 -9
  164. metadata +47 -18
  165. data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +0 -81
  166. data/vendor/faiss/faiss/impl/code_distance/code_distance.h +0 -186
  167. /data/vendor/faiss/faiss/{cppcontrib/factory_tools.h → factory_tools.h} +0 -0
@@ -21,7 +21,7 @@
21
21
  #include <faiss/impl/IDSelector.h>
22
22
 
23
23
  #include <faiss/impl/FaissAssert.h>
24
- #include <faiss/utils/distances.h>
24
+ #include <faiss/impl/expanded_scanners.h>
25
25
  #include <faiss/utils/extra_distances.h>
26
26
  #include <faiss/utils/utils.h>
27
27
 
@@ -147,7 +147,7 @@ void IndexIVFFlat::sa_decode(idx_t n, const uint8_t* bytes, float* x) const {
147
147
 
148
148
  namespace {
149
149
 
150
- template <typename VectorDistance, bool use_sel>
150
+ template <typename VectorDistance>
151
151
  struct IVFFlatScanner : InvertedListScanner {
152
152
  VectorDistance vd;
153
153
  using C = typename VectorDistance::C;
@@ -170,70 +170,18 @@ struct IVFFlatScanner : InvertedListScanner {
170
170
  this->list_no = list_no;
171
171
  }
172
172
 
173
- float distance_to_code(const uint8_t* code) const override {
173
+ float distance_to_code(const uint8_t* code) const final {
174
174
  const float* yj = (float*)code;
175
175
  return vd(xi, yj);
176
176
  }
177
177
 
178
+ // redefining the scan_codes allows to inline the distance_to_code
178
179
  size_t scan_codes(
179
180
  size_t list_size,
180
181
  const uint8_t* codes,
181
182
  const idx_t* ids,
182
- float* simi,
183
- idx_t* idxi,
184
- size_t k) const override {
185
- const float* list_vecs = (const float*)codes;
186
- size_t nup = 0;
187
- for (size_t j = 0; j < list_size; j++) {
188
- const float* yj = list_vecs + vd.d * j;
189
- if (use_sel && !sel->is_member(ids[j])) {
190
- continue;
191
- }
192
- float dis = vd(xi, yj);
193
- if (C::cmp(simi[0], dis)) {
194
- int64_t id = store_pairs ? lo_build(list_no, j) : ids[j];
195
- heap_replace_top<C>(k, simi, idxi, dis, id);
196
- nup++;
197
- }
198
- }
199
- return nup;
200
- }
201
-
202
- void scan_codes_range(
203
- size_t list_size,
204
- const uint8_t* codes,
205
- const idx_t* ids,
206
- float radius,
207
- RangeQueryResult& res) const override {
208
- const float* list_vecs = (const float*)codes;
209
- for (size_t j = 0; j < list_size; j++) {
210
- const float* yj = list_vecs + vd.d * j;
211
- if (use_sel && !sel->is_member(ids[j])) {
212
- continue;
213
- }
214
- float dis = vd(xi, yj);
215
- if (C::cmp(radius, dis)) {
216
- int64_t id = store_pairs ? lo_build(list_no, j) : ids[j];
217
- res.add(dis, id);
218
- }
219
- }
220
- }
221
- };
222
-
223
- struct Run_get_InvertedListScanner {
224
- using T = InvertedListScanner*;
225
-
226
- template <class VD>
227
- InvertedListScanner* f(
228
- VD& vd,
229
- const IndexIVFFlat* ivf,
230
- bool store_pairs,
231
- const IDSelector* sel) {
232
- if (sel) {
233
- return new IVFFlatScanner<VD, true>(vd, store_pairs, sel);
234
- } else {
235
- return new IVFFlatScanner<VD, false>(vd, store_pairs, sel);
236
- }
183
+ ResultHandler& handler) const {
184
+ return run_scan_codes_fix_C<C>(*this, list_size, codes, ids, handler);
237
185
  }
238
186
  };
239
187
 
@@ -243,9 +191,10 @@ InvertedListScanner* IndexIVFFlat::get_InvertedListScanner(
243
191
  bool store_pairs,
244
192
  const IDSelector* sel,
245
193
  const IVFSearchParameters*) const {
246
- Run_get_InvertedListScanner run;
247
- return dispatch_VectorDistance(
248
- d, metric_type, metric_arg, run, this, store_pairs, sel);
194
+ return with_VectorDistance(
195
+ d, metric_type, metric_arg, [&](auto vd) -> InvertedListScanner* {
196
+ return new IVFFlatScanner<decltype(vd)>(vd, store_pairs, sel);
197
+ });
249
198
  }
250
199
 
251
200
  void IndexIVFFlat::reconstruct_from_offset(
@@ -12,13 +12,14 @@
12
12
  #include <cstdio>
13
13
 
14
14
  #include <faiss/IndexFlat.h>
15
+ #include <faiss/MetricType.h>
15
16
 
16
17
  #include <faiss/impl/AuxIndexStructures.h>
17
18
  #include <faiss/impl/IDSelector.h>
18
19
  #include <faiss/impl/PanoramaStats.h>
20
+ #include <faiss/impl/ResultHandler.h>
19
21
 
20
22
  #include <faiss/impl/FaissAssert.h>
21
- #include <faiss/utils/distances.h>
22
23
  #include <faiss/utils/extra_distances.h>
23
24
  #include <faiss/utils/utils.h>
24
25
 
@@ -32,10 +33,7 @@ IndexIVFFlatPanorama::IndexIVFFlatPanorama(
32
33
  MetricType metric,
33
34
  bool own_invlists)
34
35
  : IndexIVFFlat(quantizer, d, nlist, metric, false), n_levels(n_levels) {
35
- // For now, we only support L2 distance.
36
- // Supporting dot product and cosine distance is a trivial addition
37
- // left for future work.
38
- FAISS_THROW_IF_NOT(metric == METRIC_L2);
36
+ FAISS_THROW_IF_NOT(metric == METRIC_L2 || metric == METRIC_INNER_PRODUCT);
39
37
 
40
38
  // We construct the inverted lists here so that we can use the
41
39
  // level-oriented storage. This does not cause a leak as we constructed
@@ -53,6 +51,7 @@ struct IVFFlatScannerPanorama : InvertedListScanner {
53
51
  VectorDistance vd;
54
52
  const ArrayInvertedListsPanorama* storage;
55
53
  using C = typename VectorDistance::C;
54
+ static constexpr MetricType metric = VectorDistance::metric;
56
55
 
57
56
  IVFFlatScannerPanorama(
58
57
  const VectorDistance& vd,
@@ -90,9 +89,7 @@ struct IVFFlatScannerPanorama : InvertedListScanner {
90
89
  size_t list_size,
91
90
  const uint8_t* codes,
92
91
  const idx_t* ids,
93
- float* simi,
94
- idx_t* idxi,
95
- size_t k) const override {
92
+ ResultHandler& handler) const override {
96
93
  size_t nup = 0;
97
94
 
98
95
  const size_t n_batches =
@@ -109,22 +106,22 @@ struct IVFFlatScannerPanorama : InvertedListScanner {
109
106
  for (size_t batch_no = 0; batch_no < n_batches; batch_no++) {
110
107
  size_t batch_start = batch_no * storage->kBatchSize;
111
108
 
112
- size_t num_active =
113
- storage->pano
114
- .progressive_filter_batch<CMax<float, int64_t>>(
115
- codes,
116
- cum_sums_data,
117
- xi,
118
- cum_sums.data(),
119
- batch_no,
120
- list_size,
121
- sel,
122
- ids,
123
- use_sel,
124
- active_indices,
125
- exact_distances,
126
- simi[0],
127
- local_stats);
109
+ size_t num_active = with_metric_type(metric, [&]<MetricType M>() {
110
+ return storage->pano.progressive_filter_batch<C, M>(
111
+ codes,
112
+ cum_sums_data,
113
+ xi,
114
+ cum_sums.data(),
115
+ batch_no,
116
+ list_size,
117
+ sel,
118
+ ids,
119
+ use_sel,
120
+ active_indices,
121
+ exact_distances,
122
+ handler.threshold,
123
+ local_stats);
124
+ });
128
125
 
129
126
  // Add batch survivors to heap.
130
127
  for (size_t i = 0; i < num_active; i++) {
@@ -132,10 +129,10 @@ struct IVFFlatScannerPanorama : InvertedListScanner {
132
129
  size_t global_idx = batch_start + idx;
133
130
  float dis = exact_distances[idx];
134
131
 
135
- if (C::cmp(simi[0], dis)) {
132
+ if (C::cmp(handler.threshold, dis)) {
136
133
  int64_t id = store_pairs ? lo_build(list_no, global_idx)
137
134
  : ids[global_idx];
138
- heap_replace_top<C>(k, simi, idxi, dis, id);
135
+ handler.add_result(dis, id);
139
136
  nup++;
140
137
  }
141
138
  }
@@ -144,88 +141,6 @@ struct IVFFlatScannerPanorama : InvertedListScanner {
144
141
  indexPanorama_stats.add(local_stats);
145
142
  return nup;
146
143
  }
147
-
148
- void scan_codes_range(
149
- size_t list_size,
150
- const uint8_t* codes,
151
- const idx_t* ids,
152
- float radius,
153
- RangeQueryResult& res) const override {
154
- const size_t n_batches =
155
- (list_size + storage->kBatchSize - 1) / storage->kBatchSize;
156
-
157
- const float* cum_sums_data = storage->get_cum_sums(list_no);
158
-
159
- std::vector<float> exact_distances(storage->kBatchSize);
160
- std::vector<uint32_t> active_indices(storage->kBatchSize);
161
-
162
- PanoramaStats local_stats;
163
- local_stats.reset();
164
-
165
- // Same progressive filtering as scan_codes, but with fixed radius
166
- // threshold instead of dynamic heap threshold.
167
- for (size_t batch_no = 0; batch_no < n_batches; batch_no++) {
168
- size_t batch_start = batch_no * storage->kBatchSize;
169
-
170
- size_t num_active =
171
- storage->pano
172
- .progressive_filter_batch<CMax<float, int64_t>>(
173
- codes,
174
- cum_sums_data,
175
- xi,
176
- cum_sums.data(),
177
- batch_no,
178
- list_size,
179
- sel,
180
- ids,
181
- use_sel,
182
- active_indices,
183
- exact_distances,
184
- radius,
185
- local_stats);
186
-
187
- // Add batch survivors to range result.
188
- for (size_t i = 0; i < num_active; i++) {
189
- uint32_t idx = active_indices[i];
190
- size_t global_idx = batch_start + idx;
191
- float dis = exact_distances[idx];
192
-
193
- if (C::cmp(radius, dis)) {
194
- int64_t id = store_pairs ? lo_build(list_no, global_idx)
195
- : ids[global_idx];
196
- res.add(dis, id);
197
- }
198
- }
199
- }
200
-
201
- indexPanorama_stats.add(local_stats);
202
- }
203
- };
204
-
205
- struct Run_get_InvertedListScanner {
206
- using T = InvertedListScanner*;
207
-
208
- template <class VD>
209
- InvertedListScanner* f(
210
- VD& vd,
211
- const IndexIVFFlatPanorama* ivf,
212
- bool store_pairs,
213
- const IDSelector* sel) {
214
- // Safely cast to ArrayInvertedListsPanorama to access cumulative sums.
215
- const ArrayInvertedListsPanorama* storage =
216
- dynamic_cast<const ArrayInvertedListsPanorama*>(ivf->invlists);
217
- FAISS_THROW_IF_NOT_MSG(
218
- storage,
219
- "IndexIVFFlatPanorama requires ArrayInvertedListsPanorama");
220
-
221
- if (sel) {
222
- return new IVFFlatScannerPanorama<VD, true>(
223
- vd, storage, store_pairs, sel);
224
- } else {
225
- return new IVFFlatScannerPanorama<VD, false>(
226
- vd, storage, store_pairs, sel);
227
- }
228
- }
229
144
  };
230
145
 
231
146
  } // anonymous namespace
@@ -234,9 +149,22 @@ InvertedListScanner* IndexIVFFlatPanorama::get_InvertedListScanner(
234
149
  bool store_pairs,
235
150
  const IDSelector* sel,
236
151
  const IVFSearchParameters*) const {
237
- Run_get_InvertedListScanner run;
238
- return dispatch_VectorDistance(
239
- d, metric_type, metric_arg, run, this, store_pairs, sel);
152
+ const ArrayInvertedListsPanorama* storage =
153
+ dynamic_cast<const ArrayInvertedListsPanorama*>(invlists);
154
+ FAISS_THROW_IF_NOT_MSG(
155
+ storage,
156
+ "IndexIVFFlatPanorama requires ArrayInvertedListsPanorama");
157
+
158
+ return with_VectorDistance(
159
+ d, metric_type, metric_arg, [&](auto vd) -> InvertedListScanner* {
160
+ if (sel) {
161
+ return new IVFFlatScannerPanorama<decltype(vd), true>(
162
+ vd, storage, store_pairs, sel);
163
+ } else {
164
+ return new IVFFlatScannerPanorama<decltype(vd), false>(
165
+ vd, storage, store_pairs, sel);
166
+ }
167
+ });
240
168
  }
241
169
 
242
170
  void IndexIVFFlatPanorama::reconstruct_from_offset(