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
@@ -9,6 +9,7 @@
9
9
 
10
10
  #include <faiss/impl/simdlib/simdlib_neon.h>
11
11
 
12
+ #include <algorithm>
12
13
  #include <cstring>
13
14
 
14
15
  #include <faiss/impl/scalar_quantizer/codecs.h>
@@ -180,6 +181,12 @@ struct QuantizerTemplate<
180
181
  xi.data.val[1],
181
182
  this->vdiff)});
182
183
  }
184
+
185
+ /// Raw codec decode without denormalization (for pre-decode opt)
186
+ FAISS_ALWAYS_INLINE simd8float32
187
+ decode_8_raw(const uint8_t* code, int i) const {
188
+ return Codec::decode_8_components(code, i);
189
+ }
183
190
  };
184
191
 
185
192
  template <class Codec>
@@ -216,41 +223,52 @@ struct QuantizerTemplate<
216
223
  };
217
224
 
218
225
  /**********************************************************
219
- * TurboQuant MSE quantizer
226
+ * Lloyd-Max scalar quantizer
220
227
  **********************************************************/
221
228
 
222
- #define DEFINE_TQMSE_NEON_SPECIALIZATION(NBITS, UNPACK_FN) \
223
- template <> \
224
- struct QuantizerTurboQuantMSE<NBITS, SIMDLevel::ARM_NEON> \
225
- : QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE> { \
226
- using Base = QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE>; \
227
- \
228
- QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained) \
229
- : Base(d, trained) { \
230
- assert(d % 8 == 0); \
231
- } \
232
- \
233
- FAISS_ALWAYS_INLINE simd8float32 \
234
- reconstruct_8_components(const uint8_t* code, int i) const { \
235
- uint8_t indices[8]; \
236
- UNPACK_FN(code, i, indices); \
237
- return gather_8_components(this->centroids, indices); \
238
- } \
239
- }
240
-
241
- DEFINE_TQMSE_NEON_SPECIALIZATION(1, unpack_8x1bit_to_u8);
242
- DEFINE_TQMSE_NEON_SPECIALIZATION(2, unpack_8x2bit_to_u8);
243
- DEFINE_TQMSE_NEON_SPECIALIZATION(3, unpack_8x3bit_to_u8);
244
- DEFINE_TQMSE_NEON_SPECIALIZATION(4, unpack_8x4bit_to_u8);
245
-
246
- #undef DEFINE_TQMSE_NEON_SPECIALIZATION
229
+ // NEON Lloyd-Max: decode via gather, encode stays scalar.
230
+ // NEON doesn't have movemask so 1-bit encode is also scalar.
231
+ #define DEFINE_LLOYD_MAX_NEON_SPECIALIZATION(NBITS, UNPACK_FN) \
232
+ template <> \
233
+ struct QuantizerLloydMax<NBITS, SIMDLevel::ARM_NEON> \
234
+ : QuantizerLloydMax<NBITS, SIMDLevel::NONE> { \
235
+ using Base = QuantizerLloydMax<NBITS, SIMDLevel::NONE>; \
236
+ \
237
+ QuantizerLloydMax(size_t d, const std::vector<float>& trained) \
238
+ : Base(d, trained) { \
239
+ assert(d % 8 == 0); \
240
+ } \
241
+ \
242
+ FAISS_ALWAYS_INLINE simd8float32 \
243
+ reconstruct_8_components(const uint8_t* code, int i) const { \
244
+ uint8_t indices[8]; \
245
+ UNPACK_FN(code, i, indices); \
246
+ return gather_8_components(this->centroids, indices); \
247
+ } \
248
+ \
249
+ void decode_vector(const uint8_t* code, float* x) const final { \
250
+ for (size_t i = 0; i < this->d; i += 8) { \
251
+ simd8float32 xi = \
252
+ reconstruct_8_components(code, static_cast<int>(i)); \
253
+ vst1q_f32(x + i, xi.data.val[0]); \
254
+ vst1q_f32(x + i + 4, xi.data.val[1]); \
255
+ } \
256
+ } \
257
+ }
258
+
259
+ DEFINE_LLOYD_MAX_NEON_SPECIALIZATION(1, unpack_8x1bit_to_u8);
260
+ DEFINE_LLOYD_MAX_NEON_SPECIALIZATION(2, unpack_8x2bit_to_u8);
261
+ DEFINE_LLOYD_MAX_NEON_SPECIALIZATION(3, unpack_8x3bit_to_u8);
262
+ DEFINE_LLOYD_MAX_NEON_SPECIALIZATION(4, unpack_8x4bit_to_u8);
263
+
264
+ #undef DEFINE_LLOYD_MAX_NEON_SPECIALIZATION
247
265
 
