faiss 0.6.4 → 0.6.5

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 (228) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/ext/faiss/extconf.rb +1 -1
  4. data/lib/faiss/version.rb +1 -1
  5. data/vendor/faiss/faiss/AutoTune.cpp +175 -0
  6. data/vendor/faiss/faiss/Clustering.cpp +150 -60
  7. data/vendor/faiss/faiss/Clustering.h +29 -0
  8. data/vendor/faiss/faiss/IVFlib.cpp +99 -0
  9. data/vendor/faiss/faiss/IVFlib.h +15 -0
  10. data/vendor/faiss/faiss/Index.cpp +44 -0
  11. data/vendor/faiss/faiss/Index.h +19 -14
  12. data/vendor/faiss/faiss/IndexBinary.cpp +8 -0
  13. data/vendor/faiss/faiss/IndexBinary.h +8 -0
  14. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +82 -4
  15. data/vendor/faiss/faiss/IndexBinaryHNSW.h +19 -0
  16. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +34 -0
  17. data/vendor/faiss/faiss/IndexFastScan.cpp +33 -17
  18. data/vendor/faiss/faiss/IndexFastScan.h +6 -3
  19. data/vendor/faiss/faiss/IndexFlat.cpp +56 -0
  20. data/vendor/faiss/faiss/IndexFlat.h +31 -0
  21. data/vendor/faiss/faiss/IndexFlatCodes.cpp +6 -1
  22. data/vendor/faiss/faiss/IndexHNSW.cpp +456 -10
  23. data/vendor/faiss/faiss/IndexHNSW.h +38 -0
  24. data/vendor/faiss/faiss/IndexIDMap.cpp +32 -0
  25. data/vendor/faiss/faiss/IndexIDMap.h +7 -0
  26. data/vendor/faiss/faiss/IndexIVF.cpp +281 -31
  27. data/vendor/faiss/faiss/IndexIVF.h +53 -1
  28. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +46 -14
  29. data/vendor/faiss/faiss/IndexIVFFastScan.h +4 -2
  30. data/vendor/faiss/faiss/IndexIVFFlat.cpp +33 -0
  31. data/vendor/faiss/faiss/IndexIVFFlat.h +16 -0
  32. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +1 -0
  33. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +3 -20
  34. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +50 -14
  35. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +5 -2
  36. data/vendor/faiss/faiss/IndexIVFSQFastScan.cpp +855 -0
  37. data/vendor/faiss/faiss/IndexIVFSQFastScan.h +145 -0
  38. data/vendor/faiss/faiss/IndexNNDescent.cpp +0 -3
  39. data/vendor/faiss/faiss/IndexPiPNN.cpp +201 -0
  40. data/vendor/faiss/faiss/IndexPiPNN.h +83 -0
  41. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +6 -3
  42. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +10 -4
  43. data/vendor/faiss/faiss/IndexReplicas.cpp +20 -0
  44. data/vendor/faiss/faiss/IndexReplicas.h +9 -0
  45. data/vendor/faiss/faiss/IndexSQFastScan.cpp +648 -0
  46. data/vendor/faiss/faiss/IndexSQFastScan.h +129 -0
  47. data/vendor/faiss/faiss/IndexShards.cpp +10 -0
  48. data/vendor/faiss/faiss/IndexShards.h +5 -0
  49. data/vendor/faiss/faiss/SuperKMeans.cpp +57 -15
  50. data/vendor/faiss/faiss/SuperKMeans.h +9 -4
  51. data/vendor/faiss/faiss/VectorTransform.cpp +3 -2
  52. data/vendor/faiss/faiss/clone_index.cpp +24 -0
  53. data/vendor/faiss/faiss/gpu/Dataset.h +112 -0
  54. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +16 -13
  55. data/vendor/faiss/faiss/gpu/GpuCloner.h +4 -0
  56. data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +3 -0
  57. data/vendor/faiss/faiss/gpu/GpuIndex.h +4 -13
  58. data/vendor/faiss/faiss/gpu/GpuIndexBinaryCagra.h +26 -13
  59. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +45 -22
  60. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +11 -0
  61. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +6 -0
  62. data/vendor/faiss/faiss/gpu/test/TestGpuDatasetHeader.cpp +18 -0
  63. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +215 -0
  64. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +98 -0
  65. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +11 -0
  66. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +1 -1
  67. data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +11 -0
  68. data/vendor/faiss/faiss/gpu_metal/MetalDistance.h +92 -0
  69. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +4 -0
  70. data/vendor/faiss/faiss/gpu_metal/MetalIndexBinaryFlat.h +69 -0
  71. data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFPQ.h +38 -0
  72. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +106 -0
  73. data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +10 -0
  74. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +2 -0
  75. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +1 -6
  76. data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +134 -45
  77. data/vendor/faiss/faiss/impl/ClusteringHelpers.h +36 -0
  78. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +286 -136
  79. data/vendor/faiss/faiss/impl/DistanceComputer.cpp +63 -0
  80. data/vendor/faiss/faiss/impl/DistanceComputer.h +3 -29
  81. data/vendor/faiss/faiss/impl/HNSW.cpp +46 -10
  82. data/vendor/faiss/faiss/impl/HNSW.h +72 -0
  83. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +6 -19
  84. data/vendor/faiss/faiss/impl/NNDescent.cpp +2 -1
  85. data/vendor/faiss/faiss/impl/NSG.cpp +3 -2
  86. data/vendor/faiss/faiss/impl/Panorama.h +3 -2
  87. data/vendor/faiss/faiss/impl/PiPNN.cpp +822 -0
  88. data/vendor/faiss/faiss/impl/PiPNN.h +122 -0
  89. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +54 -11
  90. data/vendor/faiss/faiss/impl/RaBitQUtils.h +1 -1
  91. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +81 -57
  92. data/vendor/faiss/faiss/impl/RaBitQuantizer.h +15 -0
  93. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +29 -0
  94. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +1 -6
  95. data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +0 -4
  96. data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +0 -4
  97. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +5 -2
  98. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +0 -4
  99. data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +0 -4
  100. data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +0 -4
  101. data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +0 -4
  102. data/vendor/faiss/faiss/impl/expanded_scanners.h +88 -0
  103. data/vendor/faiss/faiss/impl/fast_scan/FastScanDistancePostProcessing.h +4 -0
  104. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +61 -64
  105. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +13 -14
  106. data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +17 -129
  107. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +25 -19
  108. data/vendor/faiss/faiss/impl/fast_scan/fast_scan.cpp +5 -0
  109. data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +0 -4
  110. data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +0 -4
  111. data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +0 -88
  112. data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +0 -4
  113. data/vendor/faiss/faiss/impl/fast_scan/kernels_neon.h +155 -0
  114. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +22 -1
  115. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd512.h +3 -2
  116. data/vendor/faiss/faiss/impl/fast_scan/simd_result_handlers.h +41 -23
  117. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +0 -4
  118. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +0 -4
  119. data/vendor/faiss/faiss/impl/index_read.cpp +172 -0
  120. data/vendor/faiss/faiss/impl/index_write.cpp +95 -0
  121. data/vendor/faiss/faiss/impl/pipnn/HashPrune.cpp +159 -0
  122. data/vendor/faiss/faiss/impl/pipnn/HashPrune.h +69 -0
  123. data/vendor/faiss/faiss/impl/pipnn/Partition.cpp +587 -0
  124. data/vendor/faiss/faiss/impl/pipnn/Partition.h +93 -0
  125. data/vendor/faiss/faiss/impl/pipnn/kernels.cpp +326 -0
  126. data/vendor/faiss/faiss/impl/pipnn/kernels.h +92 -0
  127. data/vendor/faiss/faiss/impl/platform_macros.h +45 -0
  128. data/vendor/faiss/faiss/impl/polysemous_training/avx512.cpp +0 -4
  129. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +79 -4
  130. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +6 -0
  131. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +0 -4
  132. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +0 -4
  133. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +0 -4
  134. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-avx2.h +4 -0
  135. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-avx512.h +4 -1
  136. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +19 -0
  137. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +6 -6
  138. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +131 -6
  139. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +0 -4
  140. data/vendor/faiss/faiss/impl/pq_code_distance/pq_rvv_kernel.h +89 -0
  141. data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +21 -10
  142. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +45 -18
  143. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +2 -1
  144. data/vendor/faiss/faiss/impl/result_handler/avx2.cpp +0 -4
  145. data/vendor/faiss/faiss/impl/result_handler/avx512.cpp +0 -4
  146. data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx2.cpp +0 -4
  147. data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx512.cpp +0 -4
  148. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +5 -1
  149. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +28 -52
  150. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +59 -11
  151. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +226 -77
  152. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +482 -103
  153. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +2 -149
  154. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +3 -698
  155. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +66 -57
  156. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +101 -96
  157. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +3185 -144
  158. data/vendor/faiss/faiss/impl/scalar_quantizer/sq8_coefficients.h +48 -0
  159. data/vendor/faiss/faiss/impl/scalar_quantizer/sq8_rvv_kernel.h +546 -0
  160. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +2 -2
  161. data/vendor/faiss/faiss/impl/simd_dispatch.h +7 -0
  162. data/vendor/faiss/faiss/impl/simdlib/simdlib_avx2.h +14 -0
  163. data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +7 -8
  164. data/vendor/faiss/faiss/impl/sq_fastscan_utils.h +232 -0
  165. data/vendor/faiss/faiss/index_factory.cpp +76 -0
  166. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +3 -1
  167. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +3 -2
  168. data/vendor/faiss/faiss/utils/AlignedTable.h +6 -1
  169. data/vendor/faiss/faiss/utils/Heap.cpp +4 -3
  170. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +16 -5
  171. data/vendor/faiss/faiss/utils/bf16.h +36 -0
  172. data/vendor/faiss/faiss/utils/distances.cpp +226 -15
  173. data/vendor/faiss/faiss/utils/distances.h +34 -0
  174. data/vendor/faiss/faiss/utils/distances_dispatch.h +6 -4
  175. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +2 -5
  176. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +0 -14
  177. data/vendor/faiss/faiss/utils/distances_fused/rvv.cpp +25 -0
  178. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +0 -4
  179. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +0 -4
  180. data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +2 -1
  181. data/vendor/faiss/faiss/utils/distances_simd.cpp +9 -0
  182. data/vendor/faiss/faiss/utils/fp16-fp16c.h +4 -0
  183. data/vendor/faiss/faiss/utils/fp16-inl.h +26 -52
  184. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +0 -4
  185. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +0 -4
  186. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_vpopcnt.cpp +0 -4
  187. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +33 -5
  188. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_vpopcnt.h +15 -30
  189. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +0 -4
  190. data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +2 -1
  191. data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +0 -4
  192. data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +0 -4
  193. data/vendor/faiss/faiss/utils/pq_code_distance.h +8 -4
  194. data/vendor/faiss/faiss/utils/prefetch.h +1 -26
  195. data/vendor/faiss/faiss/utils/quantize_lut.cpp +26 -27
  196. data/vendor/faiss/faiss/utils/quantize_lut.h +11 -0
  197. data/vendor/faiss/faiss/utils/rabitq_simd.h +51 -16
  198. data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +9 -4
  199. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +37 -5
  200. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +64 -5
  201. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +64 -5
  202. data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +353 -71
  203. data/vendor/faiss/faiss/utils/simd_impl/distances_rvv_kernel.h +68 -0
  204. data/vendor/faiss/faiss/utils/simd_impl/exhaustive_L2sqr_blas_cmax.h +93 -0
  205. data/vendor/faiss/faiss/utils/simd_impl/fp16_kernels.h +76 -0
  206. data/vendor/faiss/faiss/utils/simd_impl/fp16_kernels_avx2.cpp +52 -0
  207. data/vendor/faiss/faiss/utils/simd_impl/fp16_kernels_avx512.cpp +52 -0
  208. data/vendor/faiss/faiss/utils/simd_impl/fp16_kernels_neon.cpp +48 -0
  209. data/vendor/faiss/faiss/utils/simd_impl/masked_sum-avx2.h +44 -0
  210. data/vendor/faiss/faiss/utils/simd_impl/masked_sum-avx512.h +43 -0
  211. data/vendor/faiss/faiss/utils/simd_impl/masked_sum.h +38 -0
  212. data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +0 -4
  213. data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +0 -4
  214. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +54 -15
  215. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +38 -21
  216. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512_vpopcnt.cpp +51 -14
  217. data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +297 -10
  218. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +0 -4
  219. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +0 -4
  220. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +0 -4
  221. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_sve.cpp +0 -4
  222. data/vendor/faiss/faiss/utils/simd_levels.cpp +19 -3
  223. data/vendor/faiss/faiss/utils/simd_levels.h +74 -1
  224. data/vendor/faiss/faiss/utils/transpose/transpose-avx2-inl.h +0 -4
  225. data/vendor/faiss/faiss/utils/transpose/transpose-avx512-inl.h +0 -4
  226. data/vendor/faiss/faiss/utils/utils.cpp +80 -0
  227. data/vendor/faiss/faiss/utils/utils.h +24 -0
  228. metadata +33 -1
