faiss 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/ext/faiss/extconf.rb +2 -1
  4. data/ext/faiss/{index_rb.cpp → index.cpp} +1 -1
  5. data/ext/faiss/index_binary.cpp +1 -1
  6. data/ext/faiss/kmeans.cpp +1 -1
  7. data/ext/faiss/pca_matrix.cpp +1 -1
  8. data/ext/faiss/product_quantizer.cpp +1 -1
  9. data/ext/faiss/{utils_rb.cpp → utils.cpp} +1 -1
  10. data/lib/faiss/version.rb +1 -1
  11. data/vendor/faiss/faiss/AutoTune.cpp +93 -80
  12. data/vendor/faiss/faiss/Clustering.cpp +39 -240
  13. data/vendor/faiss/faiss/Clustering.h +6 -0
  14. data/vendor/faiss/faiss/IVFlib.cpp +41 -21
  15. data/vendor/faiss/faiss/Index.cpp +6 -5
  16. data/vendor/faiss/faiss/Index.h +5 -5
  17. data/vendor/faiss/faiss/Index2Layer.cpp +37 -53
  18. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +49 -37
  19. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +36 -34
  20. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +4 -1
  21. data/vendor/faiss/faiss/IndexBinary.cpp +5 -3
  22. data/vendor/faiss/faiss/IndexBinary.h +4 -4
  23. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +1 -1
  24. data/vendor/faiss/faiss/IndexBinaryFlat.h +1 -1
  25. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -4
  26. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +88 -97
  27. data/vendor/faiss/faiss/IndexBinaryHNSW.h +9 -3
  28. data/vendor/faiss/faiss/IndexBinaryHash.cpp +45 -236
  29. data/vendor/faiss/faiss/IndexBinaryHash.h +6 -6
  30. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +89 -417
  31. data/vendor/faiss/faiss/IndexFastScan.cpp +72 -109
  32. data/vendor/faiss/faiss/IndexFastScan.h +25 -23
  33. data/vendor/faiss/faiss/IndexFlat.cpp +27 -20
  34. data/vendor/faiss/faiss/IndexFlat.h +21 -18
  35. data/vendor/faiss/faiss/IndexFlatCodes.cpp +42 -19
  36. data/vendor/faiss/faiss/IndexHNSW.cpp +374 -206
  37. data/vendor/faiss/faiss/IndexHNSW.h +16 -2
  38. data/vendor/faiss/faiss/IndexIDMap.cpp +25 -21
  39. data/vendor/faiss/faiss/IndexIDMap.h +9 -7
  40. data/vendor/faiss/faiss/IndexIVF.cpp +467 -364
  41. data/vendor/faiss/faiss/IndexIVF.h +33 -12
  42. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +79 -76
  43. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +96 -93
  44. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +4 -1
  45. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +357 -238
  46. data/vendor/faiss/faiss/IndexIVFFastScan.h +42 -41
  47. data/vendor/faiss/faiss/IndexIVFFlat.cpp +39 -69
  48. data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
  49. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +56 -33
  50. data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
  51. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
  52. data/vendor/faiss/faiss/IndexIVFPQ.cpp +73 -846
  53. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +151 -121
  54. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
  55. data/vendor/faiss/faiss/IndexIVFPQR.cpp +23 -20
  56. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +30 -52
  57. data/vendor/faiss/faiss/IndexIVFRaBitQ.h +2 -1
  58. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +475 -476
  59. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +248 -93
  60. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +41 -127
  61. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
  62. data/vendor/faiss/faiss/IndexLSH.cpp +36 -19
  63. data/vendor/faiss/faiss/IndexLattice.cpp +13 -13
  64. data/vendor/faiss/faiss/IndexNNDescent.cpp +36 -21
  65. data/vendor/faiss/faiss/IndexNNDescent.h +2 -2
  66. data/vendor/faiss/faiss/IndexNSG.cpp +38 -23
  67. data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +31 -11
  68. data/vendor/faiss/faiss/IndexPQ.cpp +128 -221
  69. data/vendor/faiss/faiss/IndexPQ.h +3 -2
  70. data/vendor/faiss/faiss/IndexPQFastScan.cpp +20 -14
  71. data/vendor/faiss/faiss/IndexPQFastScan.h +3 -0
  72. data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -18
  73. data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
  74. data/vendor/faiss/faiss/IndexRaBitQ.cpp +11 -36
  75. data/vendor/faiss/faiss/IndexRaBitQ.h +2 -1
  76. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +41 -277
  77. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +183 -27
  78. data/vendor/faiss/faiss/IndexRefine.cpp +30 -25
  79. data/vendor/faiss/faiss/IndexRefine.h +4 -4
  80. data/vendor/faiss/faiss/IndexReplicas.cpp +6 -6
  81. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +15 -14
  82. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +1 -1
  83. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +150 -20
  84. data/vendor/faiss/faiss/IndexScalarQuantizer.h +10 -0
  85. data/vendor/faiss/faiss/IndexShards.cpp +10 -9
  86. data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
  87. data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
  88. data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
  89. data/vendor/faiss/faiss/MetaIndexes.h +1 -1
  90. data/vendor/faiss/faiss/MetricType.h +14 -7
  91. data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
  92. data/vendor/faiss/faiss/SuperKMeans.h +97 -0
  93. data/vendor/faiss/faiss/VectorTransform.cpp +237 -149
  94. data/vendor/faiss/faiss/VectorTransform.h +16 -16
  95. data/vendor/faiss/faiss/build.cpp +23 -0
  96. data/vendor/faiss/faiss/build.h +15 -0
  97. data/vendor/faiss/faiss/clone_index.cpp +48 -47
  98. data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +1 -1
  99. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
  100. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
  101. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +902 -12
  102. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
  103. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
  104. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +702 -10
  105. data/vendor/faiss/faiss/factory_tools.cpp +9 -0
  106. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
  107. data/vendor/faiss/faiss/gpu/GpuResources.h +3 -2
  108. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +15 -16
  109. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +5 -4
  110. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
  111. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
  112. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
  113. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
  114. data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
  115. data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
  116. data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
  117. data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
  118. data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
  119. data/vendor/faiss/faiss/gpu_metal/MetalDistance.h +87 -0
  120. data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
  121. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +58 -0
  122. data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
  123. data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +181 -0
  124. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +111 -0
  125. data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +45 -0
  126. data/vendor/faiss/faiss/gpu_metal/MetalResources.h +79 -0
  127. data/vendor/faiss/faiss/gpu_metal/StandardMetalResources.h +35 -0
  128. data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFFlat.h +193 -0
  129. data/vendor/faiss/faiss/impl/AdSampling.cpp +103 -0
  130. data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
  131. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +29 -25
  132. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
  133. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
  134. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -0
  135. data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
  136. data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
  137. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +16 -16
  138. data/vendor/faiss/faiss/impl/CodePacker.cpp +3 -3
  139. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +1 -1
  140. data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
  141. data/vendor/faiss/faiss/impl/FaissAssert.h +6 -3
  142. data/vendor/faiss/faiss/impl/FaissException.h +50 -3
  143. data/vendor/faiss/faiss/impl/HNSW.cpp +639 -507
  144. data/vendor/faiss/faiss/impl/HNSW.h +61 -44
  145. data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
  146. data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
  147. data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
  148. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +82 -77
  149. data/vendor/faiss/faiss/impl/NNDescent.cpp +62 -25
  150. data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
  151. data/vendor/faiss/faiss/impl/NSG.cpp +53 -32
  152. data/vendor/faiss/faiss/impl/NSG.h +4 -4
  153. data/vendor/faiss/faiss/impl/Panorama.cpp +23 -6
  154. data/vendor/faiss/faiss/impl/Panorama.h +269 -87
  155. data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
  156. data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
  157. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +46 -32
  158. data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
  159. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
  160. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
  161. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +55 -25
  162. data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
  163. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +55 -49
  164. data/vendor/faiss/faiss/impl/RaBitQUtils.h +65 -0
  165. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +302 -283
  166. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +26 -23
  167. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
  168. data/vendor/faiss/faiss/impl/ResultHandler.h +100 -75
  169. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +318 -7
  170. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +77 -1
  171. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
  172. data/vendor/faiss/faiss/impl/VisitedTable.cpp +10 -10
  173. data/vendor/faiss/faiss/impl/VisitedTable.h +70 -28
  174. data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
  175. data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
  176. data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
  177. data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
  178. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
  179. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
  180. data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
  181. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
  182. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
  183. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
  184. data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
  185. data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
  186. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
  187. data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
  188. data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
  189. data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
  190. data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
  191. data/vendor/faiss/faiss/impl/expanded_scanners.h +8 -3
  192. data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
  193. data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
  194. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
  195. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
  196. data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
  197. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +270 -0
  198. data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +169 -2
  199. data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
  200. data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
  201. data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
  202. data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
  203. data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
  204. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
  205. data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -356
  206. data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
  207. data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
  208. data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +282 -134
  209. data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
  210. data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
  211. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +83 -0
  212. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +113 -0
  213. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +150 -0
  214. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +142 -0
  215. data/vendor/faiss/faiss/impl/index_read.cpp +1227 -79
  216. data/vendor/faiss/faiss/impl/index_read_utils.h +1 -1
  217. data/vendor/faiss/faiss/impl/index_write.cpp +96 -13
  218. data/vendor/faiss/faiss/impl/io.cpp +6 -6
  219. data/vendor/faiss/faiss/impl/io_macros.h +58 -16
  220. data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
  221. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +37 -23
  222. data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
  223. data/vendor/faiss/faiss/impl/mapped_io.cpp +6 -6
  224. data/vendor/faiss/faiss/impl/platform_macros.h +15 -4
  225. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
  226. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
  227. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
  228. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
  229. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +23 -0
  230. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +23 -0
  231. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +23 -0
  232. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx2.cpp → pq_code_distance-avx2.h} +9 -13
  233. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx512.cpp → pq_code_distance-avx512.h} +9 -57
  234. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +45 -107
  235. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
  236. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +274 -5
  237. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +10 -7
  238. data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +105 -0
  239. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +70 -0
  240. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +311 -477
  241. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
  242. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +1 -1
  243. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +9 -2
  244. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +419 -19
  245. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +27 -1
  246. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +3 -3
  247. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +387 -2
  248. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +553 -0
  249. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +559 -0
  250. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +341 -2
  251. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +425 -3
  252. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +290 -2
  253. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +337 -0
  254. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +192 -8
  255. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +12 -0
  256. data/vendor/faiss/faiss/impl/simd_dispatch.h +157 -66
  257. data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
  258. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +264 -172
  259. data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
  260. data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
  261. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
  262. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +270 -218
  263. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
  264. data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
  265. data/vendor/faiss/faiss/impl/svs_io.h +8 -2
  266. data/vendor/faiss/faiss/index_factory.cpp +90 -18
  267. data/vendor/faiss/faiss/index_io.h +40 -0
  268. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +66 -16
  269. data/vendor/faiss/faiss/invlists/DirectMap.cpp +28 -15
  270. data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
  271. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +170 -86
  272. data/vendor/faiss/faiss/invlists/InvertedLists.h +88 -25
  273. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
  274. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +13 -13
  275. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  276. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +1 -1
  277. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
  278. data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
  279. data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
  280. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
  281. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
  282. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
  283. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
  284. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +142 -21
  285. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +33 -7
  286. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +3 -2
  287. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
  288. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +77 -27
  289. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +10 -4
  290. data/vendor/faiss/faiss/utils/Heap.cpp +10 -10
  291. data/vendor/faiss/faiss/utils/NeuralNet.cpp +47 -36
  292. data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
  293. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
  294. data/vendor/faiss/faiss/utils/bf16.h +34 -0
  295. data/vendor/faiss/faiss/utils/distances.cpp +390 -560
  296. data/vendor/faiss/faiss/utils/distances.h +20 -1
  297. data/vendor/faiss/faiss/utils/distances_dispatch.h +117 -37
  298. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
  299. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
  300. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
  301. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
  302. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
  303. data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
  304. data/vendor/faiss/faiss/utils/distances_simd.cpp +5 -178
  305. data/vendor/faiss/faiss/utils/extra_distances.cpp +9 -8
  306. data/vendor/faiss/faiss/utils/extra_distances.h +32 -6
  307. data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
  308. data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
  309. data/vendor/faiss/faiss/utils/hamming.h +92 -2
  310. data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
  311. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +16 -0
  312. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
  313. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +15 -0
  314. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
  315. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +210 -0
  316. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_spr.h +171 -0
  317. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-generic.h +368 -0
  318. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +322 -0
  319. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-rvv.h +39 -0
  320. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer.h +146 -0
  321. data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +481 -0
  322. data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +15 -0
  323. data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +15 -0
  324. data/vendor/faiss/faiss/utils/partitioning.cpp +66 -989
  325. data/vendor/faiss/faiss/utils/partitioning.h +31 -0
  326. data/vendor/faiss/faiss/utils/popcount.h +29 -0
  327. data/vendor/faiss/faiss/utils/pq_code_distance.h +2 -2
  328. data/vendor/faiss/faiss/utils/prefetch.h +2 -2
  329. data/vendor/faiss/faiss/utils/quantize_lut.cpp +30 -30
  330. data/vendor/faiss/faiss/utils/quantize_lut.h +1 -1
  331. data/vendor/faiss/faiss/utils/rabitq_simd.h +57 -536
  332. data/vendor/faiss/faiss/utils/random.cpp +6 -6
  333. data/vendor/faiss/faiss/utils/simd_impl/IVFFlatScanner-inl.h +51 -0
  334. data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +5 -1
  335. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +213 -4
  336. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +163 -10
  337. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +250 -4
  338. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +7 -4
  339. data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +189 -0
  340. data/vendor/faiss/faiss/utils/simd_impl/distances_simdlib256.h +195 -0
  341. data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +2 -1
  342. data/vendor/faiss/faiss/utils/{distances_fused/simdlib_based.h → simd_impl/exhaustive_L2sqr_blas_cmax.h} +5 -10
  343. data/vendor/faiss/faiss/utils/simd_impl/hamming_impl.h +481 -0
  344. data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +14 -0
  345. data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +14 -0
  346. data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +1031 -0
  347. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +355 -0
  348. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +477 -0
  349. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512_spr.cpp +343 -0
  350. data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +55 -0
  351. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
  352. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
  353. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
  354. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
  355. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
  356. data/vendor/faiss/faiss/utils/simd_levels.cpp +29 -7
  357. data/vendor/faiss/faiss/utils/simd_levels.h +93 -1
  358. data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
  359. data/vendor/faiss/faiss/utils/utils.cpp +5 -5
  360. data/vendor/faiss/faiss/utils/utils.h +3 -3
  361. metadata +129 -34
  362. data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
  363. data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
  364. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -224
  365. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -230
  366. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
  367. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
  368. data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
  369. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
  370. data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -235
  371. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
  372. data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
  373. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -449
  374. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
  375. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
  376. data/vendor/faiss/faiss/utils/simdlib.h +0 -42
  377. data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -365
  378. /data/ext/faiss/{utils_rb.h → utils.h} +0 -0