248
266
  template <>
249
- struct QuantizerTurboQuantMSE<8, SIMDLevel::ARM_NEON>
250
- : QuantizerTurboQuantMSE<8, SIMDLevel::NONE> {
251
- using Base = QuantizerTurboQuantMSE<8, SIMDLevel::NONE>;
267
+ struct QuantizerLloydMax<8, SIMDLevel::ARM_NEON>
268
+ : QuantizerLloydMax<8, SIMDLevel::NONE> {
269
+ using Base = QuantizerLloydMax<8, SIMDLevel::NONE>;
252
270
 
253
- QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained)
271
+ QuantizerLloydMax(size_t d, const std::vector<float>& trained)
254
272
  : Base(d, trained) {
255
273
  assert(d % 8 == 0);
256
274
  }
@@ -261,6 +279,15 @@ struct QuantizerTurboQuantMSE<8, SIMDLevel::ARM_NEON>
261
279
  std::memcpy(indices, code + static_cast<size_t>(i), sizeof(indices));
262
280
  return gather_8_components(this->centroids, indices);
263
281
  }
282
+
283
+ void decode_vector(const uint8_t* code, float* x) const final {
284
+ for (size_t i = 0; i < this->d; i += 8) {
285
+ simd8float32 xi =
286
+ reconstruct_8_components(code, static_cast<int>(i));
287
+ vst1q_f32(x + i, xi.data.val[0]);
288
+ vst1q_f32(x + i + 4, xi.data.val[1]);
289
+ }
290
+ }
264
291
  };
265
292
 