@@ -149,11 +149,11 @@ struct QuantizerTemplate<
149
149
  /*******************************************************************
150
150
  * Lloyd-Max scalar quantizer
151
151
  *******************************************************************/
152
+ // Each QuantizerXBase<SL> holds the scalar code of a quantizer. It takes the
153
+ // SIMD level of the file that uses it, so each per-level file compiles its own
154
+ // copy under its own name.
152
155
  template <int NBits, SIMDLevel SL>
153
- struct QuantizerLloydMax;
154
-
155
- template <int NBits>
156
- struct QuantizerLloydMax<NBits, SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
156
+ struct QuantizerLloydMaxBase : ScalarQuantizer::SQuantizer {
157
157
  static_assert(NBits >= 1 && NBits <= 8);
158
158
 
159
159
  static constexpr size_t kCentroidsCount = size_t(1) << NBits;
@@ -164,7 +164,7 @@ struct QuantizerLloydMax<NBits, SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
164
164
  const float* centroids;
165
165
  const float* boundaries;
166
166
 
167
- QuantizerLloydMax(size_t d_in, const std::vector<float>& trained)
167
+ QuantizerLloydMaxBase(size_t d_in, const std::vector<float>& trained)
168
168
  : d(d_in), centroids(nullptr), boundaries(nullptr) {
169
169
  FAISS_THROW_IF_NOT(trained.size() == 2 * kCentroidsCount - 1);
170
170
  centroids = trained.data();
@@ -220,8 +220,8 @@ struct QuantizerLloydMax<NBits, SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
220
220
  };
221
221
 
222
222
  template <int NBits, SIMDLevel SL>
223
- struct QuantizerLloydMax : QuantizerLloydMax<NBits, SIMDLevel::NONE> {
224
- using QuantizerLloydMax<NBits, SIMDLevel::NONE>::QuantizerLloydMax;
223
+ struct QuantizerLloydMax : QuantizerLloydMaxBase<NBits, SL> {
224
+ using QuantizerLloydMaxBase<NBits, SL>::QuantizerLloydMaxBase;
225
225
  };
226
226
 
227
227
  template <int NBits, SIMDLevel SL>
@@ -232,13 +232,10 @@ using QuantizerTurboQuantMSE = QuantizerLloydMax<NBits, SL>;
232
232
  *******************************************************************/
233
233
 
234
234
  template <SIMDLevel SL>
235
- struct QuantizerFP16;
236
-
237
- template <>
238
- struct QuantizerFP16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
235
+ struct QuantizerFP16Base : ScalarQuantizer::SQuantizer {
239
236
  const size_t d;
240
237
 
241
- QuantizerFP16(size_t d_in, const std::vector<float>& /* unused */)
238
+ QuantizerFP16Base(size_t d_in, const std::vector<float>& /* unused */)
242
239
  : d(d_in) {}
243
240
 
244
241
  void encode_vector(const float* x, uint8_t* code) const final {
@@ -247,7 +244,7 @@ struct QuantizerFP16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
247
244
  }
248
245
  }
249
246
 
250
- void decode_vector(const uint8_t* code, float* x) const final {
247
+ void decode_vector(const uint8_t* code, float* x) const override {
251
248
  for (size_t i = 0; i < d; i++) {
252
249
  x[i] = decode_fp16(((uint16_t*)code)[i]);
253
250
  }
@@ -261,8 +258,8 @@ struct QuantizerFP16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
261
258
  };
262
259
 
263
260
  template <SIMDLevel SL>
264
- struct QuantizerFP16 : QuantizerFP16<SIMDLevel::NONE> {
265
- using QuantizerFP16<SIMDLevel::NONE>::QuantizerFP16;
261
+ struct QuantizerFP16 : QuantizerFP16Base<SL> {
262
+ using QuantizerFP16Base<SL>::QuantizerFP16Base;
266
263
  };
267
264
 
268
265
  /*******************************************************************
@@ -270,13 +267,10 @@ struct QuantizerFP16 : QuantizerFP16<SIMDLevel::NONE> {
270
267
  *******************************************************************/
271
268
 
272
269
  template <SIMDLevel SL>
273
- struct QuantizerBF16;
274
-
275
- template <>
276
- struct QuantizerBF16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
270
+ struct QuantizerBF16Base : ScalarQuantizer::SQuantizer {
277
271
  const size_t d;
278
272
 
279
- QuantizerBF16(size_t d_in, const std::vector<float>& /* unused */)
273
+ QuantizerBF16Base(size_t d_in, const std::vector<float>& /* unused */)
280
274
  : d(d_in) {}
281
275
 
282
276
  void encode_vector(const float* x, uint8_t* code) const override {
@@ -295,8 +289,8 @@ struct QuantizerBF16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
295
289
  };
296
290
 
297
291
  template <SIMDLevel SL>
298
- struct QuantizerBF16 : QuantizerBF16<SIMDLevel::NONE> {
299
- using QuantizerBF16<SIMDLevel::NONE>::QuantizerBF16;
292
+ struct QuantizerBF16 : QuantizerBF16Base<SL> {
293
+ using QuantizerBF16Base<SL>::QuantizerBF16Base;
300
294
  };
301
295
 
302
296
  template <>
@@ -309,22 +303,19 @@ struct QuantizerBF16<SIMDLevel::AVX512_SPR>;
309
303
  *******************************************************************/
310
304
 
311
305
  template <SIMDLevel SL>
312
- struct Quantizer8bitDirect;
313
-
314
- template <>
315
- struct Quantizer8bitDirect<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
306
+ struct Quantizer8bitDirectBase : ScalarQuantizer::SQuantizer {
316
307
  const size_t d;
317
308
 
318
- Quantizer8bitDirect(size_t d_in, const std::vector<float>& /* unused */)
309
+ Quantizer8bitDirectBase(size_t d_in, const std::vector<float>& /* unused */)
319
310
  : d(d_in) {}
320
311
 
321
- void encode_vector(const float* x, uint8_t* code) const final {
312
+ void encode_vector(const float* x, uint8_t* code) const override {
322
313
  for (size_t i = 0; i < d; i++) {
323
314
  code[i] = (uint8_t)x[i];
324
315
  }
325
316
  }
326
317
 
327
- void decode_vector(const uint8_t* code, float* x) const final {
318
+ void decode_vector(const uint8_t* code, float* x) const override {
328
319
  for (size_t i = 0; i < d; i++) {
329
320
  x[i] = code[i];
330
321
  }
@@ -338,8 +329,8 @@ struct Quantizer8bitDirect<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
338
329
  };
339
330
 
340
331
  template <SIMDLevel SL>
341
- struct Quantizer8bitDirect : Quantizer8bitDirect<SIMDLevel::NONE> {
342
- using Quantizer8bitDirect<SIMDLevel::NONE>::Quantizer8bitDirect;
332
+ struct Quantizer8bitDirect : Quantizer8bitDirectBase<SL> {
333
+ using Quantizer8bitDirectBase<SL>::Quantizer8bitDirectBase;
343
334
  };
344
335
 
345
336
  /*******************************************************************
@@ -347,14 +338,10 @@ struct Quantizer8bitDirect : Quantizer8bitDirect<SIMDLevel::NONE> {
347
338
  *******************************************************************/
348
339
 
349
340
  template <SIMDLevel SL>
350
- struct Quantizer8bitDirectSigned;
351
-
352
- template <>
353
- struct Quantizer8bitDirectSigned<SIMDLevel::NONE>
354
- : ScalarQuantizer::SQuantizer {
341
+ struct Quantizer8bitDirectSignedBase : ScalarQuantizer::SQuantizer {
355
342
  const size_t d;
356
343
 
357
- Quantizer8bitDirectSigned(
344
+ Quantizer8bitDirectSignedBase(
358
345
  size_t d_in,
359
346
  const std::vector<float>& /* unused */)
360
347
  : d(d_in) {}
@@ -365,7 +352,7 @@ struct Quantizer8bitDirectSigned<SIMDLevel::NONE>
365
352
  }
366
353
  }
367
354
 
368
- void decode_vector(const uint8_t* code, float* x) const final {
355
+ void decode_vector(const uint8_t* code, float* x) const override {
369
356
  for (size_t i = 0; i < d; i++) {
370
357
  x[i] = code[i] - 128;
371
358
  }
@@ -379,8 +366,8 @@ struct Quantizer8bitDirectSigned<SIMDLevel::NONE>
379
366
  };
380
367
 
381
368
  template <SIMDLevel SL>
382
- struct Quantizer8bitDirectSigned : Quantizer8bitDirectSigned<SIMDLevel::NONE> {
383
- using Quantizer8bitDirectSigned<SIMDLevel::NONE>::Quantizer8bitDirectSigned;
369
+ struct Quantizer8bitDirectSigned : Quantizer8bitDirectSignedBase<SL> {
370
+ using Quantizer8bitDirectSignedBase<SL>::Quantizer8bitDirectSignedBase;
384
371
  };
385
372
 
386
373
  /*******************************************************************
@@ -403,11 +390,7 @@ struct SQTurboQFactors {
403
390
  FAISS_PACK_STRUCTS_END
404
391
 
405
392
  template <int NBits, SIMDLevel SL>
406
- struct QuantizerTurboQuantFull;
407
-
408
- template <int NBits>
409
- struct QuantizerTurboQuantFull<NBits, SIMDLevel::NONE>
410
- : ScalarQuantizer::SQuantizer {
393
+ struct QuantizerTurboQuantFull : ScalarQuantizer::SQuantizer {
411
394
  static_assert(NBits >= 2 && NBits <= 5);
412
395
 
413
396
  static constexpr int kMSEBits = NBits - 1;
@@ -658,13 +641,6 @@ struct QuantizerTurboQuantFull<NBits, SIMDLevel::NONE>
658
641
  }
659
642
  };
660
643
 
661
- template <int NBits, SIMDLevel SL>
662
- struct QuantizerTurboQuantFull
663
- : QuantizerTurboQuantFull<NBits, SIMDLevel::NONE> {
664
- using QuantizerTurboQuantFull<NBits, SIMDLevel::NONE>::
665
- QuantizerTurboQuantFull;
666
- };
667
-
668
644
  /*******************************************************************
669
645
  * Selection function
670
646
  *******************************************************************/
@@ -35,6 +35,19 @@ namespace scalar_quantizer {
35
35
  using QuantizerType = ScalarQuantizer::QuantizerType;
36
36
  using SQDistanceComputer = ScalarQuantizer::SQDistanceComputer;
37
37
 
38
+ // True when query_to_codes_batch_4 matches four query_to_code calls. The SIMD
39
+ // DCTemplate batch differs from the single path only for the uniform
40
+ // quantizers, whose single path predecodes the query, so those stay on the
41
+ // scalar scan and batched results never differ from scalar.
42
+ template <class DC>
43
+ constexpr bool sq_batch_4_is_exact() {
44
+ if constexpr (requires { DC::has_decode_raw(); }) {
45
+ return !DC::has_decode_raw();
46
+ } else {
47
+ return true;
48
+ }
49
+ }
50
+
38
51
  /*******************************************************************
39
52
  * IVFSQScannerIP / IVFSQScannerL2 — moved from anonymous namespace
40
53
  * in ScalarQuantizer.cpp
@@ -74,13 +87,35 @@ struct IVFSQScannerIP : InvertedListScanner {
74
87
  return accu0 + dc.query_to_code(code);
75
88
  }
76
89
 
90
+ void distance_to_codes_batch_4(
91
+ const uint8_t* code_0,
92
+ const uint8_t* code_1,
93
+ const uint8_t* code_2,
94
+ const uint8_t* code_3,
95
+ float& dis0,
96
+ float& dis1,
97
+ float& dis2,
98
+ float& dis3) const {
99
+ dc.query_to_codes_batch_4(
100
+ code_0, code_1, code_2, code_3, dis0, dis1, dis2, dis3);
101
+ dis0 += accu0;
102
+ dis1 += accu0;
103
+ dis2 += accu0;
104
+ dis3 += accu0;
105
+ }
106
+
77
107
  size_t scan_codes(
78
108
  size_t list_size,
79
109
  const uint8_t* codes,
80
110
  const idx_t* ids,
81
111
  ResultHandler& handler) const override {
82
- return run_scan_codes_fix_C<CMin<float, idx_t>>(
83
- *this, list_size, codes, ids, handler);
112
+ if constexpr (sq_batch_4_is_exact<DCClass>()) {
113
+ return run_scan_codes4_fix_C<CMin<float, idx_t>>(
114
+ *this, list_size, codes, ids, handler);
115
+ } else {
116
+ return run_scan_codes_fix_C<CMin<float, idx_t>>(
117
+ *this, list_size, codes, ids, handler);
118
+ }
84
119
  }
85
120
  };
86
121
 
@@ -133,13 +168,31 @@ struct IVFSQScannerL2 : InvertedListScanner {
133
168
  return dc.query_to_code(code);
134
169
  }
135
170
 
171
+ void distance_to_codes_batch_4(
172
+ const uint8_t* code_0,
173
+ const uint8_t* code_1,
174
+ const uint8_t* code_2,
175
+ const uint8_t* code_3,
176
+ float& dis0,
177
+ float& dis1,
178
+ float& dis2,
179
+ float& dis3) const {
180
+ dc.query_to_codes_batch_4(
181
+ code_0, code_1, code_2, code_3, dis0, dis1, dis2, dis3);
182
+ }
183
+
136
184
  size_t scan_codes(
137
185
  size_t list_size,
138
186
  const uint8_t* codes,
139
187
  const idx_t* ids,
140
188
  ResultHandler& handler) const override {
141
- return run_scan_codes_fix_C<CMax<float, idx_t>>(
142
- *this, list_size, codes, ids, handler);
189
+ if constexpr (sq_batch_4_is_exact<DCClass>()) {
190
+ return run_scan_codes4_fix_C<CMax<float, idx_t>>(
191
+ *this, list_size, codes, ids, handler);
192
+ } else {
193
+ return run_scan_codes_fix_C<CMax<float, idx_t>>(
194
+ *this, list_size, codes, ids, handler);
195
+ }
143
196
  }
144
197
  };
145
198
 
@@ -175,14 +228,9 @@ struct IVFCoarseDistanceScanner : InvertedListScanner {
175
228
 
176
229
  void set_query(const float* /*query_vector*/) override {}
177
230
 
178
- void set_list(idx_t list_no_in, float coarse_dis_in) override {
179
- this->list_no = list_no_in;
180
- this->coarse_dis = coarse_dis_in;
181
- }
231
+ void set_list(idx_t list_no_in, float coarse_dis_in) override;
182
232
 
183
- float distance_to_code(const uint8_t* /*code*/) const override {
184
- return coarse_dis;
185
- }
233
+ float distance_to_code(const uint8_t* /*code*/) const override;
186
234
  };
187
235
 
188
236
  } // namespace scalar_quantizer