@@ -7,11 +7,15 @@
7
7
 
8
8
  #pragma once
9
9
 
10
+ #include <faiss/impl/RaBitQUtils.h>
10
11
  #include <faiss/impl/scalar_quantizer/codecs.h>
11
12
  #include <faiss/impl/scalar_quantizer/distance_computers.h>
12
13
  #include <faiss/impl/scalar_quantizer/quantizers.h>
13
14
  #include <faiss/impl/scalar_quantizer/scanners.h>
14
15
  #include <faiss/impl/scalar_quantizer/similarities.h>
16
+ #include <faiss/utils/distances.h>
17
+ #include <faiss/utils/rabitq_simd.h>
18
+ #include <limits>
15
19
 
16
20
  #ifndef THE_LEVEL_TO_DISPATCH
17
21
  #error "THE_LEVEL_TO_DISPATCH should be set on input to this header"
@@ -24,10 +28,324 @@ namespace scalar_quantizer {
24
28
  // Define SL as alias for THE_LEVEL_TO_DISPATCH for use in this file
25
29
  constexpr SIMDLevel SL = THE_LEVEL_TO_DISPATCH;
26
30
 
31
+ /*******************************************************************
32
+ * TurboQuant SIMD kernel: masked_sum
33
+ * Compute sum of arr[j] where bit j of the bitmask is set.
34
+ * NONE specialization is inline; AVX2/AVX512/NEON specializations
35
+ * live in sq-avx2.cpp / sq-avx512.cpp / sq-neon.cpp.
36
+ *******************************************************************/
37
+
38
+ template <SIMDLevel SL0>
39
+ float turboq_masked_sum(const float* arr, const uint8_t* bits, size_t d);
40
+
41
+ template <>
42
+ inline float turboq_masked_sum<SIMDLevel::NONE>(
43
+ const float* arr,
44
+ const uint8_t* bits,
45
+ size_t d) {
46
+ float result = 0;
47
+ for (size_t byte_idx = 0; byte_idx < (d + 7) / 8; byte_idx++) {
48
+ uint8_t b = bits[byte_idx];
49
+ size_t base = byte_idx * 8;
50
+ size_t end = std::min(base + 8, d);
51
+ for (size_t j = base; j < end; j++) {
52
+ if (b & (1 << (j - base))) {
53
+ result += arr[j];
54
+ }
55
+ }
56
+ }
57
+ return result;
58
+ }
59
+
60
+ /*******************************************************************
61
+ * Full TurboQuant DC — lives here because it needs both
62
+ * quantizers.h (QuantizerTurboQuantFull, SQTurboQFactors) and
63
+ * similarities.h (Similarity::metric_type). distance_computers.h
64
+ * can't include quantizers.h due to header ordering.
65
+ *******************************************************************/
66
+ template <int NBits, class Similarity, SIMDLevel SL2>
67
+ struct DCTurboQuantFull : ScalarQuantizer::TurboQuantRefine::DistanceComputer {
68
+ using Sim = Similarity;
69
+ QuantizerTurboQuantFull<NBits, SIMDLevel::NONE> quant;
70
+ std::vector<float> query;
71
+ std::vector<float> query_proj;
72
+ float q_norm_sq = 0;
73
+ float qjl_coeff = 0;
74
+ float total_qproj_sum = 0;
75
+
76
+ // Pre-screening state
77
+ const float* threshold_ptr = nullptr;
78
+ bool prescreen_l2 = false;
79
+ float qjl_error_coeff = 0;
80
+ mutable size_t n_total = 0;
81
+ mutable size_t n_skipped = 0;
82
+
83
+ // Integer popcount state
84
+ uint8_t qb = 0;
85
+ bool int_qjl = false;
86
+ std::vector<uint8_t> rearranged_q;
87
+ float mse_base = 0;
88
+ float mse_int_scale = 0;
89
+ float mse_popcnt_scale = 0;
90
+
91
+ // Integer QJL popcount state
92
+ std::vector<uint8_t> rearranged_qproj;
93
+ float qjl_int_scale = 0;
94
+ float qjl_popcnt_scale = 0;
95
+
96
+ // Scaled centroids for 1-bit MSE fast path (NBits==2)
97
+ float scaled_c0 = 0;
98
+ float scaled_c1 = 0;
99
+ float delta_centroid = 0;
100
+ float total_q_sum = 0;
101
+
102
+ // Multi-bit MSE decomposed coefficients (NBits==3, kMSEBits==2)
103
+ float mse_multi_base = 0;
104
+ float mse_coeff_s0 = 0;
105
+ float mse_coeff_s1 = 0;
106
+ float mse_coeff_s01 = 0;
107
+ mutable std::vector<uint8_t> scratch_and;
108
+
109
+ DCTurboQuantFull(size_t d, const std::vector<float>& trained)
110
+ : quant(d, trained) {
111
+ qjl_coeff = std::sqrt(M_PI / 2.0f) / static_cast<float>(d);
112
+ }
113
+
114
+ void configure(uint8_t qb_in, bool int_qjl_in) override {
115
+ qb = qb_in;
116
+ int_qjl = int_qjl_in;
117
+ }
118
+
119
+ void set_prescreen_threshold(const float* ptr, bool l2) override {
120
+ threshold_ptr = ptr;
121
+ prescreen_l2 = l2;
122
+ }
123
+
124
+ void clear_prescreen_threshold() override {
125
+ threshold_ptr = nullptr;
126
+ }
127
+
128
+ void set_query(const float* x) final {
129
+ q = x;
130
+ size_t d = quant.d;
131
+ query.assign(x, x + d);
132
+ q_norm_sq = fvec_norm_L2sqr(x, d);
133
+
134
+ // Project query
135
+ query_proj.resize(d);
136
+ quant.project_forward(x, query_proj.data());
137
+ float inv_sqrt_pd =
138
+ 1.0f / std::sqrt(static_cast<float>(quant.padded_d));
139
+ for (size_t j = 0; j < d; j++) {
140
+ query_proj[j] *= inv_sqrt_pd;
141
+ }
142
+
143
+ total_qproj_sum = 0;
144
+ for (size_t j = 0; j < d; j++) {
145
+ total_qproj_sum += query_proj[j];
146
+ }
147
+
148
+ // Pre-screening: worst-case L1 bound on QJL error
149
+ float qproj_l1 = 0;
150
+ for (size_t j = 0; j < d; j++) {
151
+ qproj_l1 += std::abs(query_proj[j]);
152
+ }
153
+ qjl_error_coeff = qjl_coeff * qproj_l1;
154
+
155
+ // Pre-compute for 1-bit MSE fast path
156
+ if constexpr (NBits == 2) {
157
+ float inv_sqrt_d = 1.0f / std::sqrt(static_cast<float>(d));
158
+ scaled_c0 = quant.centroids[0] * inv_sqrt_d;
159
+ scaled_c1 = quant.centroids[1] * inv_sqrt_d;
160
+ delta_centroid = scaled_c1 - scaled_c0;
161
+ total_q_sum = 0;
162
+ for (size_t j = 0; j < d; j++) {
163
+ total_q_sum += query[j];
164
+ }
165
+
166
+ // Integer popcount setup
167
+ if (qb > 0) {
168
+ size_t byte_size = (d + 7) / 8;
169
+ float q_min = *std::min_element(query.begin(), query.end());
170
+ float q_max = *std::max_element(query.begin(), query.end());
171
+ float q_range = q_max - q_min;
172
+ if (q_range < 1e-30f) {
173
+ q_range = 1e-30f;
174
+ }
175
+ float max_val = static_cast<float>((1 << qb) - 1);
176
+ float scale = max_val / q_range;
177
+ float delta_q = q_range / max_val;
178
+
179
+ rearranged_q.assign(byte_size * qb, 0);
180
+ for (size_t j = 0; j < d; j++) {
181
+ int qval = static_cast<int>(
182
+ std::round((query[j] - q_min) * scale));
183
+ qval = std::max(
184
+ 0, std::min(static_cast<int>(max_val), qval));
185
+ for (int b = 0; b < qb; b++) {
186
+ if (qval & (1 << b)) {
187
+ rearranged_q[b * byte_size + j / 8] |=
188
+ (1 << (j % 8));
189
+ }
190
+ }
191
+ }
192
+ mse_base = scaled_c0 * total_q_sum;
193
+ mse_int_scale = delta_centroid * delta_q;
194
+ mse_popcnt_scale = delta_centroid * q_min;
195
+ }
196
+ }
197
+
198
+ // Pre-compute for 2-bit MSE decomposed path (NBits==3)
199
+ if constexpr (NBits == 3) {
200
+ float inv_sqrt_d = 1.0f / std::sqrt(static_cast<float>(d));
201
+ const float* c = quant.centroids;
202
+ total_q_sum = 0;
203
+ for (size_t j = 0; j < d; j++) {
204
+ total_q_sum += query[j];
205
+ }
206
+ mse_multi_base = c[0] * inv_sqrt_d * total_q_sum;
207
+ mse_coeff_s0 = (c[1] - c[0]) * inv_sqrt_d;
208
+ mse_coeff_s1 = (c[2] - c[0]) * inv_sqrt_d;
209
+ mse_coeff_s01 = (c[3] - c[2] - c[1] + c[0]) * inv_sqrt_d;
210
+ scratch_and.resize((d + 7) / 8);
211
+ }
212
+
213
+ // Integer QJL: quantize projected query into bit-planes
214
+ if (qb > 0 && int_qjl) {
215
+ size_t byte_size = (d + 7) / 8;
216
+ float qp_min =
217
+ *std::min_element(query_proj.begin(), query_proj.end());
218
+ float qp_max =
219
+ *std::max_element(query_proj.begin(), query_proj.end());
220
+ float qp_range = qp_max - qp_min;
221
+ if (qp_range < 1e-30f) {
222
+ qp_range = 1e-30f;
223
+ }
224
+ float max_val = static_cast<float>((1 << qb) - 1);
225
+ float qp_scale = max_val / qp_range;
226
+ float delta_qp = qp_range / max_val;
227
+
228
+ rearranged_qproj.assign(byte_size * qb, 0);
229
+ for (size_t j = 0; j < d; j++) {
230
+ int qval = static_cast<int>(
231
+ std::round((query_proj[j] - qp_min) * qp_scale));
232
+ qval = std::max(0, std::min(static_cast<int>(max_val), qval));
233
+ for (int b = 0; b < qb; b++) {
234
+ if (qval & (1 << b)) {
235
+ rearranged_qproj[b * byte_size + j / 8] |=
236
+ (1 << (j % 8));
237
+ }
238
+ }
239
+ }
240
+ qjl_popcnt_scale = qp_min;
241
+ qjl_int_scale = delta_qp;
242
+ }
243
+
244
+ n_total = 0;
245
+ n_skipped = 0;
246
+ }
247
+
248
+ float query_to_code(const uint8_t* code) const final {
249
+ size_t d = quant.d;
250
+ float inv_sqrt_d = 1.0f / std::sqrt(static_cast<float>(d));
251
+ const auto* factors = reinterpret_cast<const SQTurboQFactors*>(
252
+ code + quant.mse_total_bytes + quant.qjl_plane_bytes);
253
+ float norm = factors->norm;
254
+ float gamma = factors->gamma;
255
+
256
+ // Stage 1: MSE dot product
257
+ float mse_dot = 0;
258
+ if constexpr (NBits == 2) {
259
+ if (qb > 0) {
260
+ // Integer popcount path for 1-bit MSE
261
+ size_t byte_size = (d + 7) / 8;
262
+ uint64_t and_result = rabitq::bitwise_and_dot_product<SL2>(
263
+ rearranged_q.data(), code, byte_size, qb);
264
+ uint64_t pop = rabitq::popcount<SL2>(code, byte_size);
265
+ mse_dot = mse_base +
266
+ mse_int_scale * static_cast<float>(and_result) +
267
+ mse_popcnt_scale * static_cast<float>(pop);
268
+ } else {
269
+ // Float path: masked accumulation
270
+ float pos_sum = turboq_masked_sum<SL2>(query.data(), code, d);
271
+ mse_dot = scaled_c0 * total_q_sum + delta_centroid * pos_sum;
272
+ }
273
+ } else if constexpr (NBits == 3) {
274
+ // 2-bit MSE: decompose into 3 masked sums over bit-planes.
275
+ size_t pb = quant.mse_plane_bytes;
276
+ float s0 = turboq_masked_sum<SL2>(query.data(), code, d);
277
+ float s1 = turboq_masked_sum<SL2>(query.data(), code + pb, d);
278
+ for (size_t i = 0; i < pb; i++) {
279
+ scratch_and[i] = code[i] & code[pb + i];
280
+ }
281
+ float s01 =
282
+ turboq_masked_sum<SL2>(query.data(), scratch_and.data(), d);
283
+ mse_dot = mse_multi_base + mse_coeff_s0 * s0 + mse_coeff_s1 * s1 +
284
+ mse_coeff_s01 * s01;
285
+ } else {
286
+ // kMSEBits > 2: per-dimension fallback
287
+ for (size_t j = 0; j < d; j++) {
288
+ uint8_t idx = quant.load_mse_index(code, j);
289
+ mse_dot += query[j] * quant.centroids[idx] * inv_sqrt_d;
290
+ }
291
+ }
292
+
293
+ // Pre-screening
294
+ if (threshold_ptr != nullptr) {
295
+ n_total++;
296
+ float bound = qjl_error_coeff * gamma * norm;
297
+ float mse_ip = norm * mse_dot;
298
+
299
+ if constexpr (Similarity::metric_type == METRIC_INNER_PRODUCT) {
300
+ if (mse_ip + bound <= *threshold_ptr) {
301
+ n_skipped++;
302
+ return -std::numeric_limits<float>::infinity();
303
+ }
304
+ } else {
305
+ float best_possible =
306
+ q_norm_sq + norm * norm - 2.0f * (mse_ip + bound);
307
+ if (best_possible >= *threshold_ptr) {
308
+ n_skipped++;
309
+ return std::numeric_limits<float>::infinity();
310
+ }
311
+ }
312
+ }
313
+
314
+ // Stage 2: QJL dot product
315
+ const uint8_t* qjl_code = code + quant.mse_total_bytes;
316
+ float qjl_dot;
317
+ if (qb > 0 && int_qjl) {
318
+ size_t byte_size = (d + 7) / 8;
319
+ uint64_t and_result = rabitq::bitwise_and_dot_product<SL2>(
320
+ rearranged_qproj.data(), qjl_code, byte_size, qb);
321
+ uint64_t pop = rabitq::popcount<SL2>(qjl_code, byte_size);
322
+ float pos_sum = qjl_popcnt_scale * static_cast<float>(pop) +
323
+ qjl_int_scale * static_cast<float>(and_result);
324
+ qjl_dot = qjl_coeff * gamma * (2.0f * pos_sum - total_qproj_sum);
325
+ } else {
326
+ float pos_sum =
327
+ turboq_masked_sum<SL2>(query_proj.data(), qjl_code, d);
328
+ qjl_dot = qjl_coeff * gamma * (2.0f * pos_sum - total_qproj_sum);
329
+ }
330
+
331
+ float estimated_ip = norm * (mse_dot + qjl_dot);
332
+
333
+ if constexpr (Similarity::metric_type == METRIC_INNER_PRODUCT) {
334
+ return estimated_ip;
335
+ } else {
336
+ return q_norm_sq + norm * norm - 2.0f * estimated_ip;
337
+ }
338
+ }
339
+
340
+ float symmetric_dis(idx_t, idx_t) override {
341
+ FAISS_THROW_MSG("Not implemented");
342
+ }
343
+ };
344
+
27
345
  // Returns true if dimension d is compatible with the given SIMD level
28
346
  template <SIMDLevel SL2>
29
347
  constexpr bool is_dimension_compatible(size_t d) {
30
- if constexpr (SL2 == SIMDLevel::AVX512) {
348
+ if constexpr (SL2 == SIMDLevel::AVX512 || SL2 == SIMDLevel::AVX512_SPR) {
31
349
  return d % 16 == 0;
32
350
  } else if constexpr (SL2 == SIMDLevel::AVX2 || SL2 == SIMDLevel::ARM_NEON) {
33
351
  return d % 8 == 0;
@@ -85,6 +403,27 @@ ScalarQuantizer::SQuantizer* sq_select_quantizer<THE_LEVEL_TO_DISPATCH>(
85
403
  return new Quantizer8bitDirect<SL>(d, trained);
86
404
  case ScalarQuantizer::QT_8bit_direct_signed:
87
405
  return new Quantizer8bitDirectSigned<SL>(d, trained);
406
+ case ScalarQuantizer::QT_0bit:
407
+ FAISS_THROW_MSG(
408
+ "QT_0bit does not support standalone quantization, use IndexIVFScalarQuantizer");
409
+ case ScalarQuantizer::QT_1bit_tqmse:
410
+ return new QuantizerTurboQuantMSE<1, SL>(d, trained);
411
+ case ScalarQuantizer::QT_2bit_tqmse:
412
+ return new QuantizerTurboQuantMSE<2, SL>(d, trained);
413
+ case ScalarQuantizer::QT_3bit_tqmse:
414
+ return new QuantizerTurboQuantMSE<3, SL>(d, trained);
415
+ case ScalarQuantizer::QT_4bit_tqmse:
416
+ return new QuantizerTurboQuantMSE<4, SL>(d, trained);
417
+ case ScalarQuantizer::QT_8bit_tqmse:
418
+ return new QuantizerTurboQuantMSE<8, SL>(d, trained);
419
+ case ScalarQuantizer::QT_2bit_tq:
420
+ return new QuantizerTurboQuantFull<2, SL>(d, trained);
421
+ case ScalarQuantizer::QT_3bit_tq:
422
+ return new QuantizerTurboQuantFull<3, SL>(d, trained);
423
+ case ScalarQuantizer::QT_4bit_tq:
424
+ return new QuantizerTurboQuantFull<4, SL>(d, trained);
425
+ case ScalarQuantizer::QT_5bit_tq:
426
+ return new QuantizerTurboQuantFull<5, SL>(d, trained);
88
427
  default:
89
428
  FAISS_THROW_MSG("unknown qtype");
90
429
  }
@@ -158,7 +497,8 @@ SQDistanceComputer* select_distance_computer_body(
158
497
  return new DCTemplate<QuantizerBF16<SL2>, Sim, SL2>(d, trained);
159
498
 
160
499
  case ScalarQuantizer::QT_8bit_direct:
161
- if constexpr (SL2 == SIMDLevel::AVX512) {
500
+ if constexpr (
501
+ SL2 == SIMDLevel::AVX512 || SL2 == SIMDLevel::AVX512_SPR) {
162
502
  if (d % 32 == 0) {
163
503
  return new DistanceComputerByte<Sim, SL2>(
164
504
  static_cast<int>(d), trained);
@@ -173,8 +513,42 @@ SQDistanceComputer* select_distance_computer_body(
173
513
  d, trained);
174
514
 
175
515
  case ScalarQuantizer::QT_8bit_direct_signed:
516
+ if constexpr (SL2 == SIMDLevel::AVX512_SPR) {
517
+ if (d % 64 == 0) {
518
+ return new DistanceComputerByteSigned<Sim, SL2>(
519
+ static_cast<int>(d), trained);
520
+ }
521
+ }
176
522
  return new DCTemplate<Quantizer8bitDirectSigned<SL2>, Sim, SL2>(
177
523
  d, trained);
524
+ case ScalarQuantizer::QT_0bit:
525
+ FAISS_THROW_MSG(
526
+ "QT_0bit does not support standalone distance computation, use IndexIVFScalarQuantizer");
527
+ case ScalarQuantizer::QT_1bit_tqmse:
528
+ return new DCTemplate<QuantizerTurboQuantMSE<1, SL2>, Sim, SL2>(
529
+ d, trained);
530
+ case ScalarQuantizer::QT_2bit_tqmse:
531
+ return new DCTemplate<QuantizerTurboQuantMSE<2, SL2>, Sim, SL2>(
532
+ d, trained);
533
+ case ScalarQuantizer::QT_3bit_tqmse:
534
+ return new DCTemplate<QuantizerTurboQuantMSE<3, SL2>, Sim, SL2>(
535
+ d, trained);
536
+ case ScalarQuantizer::QT_4bit_tqmse:
537
+ return new DCTemplate<QuantizerTurboQuantMSE<4, SL2>, Sim, SL2>(
538
+ d, trained);
539
+ case ScalarQuantizer::QT_8bit_tqmse:
540
+ return new DCTemplate<QuantizerTurboQuantMSE<8, SL2>, Sim, SL2>(
541
+ d, trained);
542
+ case ScalarQuantizer::QT_2bit_tq:
543
+ // FRICTION: bypasses DCTemplate entirely — custom DC
544
+ // that doesn't fit the Quantizer+Similarity decomposition
545
+ return new DCTurboQuantFull<2, Sim, SL2>(d, trained);
546
+ case ScalarQuantizer::QT_3bit_tq:
547
+ return new DCTurboQuantFull<3, Sim, SL2>(d, trained);
548
+ case ScalarQuantizer::QT_4bit_tq:
549
+ return new DCTurboQuantFull<4, Sim, SL2>(d, trained);
550
+ case ScalarQuantizer::QT_5bit_tq:
551
+ return new DCTurboQuantFull<5, Sim, SL2>(d, trained);
178
552
  default:
179
553
  FAISS_THROW_MSG("unknown qtype");
180
554
  }
@@ -289,7 +663,9 @@ InvertedListScanner* sq_select_InvertedListScanner<THE_LEVEL_TO_DISPATCH>(
289
663
  return scan.template
290
664
  operator()<DCTemplate<QuantizerBF16<SL2>, Similarity, SL2>>();
291
665
  case ScalarQuantizer::QT_8bit_direct:
292
- if constexpr (SL2 == SIMDLevel::AVX512) {
666
+ if constexpr (
667
+ SL2 == SIMDLevel::AVX512 ||
668
+ SL2 == SIMDLevel::AVX512_SPR) {
293
669
  if (d % 32 == 0) {
294
670
  return scan.template
295
671
  operator()<DistanceComputerByte<Similarity, SL2>>();
@@ -305,10 +681,56 @@ InvertedListScanner* sq_select_InvertedListScanner<THE_LEVEL_TO_DISPATCH>(
305
681
  Similarity,
306
682
  SL2>>();
307
683
  case ScalarQuantizer::QT_8bit_direct_signed:
684
+ if constexpr (SL2 == SIMDLevel::AVX512_SPR) {
685
+ if (d % 64 == 0) {
686
+ return scan.template operator()<
687
+ DistanceComputerByteSigned<Similarity, SL2>>();
688
+ }
689
+ }
308
690
  return scan.template operator()<DCTemplate<
309
691
  Quantizer8bitDirectSigned<SL2>,
310
692
  Similarity,
311
693
  SL2>>();
694
+ case ScalarQuantizer::QT_0bit:
695
+ return new IVFCoarseDistanceScanner(
696
+ Similarity::metric_type != METRIC_L2, store_pairs, sel);
697
+ case ScalarQuantizer::QT_1bit_tqmse:
698
+ return scan.template operator()<DCTemplate<
699
+ QuantizerTurboQuantMSE<1, SL2>,
700
+ Similarity,
701
+ SL2>>();
702
+ case ScalarQuantizer::QT_2bit_tqmse:
703
+ return scan.template operator()<DCTemplate<
704
+ QuantizerTurboQuantMSE<2, SL2>,
705
+ Similarity,
706
+ SL2>>();
707
+ case ScalarQuantizer::QT_3bit_tqmse:
708
+ return scan.template operator()<DCTemplate<
709
+ QuantizerTurboQuantMSE<3, SL2>,
710
+ Similarity,
711
+ SL2>>();
712
+ case ScalarQuantizer::QT_4bit_tqmse:
713
+ return scan.template operator()<DCTemplate<
714
+ QuantizerTurboQuantMSE<4, SL2>,
715
+ Similarity,
716
+ SL2>>();
717
+ case ScalarQuantizer::QT_8bit_tqmse:
718
+ return scan.template operator()<DCTemplate<
719
+ QuantizerTurboQuantMSE<8, SL2>,
720
+ Similarity,
721
+ SL2>>();
722
+ case ScalarQuantizer::QT_2bit_tq:
723
+ return scan.template
724
+ operator()<DCTurboQuantFull<2, Similarity, SL2>>();
725
+ case ScalarQuantizer::QT_3bit_tq:
726
+ return scan.template
727
+ operator()<DCTurboQuantFull<3, Similarity, SL2>>();
728
+ case ScalarQuantizer::QT_4bit_tq:
729
+ return scan.template
730
+ operator()<DCTurboQuantFull<4, Similarity, SL2>>();
731
+ case ScalarQuantizer::QT_5bit_tq:
732
+ return scan.template
733
+ operator()<DCTurboQuantFull<5, Similarity, SL2>>();
312
734
  default:
313
735
  FAISS_THROW_MSG("unknown qtype");
314
736
  }