266
293
  /**********************************************************
@@ -397,6 +424,22 @@ struct SimilarityL2<SIMDLevel::ARM_NEON> {
397
424
  FAISS_ALWAYS_INLINE float result_8() {
398
425
  return horizontal_add(accu8);
399
426
  }
427
+
428
+ static void adjust_query_for_raw_decode(
429
+ const float* x,
430
+ float* q_adj,
431
+ size_t d,
432
+ float vmin,
433
+ float vdiff,
434
+ float& scale_factor,
435
+ float& bias) {
436
+ float inv_vdiff = (vdiff != 0) ? 1.0f / vdiff : 0.0f;
437
+ for (size_t i = 0; i < d; i++) {
438
+ q_adj[i] = (x[i] - vmin) * inv_vdiff;
439
+ }
440
+ scale_factor = vdiff * vdiff;
441
+ bias = 0;
442
+ }
400
443
  };
401
444
 
402
445
  template <>
@@ -431,6 +474,23 @@ struct SimilarityIP<SIMDLevel::ARM_NEON> {
431
474
  FAISS_ALWAYS_INLINE float result_8() {
432
475
  return horizontal_add(accu8);
433
476
  }
477
+
478
+ static void adjust_query_for_raw_decode(
479
+ const float* x,
480
+ float* q_adj,
481
+ size_t d,
482
+ float vmin,
483
+ float vdiff,
484
+ float& scale_factor,
485
+ float& bias) {
486
+ float sum_q = 0;
487
+ for (size_t i = 0; i < d; i++) {
488
+ q_adj[i] = x[i];
489
+ sum_q += x[i];
490
+ }
491
+ scale_factor = vdiff;
492
+ bias = vmin * sum_q;
493
+ }
434
494
  };
435
495
 
436
496
  /**********************************************************
@@ -444,8 +504,23 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::ARM_NEON>
444
504
 
445
505
  Quantizer quant;
446
506
 
507
+ // Pre-adjusted query buffer for uniform quantizers
508
+ std::vector<float> q_adj;
509
+ float scale_factor = 0;
510
+ float bias = 0;
511
+
512
+ static constexpr bool has_decode_raw() {
513
+ return requires(const Quantizer& q, const uint8_t* c, int i) {
514
+ { q.decode_8_raw(c, i) };
515
+ };
516
+ }
517
+
447
518
  DCTemplate(size_t d, const std::vector<float>& trained)
448
- : quant(d, trained) {}
519
+ : quant(d, trained) {
520
+ if constexpr (has_decode_raw()) {
521
+ q_adj.resize(d);
522
+ }
523
+ }
449
524
 
450
525
  float compute_distance(const float* x, const uint8_t* code) const {
451
526
  Similarity sim(x);
@@ -471,6 +546,26 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::ARM_NEON>
471
546
 
472
547
  void set_query(const float* x) final {
473
548
  q = x;
549
+ if constexpr (has_decode_raw()) {
550
+ Sim::adjust_query_for_raw_decode(
551
+ x,
552
+ q_adj.data(),
553
+ quant.d,
554
+ quant.vmin,
555
+ quant.vdiff,
556
+ scale_factor,
557
+ bias);
558
+ }
559
+ }
560
+
561
+ float query_to_code_predecoded(const uint8_t* code) const {
562
+ Similarity sim(q_adj.data());
563
+ sim.begin_8();
564
+ for (size_t i = 0; i < quant.d; i += 8) {
565
+ simd8float32 xi = quant.decode_8_raw(code, i);
566
+ sim.add_8_components(xi);
567
+ }
568
+ return bias + scale_factor * sim.result_8();
474
569
  }
475
570
 
476
571
  float symmetric_dis(idx_t i, idx_t j) override {
@@ -479,7 +574,11 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::ARM_NEON>
479
574
  }
480
575
 
481
576
  float query_to_code(const uint8_t* code) const final {
482
- return compute_distance(q, code);
577
+ if constexpr (has_decode_raw()) {
578
+ return query_to_code_predecoded(code);
579
+ } else {
580
+ return compute_distance(q, code);
581
+ }
483
582
  }
484
583
 
485
584
  void query_to_codes_batch_4(
@@ -564,6 +663,32 @@ struct DistanceComputerByte<Similarity, SIMDLevel::ARM_NEON>
564
663
  }
565
664
  };
566
665
 
666
+ /**********************************************************
667
+ * TurboQuant masked_sum NEON specialization (scalar fallback)
668
+ **********************************************************/
669
+
670
+ template <SIMDLevel SL0>
671
+ float turboq_masked_sum(const float* arr, const uint8_t* bits, size_t d);
672
+
673
+ template <>
674
+ float turboq_masked_sum<SIMDLevel::ARM_NEON>(
675
+ const float* arr,
676
+ const uint8_t* bits,
677
+ size_t d) {
678
+ float result = 0;
679
+ for (size_t byte_idx = 0; byte_idx < (d + 7) / 8; byte_idx++) {
680
+ uint8_t b = bits[byte_idx];
681
+ size_t base = byte_idx * 8;
682
+ size_t end = std::min(base + 8, d);
683
+ for (size_t j = base; j < end; j++) {
684
+ if (b & (1 << (j - base))) {
685
+ result += arr[j];
686
+ }
687
+ }
688
+ }
689
+ return result;
690
+ }
691
+
567
692
  } // namespace scalar_quantizer
568
693
  } // namespace faiss
569
694
 
@@ -302,6 +302,32 @@ struct DCTemplate<
302
302
  }
303
303
  };
304
304
 
305
+ /**********************************************************
306
+ * TurboQuant masked_sum RVV specialization (scalar fallback)
307
+ **********************************************************/
308
+
309
+ template <SIMDLevel SL0>
310
+ float turboq_masked_sum(const float* arr, const uint8_t* bits, size_t d);
311
+
312
+ template <>
313
+ float turboq_masked_sum<SIMDLevel::RISCV_RVV>(
314
+ const float* arr,
315
+ const uint8_t* bits,
316
+ size_t d) {
317
+ float result = 0;
318
+ for (size_t byte_idx = 0; byte_idx < (d + 7) / 8; byte_idx++) {
319
+ uint8_t b = bits[byte_idx];
320
+ size_t base = byte_idx * 8;
321
+ size_t end = std::min(base + 8, d);
322
+ for (size_t j = base; j < end; j++) {
323
+ if (b & (1 << (j - base))) {
324
+ result += arr[j];
325
+ }
326
+ }
327
+ }
328
+ return result;
329
+ }
330
+
305
331
  } // namespace scalar_quantizer
306
332
  } // namespace faiss
307
333
 
@@ -36,6 +36,12 @@ constexpr int AVAILABLE_SIMD_LEVELS_AVX2_NEON = AVAILABLE_SIMD_LEVELS_NONE |
36
36
  constexpr int AVAILABLE_SIMD_LEVELS_A0 = AVAILABLE_SIMD_LEVELS_AVX2_NEON |
37
37
  (1 << int(SIMDLevel::AVX512)) | (1 << int(SIMDLevel::RISCV_RVV));
38
38
 
39
+ // A0_SPR: same as A0 + AVX512_SPR (for functions with a dedicated SPR
40
+ // specialization on top of an AVX512 fallback). Currently used by the
41
+ // RaBitQ popcount kernels, which use VPOPCNTDQ on SPR+.
42
+ constexpr int AVAILABLE_SIMD_LEVELS_A0_SPR =
43
+ AVAILABLE_SIMD_LEVELS_A0 | (1 << int(SIMDLevel::AVX512_SPR));
44
+
39
45
  // A1: same + ARM_SVE (for functions with dedicated SVE implementations)
40
46
  constexpr int AVAILABLE_SIMD_LEVELS_A1 =
41
47
  AVAILABLE_SIMD_LEVELS_A0 | (1 << int(SIMDLevel::ARM_SVE));
@@ -47,6 +53,55 @@ constexpr int AVAILABLE_SIMD_LEVELS_A2 = AVAILABLE_SIMD_LEVELS_NONE |
47
53
 
48
54
  constexpr int AVAILABLE_SIMD_LEVELS_ALL = -1;
49
55
 
56
+ constexpr SIMDLevel get_simd_fallback(SIMDLevel level) {
57
+ switch (level) {
58
+ case SIMDLevel::AVX512_SPR:
59
+ return SIMDLevel::AVX512;
60
+ case SIMDLevel::AVX512:
61
+ return SIMDLevel::AVX2;
62
+ case SIMDLevel::ARM_SVE:
63
+ return SIMDLevel::ARM_NEON;
64
+ case SIMDLevel::AVX2:
65
+ case SIMDLevel::ARM_NEON:
66
+ case SIMDLevel::RISCV_RVV:
67
+ return SIMDLevel::NONE;
68
+ default:
69
+ return SIMDLevel::NONE;
70
+ }
71
+ }
72
+
73
+ template <int available_levels, SIMDLevel current_level, typename LambdaType>
74
+ inline auto dispatch_with_fallback(LambdaType&& action) {
75
+ if constexpr (available_levels & (1 << int(current_level))) {
76
+ return action.template operator()<current_level>();
77
+ } else if constexpr (current_level != SIMDLevel::NONE) {
78
+ return dispatch_with_fallback<
79
+ available_levels,
80
+ get_simd_fallback(current_level)>(
81
+ std::forward<LambdaType>(action));
82
+ } else {
83
+ return action.template operator()<SIMDLevel::NONE>();
84
+ }
85
+ }
86
+
87
+ /** Run action at current_level; on a null result, retry the next-lower level,
88
+ * down to NONE (terminal). action is called per level tried, so never moved. */
89
+ template <int available_levels, SIMDLevel current_level, typename LambdaType>
90
+ inline auto dispatch_simd_level_or_lower(LambdaType& action) {
91
+ if constexpr (current_level == SIMDLevel::NONE) {
92
+ return action.template operator()<SIMDLevel::NONE>();
93
+ } else {
94
+ if constexpr (available_levels & (1 << int(current_level))) {
95
+ if (auto result = action.template operator()<current_level>()) {
96
+ return result;
97
+ }
98
+ }
99
+ return dispatch_simd_level_or_lower<
100
+ available_levels,
101
+ get_simd_fallback(current_level)>(action);
102
+ }
103
+ }
104
+
50
105
  /** The complete dispatching function. It takes into account:
51
106
  * - the currently selected SIMD level
52
107
  * - the compiled in SIMD levels (given by COMPILE_SIMD_XXX)
@@ -114,17 +169,30 @@ inline auto with_selected_simd_levels(LambdaType&& action) {
114
169
  }
115
170
  #else // static dispatch
116
171
  // In static mode, SINGLE_SIMD_LEVEL is a constexpr resolved at compile
117
- // time. If the compiled level is not in the available set, fall through
118
- // to NONE (mirroring the DD fallthrough behavior). Only SINGLE_SIMD_LEVEL
119
- // and NONE have compiled specializations.
120
- if constexpr (available_levels & (1 << int(SINGLE_SIMD_LEVEL))) {
121
- return action.template operator()<SINGLE_SIMD_LEVEL>();
122
- } else {
123
- return action.template operator()<SIMDLevel::NONE>();
124
- }
172
+ // time. We mirror the DD fallthrough behavior at compile time via
173
+ // dispatch_with_fallback, which recursively walks get_simd_fallback:
174
+ // x86: AVX512_SPR -> AVX512 -> AVX2 -> NONE
175
+ // ARM: ARM_SVE -> ARM_NEON -> NONE
176
+ // RISCV: RISCV_RVV -> NONE
177
+ // The first level in the chain that appears in available_levels is
178
+ // selected; if none match, NONE is used unconditionally.
179
+ return dispatch_with_fallback<available_levels, SINGLE_SIMD_LEVEL>(
180
+ std::forward<LambdaType>(action));
125
181
  #endif
126
182
  }
127
183
 
184
+ /** Like with_selected_simd_levels, but for factory actions that return null to
185
+ * decline a level (e.g. AVX-512 needing d % 16 == 0). Falls back to the next
186
+ * lower level, down to NONE. */
187
+ template <int available_levels, typename LambdaType>
188
+ inline auto with_simd_level_fallback(const LambdaType& action) {
189
+ return with_selected_simd_levels<available_levels>(
190
+ [&action]<SIMDLevel SL>() {
191
+ return dispatch_simd_level_or_lower<available_levels, SL>(
192
+ action);
193
+ });
194
+ }
195
+
128
196
  /**
129
197
  * Dispatch to a lambda with SIMDLevel as a compile-time constant.
130
198
  *
@@ -170,4 +238,14 @@ inline auto with_simd_level_256bit(LambdaType&& action) {
170
238
  std::forward<LambdaType>(action));
171
239
  }
172
240
 
241
+ /**
242
+ * Use for functions that have A0-level implementations plus an AVX512_SPR
243
+ * specialization (e.g. using VPOPCNTDQ).
244
+ */
245
+ template <typename LambdaType>
246
+ inline auto with_simd_level_a0_spr(LambdaType&& action) {
247
+ return with_selected_simd_levels<AVAILABLE_SIMD_LEVELS_A0_SPR>(
248
+ std::forward<LambdaType>(action));
249
+ }
250
+
173
251
  } // namespace faiss
@@ -21,11 +21,13 @@
21
21
  #include <faiss/Index2Layer.h>
22
22
  #include <faiss/IndexAdditiveQuantizer.h>
23
23
  #include <faiss/IndexAdditiveQuantizerFastScan.h>
24
+ #include <faiss/IndexEDEN.h>
24
25
  #include <faiss/IndexFlat.h>
25
26
  #include <faiss/IndexHNSW.h>
26
27
  #include <faiss/IndexIVF.h>
27
28
  #include <faiss/IndexIVFAdditiveQuantizer.h>
28
29
  #include <faiss/IndexIVFAdditiveQuantizerFastScan.h>
30
+ #include <faiss/IndexIVFEDEN.h>
29
31
  #include <faiss/IndexIVFFlat.h>
30
32
  #include <faiss/IndexIVFFlatPanorama.h>
31
33
  #include <faiss/IndexIVFPQ.h>
@@ -168,9 +170,13 @@ std::map<std::string, ScalarQuantizer::QuantizerType> sq_types = {
168
170
  {"SQtqmse3", ScalarQuantizer::QT_3bit_tqmse},
169
171
  {"SQtqmse4", ScalarQuantizer::QT_4bit_tqmse},
170
172
  {"SQtqmse8", ScalarQuantizer::QT_8bit_tqmse},
173
+ {"SQtq2", ScalarQuantizer::QT_2bit_tq},
174
+ {"SQtq3", ScalarQuantizer::QT_3bit_tq},
175
+ {"SQtq4", ScalarQuantizer::QT_4bit_tq},
176
+ {"SQtq5", ScalarQuantizer::QT_5bit_tq},
171
177
  };
172
178
  const std::string sq_pattern =
173
- "(SQ0|SQ4|SQ8|SQ6|SQfp16|SQbf16|SQ8_direct_signed|SQ8_direct|SQtqmse1|SQtqmse2|SQtqmse3|SQtqmse4|SQtqmse8)";
179
+ "(SQ0|SQ4|SQ8|SQ6|SQfp16|SQbf16|SQ8_direct_signed|SQ8_direct|SQtqmse1|SQtqmse2|SQtqmse3|SQtqmse4|SQtqmse8|SQtq2|SQtq3|SQtq4|SQtq5)";
174
180
 
175
181
  std::map<std::string, AdditiveQuantizer::Search_type_t> aq_search_type = {
176
182
  {"_Nfloat", AdditiveQuantizer::ST_norm_float},
@@ -311,8 +317,8 @@ Index* parse_coarse_quantizer(
311
317
  SVSStorageKind storage = SVSStorageKind::SVS_FP32;
312
318
  if (sm[3].matched) {
313
319
  std::string s = sm[3].str().substr(1);
314
- if (s == "SQI8") {
315
- storage = SVSStorageKind::SVS_SQI8;
320
+ if (s == "SQ8") {
321
+ storage = SVSStorageKind::SVS_SQ8;
316
322
  } else if (s == "FP16") {
317
323
  storage = SVSStorageKind::SVS_FP16;
318
324
  } else if (s == "FP32") {
@@ -510,6 +516,18 @@ IndexIVF* parse_IndexIVF(
510
516
  uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
511
517
  return new IndexIVFRaBitQ(get_q(), d, nlist, mt, own_il, nb_bits);
512
518
  }
519
+ // IndexIVFEDEN with optional nb_bits (1-8) and scale type.
520
+ // Accepts: "EDEN" (default 1-bit), "EDEN{nb_bits}" (e.g., "EDEN4"),
521
+ // or "EDEN{nb_bits}BIASED" for the MSE-minimizing scale.
522
+ if (match("EDEN([1-8])?(BIASED|BIAS)?")) {
523
+ uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
524
+ EDENScaleType scale_type =
525
+ sm[2].str() == "BIASED" || sm[2].str() == "BIAS"
526
+ ? EDENScaleType_BIASED
527
+ : EDENScaleType_UNBIASED;
528
+ return new IndexIVFEDEN(
529
+ get_q(), d, nlist, mt, own_il, nb_bits, scale_type);
530
+ }
513
531
  // Accepts: "RaBitQfs" (default 1-bit, batch size 32)
514
532
  // "RaBitQfs{nb_bits}" (e.g., "RaBitQfs4")
515
533
  // "RaBitQfs_64" (1-bit, batch size 64)
@@ -677,16 +695,16 @@ Index* parse_svs_datatype(
677
695
  }
678
696
  FAISS_ASSERT(false && "Unsupported SVS index type for Float16");
679
697
  }
680
- if (re_match(datatype_string, "SQI8", sm)) {
698
+ if (re_match(datatype_string, "SQ8", sm)) {
681
699
  if (index_type == "Vamana") {
682
700
  return new IndexSVSVamana(
683
- d, std::stoul(arg_string), mt, SVSStorageKind::SVS_SQI8);
701
+ d, std::stoul(arg_string), mt, SVSStorageKind::SVS_SQ8);
684
702
  }
685
703
  if (index_type == "IVF") {
686
704
  return new IndexSVSIVF(
687
- d, std::stoul(arg_string), mt, SVSStorageKind::SVS_SQI8);
705
+ d, std::stoul(arg_string), mt, SVSStorageKind::SVS_SQ8);
688
706
  }
689
- FAISS_ASSERT(false && "Unsupported SVS index type for SQI8");
707
+ FAISS_ASSERT(false && "Unsupported SVS index type for SQ8");
690
708
  }
691
709
  if (re_match(datatype_string, "(LVQ[0-9]+x[0-9]+)", sm)) {
692
710
  if (index_type == "Vamana") {
@@ -913,6 +931,18 @@ Index* parse_other_indexes(
913
931
  return new IndexRaBitQ(d, metric, nb_bits);
914
932
  }
915
933
 
934
+ // IndexEDEN with optional nb_bits (1-8) and scale type.
935
+ // Accepts: "EDEN" (default 1-bit), "EDEN{nb_bits}" (e.g., "EDEN4"),
936
+ // or "EDEN{nb_bits}BIASED" for the MSE-minimizing scale.
937
+ if (match("EDEN([1-8])?(BIASED|BIAS)?")) {
938
+ uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
939
+ EDENScaleType scale_type =
940
+ sm[2].str() == "BIASED" || sm[2].str() == "BIAS"
941
+ ? EDENScaleType_BIASED
942
+ : EDENScaleType_UNBIASED;
943
+ return new IndexEDEN(d, metric, nb_bits, scale_type);
944
+ }
945
+
916
946
  if (match("RaBitQfs([1-9])?(_[0-9]+)?")) {
917
947
  uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
918
948
  int bbs = mres_to_int(sm[2], 32, 1);
@@ -137,6 +137,22 @@ size_t get_deserialization_vector_byte_limit();
137
137
  // and do not modify while deserialization is in progress on other threads.
138
138
  void set_deserialization_vector_byte_limit(size_t value);
139
139
 
140
+ // Returns the current IndexLattice r2 limit for deserialization.
141
+ // When nonzero, deserialization rejects IndexLattice payloads whose
142
+ // r2 (squared lattice radius) exceeds this value. The
143
+ // ZnSphereCodecRec constructor that runs at IndexLattice deserialize
144
+ // time builds a decode cache whose population cost scales
145
+ // polynomially in r2 and dim, and can exceed real-world workload time
146
+ // budgets even for r2 values that do not trip the existing
147
+ // decode-cache memory cap.
148
+ // Default: 0 (no limit).
149
+ size_t get_deserialization_lattice_r2_limit();
150
+
151
+ // Sets the IndexLattice r2 deserialization limit.
152
+ // NOT thread-safe: set before any concurrent deserialization calls
153
+ // and do not modify while deserialization is in progress on other threads.
154
+ void set_deserialization_lattice_r2_limit(size_t value);
155
+
140
156
  } // namespace faiss
141
157
 
142
158
  #endif
@@ -80,7 +80,7 @@ idx_t DirectMap::get(idx_t key) const {
80
80
  return lo;
81
81
  } else if (type == Hashtable) {
82
82
  auto res = hashtable.find(key);
83
- FAISS_THROW_IF_NOT_MSG(res != hashtable.end(), "key not found");
83
+ FAISS_THROW_IF_MSG(res == hashtable.end(), "key not found");
84
84
  return res->second;
85
85
  } else {
86
86
  FAISS_THROW_MSG("direct map not initialized");
@@ -254,7 +254,10 @@ void DirectMap::update_codes(
254
254
  int64_t id2 = invlists->get_single_id(il, l - 1);
255
255
  array[id2] = lo_build(il, ofs);
256
256
  invlists->update_entry(
257
- il, ofs, id2, invlists->get_single_code(il, l - 1));
257
+ il,
258
+ ofs,
259
+ id2,
260
+ InvertedLists::ScopedCodes(invlists, il, l - 1).get());
258
261
  }
259
262
  invlists->resize(il, l - 1);
260
263
  }
@@ -371,8 +371,8 @@ ArrayInvertedListsPanorama::ArrayInvertedListsPanorama(
371
371
  pano(code_size_in, n_levels_in, batch_size) {
372
372
  FAISS_THROW_IF_NOT(n_levels_in > 0);
373
373
  FAISS_THROW_IF_NOT(code_size_in % sizeof(float) == 0);
374
- FAISS_THROW_IF_NOT_MSG(
375
- !use_iterator,
374
+ FAISS_THROW_IF_MSG(
375
+ use_iterator,
376
376
  "IndexIVFFlatPanorama does not support iterators, use vanilla IndexIVFFlat instead");
377
377
  FAISS_ASSERT(level_width % sizeof(float) == 0);
378
378
 
@@ -498,12 +498,12 @@ void ReadOnlyInvertedLists::resize(size_t, size_t) {
498
498
  * HStackInvertedLists implementation
499
499
  ******************************************/
500
500
 
501
- HStackInvertedLists::HStackInvertedLists(int nil, const InvertedLists** ils_in)
501
+ HStackInvertedLists::HStackInvertedLists(int n_il, const InvertedLists** ils_in)
502
502
  : ReadOnlyInvertedLists(
503
- nil > 0 ? ils_in[0]->nlist : 0,
504
- nil > 0 ? ils_in[0]->code_size : 0) {
505
- FAISS_THROW_IF_NOT(nil > 0);
506
- for (int i = 0; i < nil; i++) {
503
+ n_il > 0 ? ils_in[0]->nlist : 0,
504
+ n_il > 0 ? ils_in[0]->code_size : 0) {
505
+ FAISS_THROW_IF_NOT(n_il > 0);
506
+ for (int i = 0; i < n_il; i++) {
507
507
  ils.push_back(ils_in[i]);
508
508
  FAISS_THROW_IF_NOT(
509
509
  ils_in[i]->code_size == code_size && ils_in[i]->nlist == nlist);
@@ -683,9 +683,9 @@ int translate_list_no(const VStackInvertedLists* vil, idx_t list_no) {
683
683
  return i0;
684
684
  }
685
685
 
686
- idx_t sum_il_sizes(int nil, const InvertedLists** ils_in) {
686
+ idx_t sum_il_sizes(int n_il, const InvertedLists** ils_in) {
687
687
  idx_t tot = 0;
688
- for (int i = 0; i < nil; i++) {
688
+ for (int i = 0; i < n_il; i++) {
689
689
  tot += ils_in[i]->nlist;
690
690
  }
691
691
  return tot;
@@ -693,13 +693,13 @@ idx_t sum_il_sizes(int nil, const InvertedLists** ils_in) {
693
693
 
694
694
  } // namespace
695
695
 
696
- VStackInvertedLists::VStackInvertedLists(int nil, const InvertedLists** ils_in)
696
+ VStackInvertedLists::VStackInvertedLists(int n_il, const InvertedLists** ils_in)
697
697
  : ReadOnlyInvertedLists(
698
- sum_il_sizes(nil, ils_in),
699
- nil > 0 ? ils_in[0]->code_size : 0) {
700
- FAISS_THROW_IF_NOT(nil > 0);
701
- cumsz.resize(nil + 1);
702
- for (int i = 0; i < nil; i++) {
698
+ sum_il_sizes(n_il, ils_in),
699
+ n_il > 0 ? ils_in[0]->code_size : 0) {
700
+ FAISS_THROW_IF_NOT(n_il > 0);
701
+ cumsz.resize(n_il + 1);
702
+ for (int i = 0; i < n_il; i++) {
703
703
  ils.push_back(ils_in[i]);
704
704
  FAISS_THROW_IF_NOT(ils_in[i]->code_size == code_size);
705
705
  cumsz[i + 1] = cumsz[i] + ils_in[i]->nlist;
@@ -376,7 +376,7 @@ struct HStackInvertedLists : ReadOnlyInvertedLists {
376
376
  std::vector<const InvertedLists*> ils;
377
377
 
378
378
  /// build InvertedLists by concatenating nil of them
379
- HStackInvertedLists(int nil, const InvertedLists** ils);
379
+ HStackInvertedLists(int n_il, const InvertedLists** ils);
380
380
 
381
381
  size_t list_size(size_t list_no) const override;
382
382
  const uint8_t* get_codes(size_t list_no) const override;
@@ -422,7 +422,7 @@ struct VStackInvertedLists : ReadOnlyInvertedLists {
422
422
  std::vector<idx_t> cumsz;
423
423
 
424
424
  /// build InvertedLists by concatenating nil of them
425
- VStackInvertedLists(int nil, const InvertedLists** ils);
425
+ VStackInvertedLists(int n_il, const InvertedLists** ils);
426
426
 
427
427
  size_t list_size(size_t list_no) const override;
428
428
  const uint8_t* get_codes(size_t list_no) const override;