faiss 0.6.0 → 0.6.1

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 (361) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -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 +84 -92
  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 +87 -415
  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 +283 -145
  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 +465 -362
  41. data/vendor/faiss/faiss/IndexIVF.h +33 -12
  42. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +77 -74
  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 +36 -68
  48. data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
  49. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +53 -30
  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 +71 -843
  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 +21 -17
  56. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +26 -39
  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 +39 -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 +82 -14
  84. data/vendor/faiss/faiss/IndexShards.cpp +10 -9
  85. data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
  86. data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
  87. data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
  88. data/vendor/faiss/faiss/MetaIndexes.h +1 -1
  89. data/vendor/faiss/faiss/MetricType.h +14 -7
  90. data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
  91. data/vendor/faiss/faiss/SuperKMeans.h +97 -0
  92. data/vendor/faiss/faiss/VectorTransform.cpp +237 -149
  93. data/vendor/faiss/faiss/VectorTransform.h +16 -16
  94. data/vendor/faiss/faiss/build.cpp +23 -0
  95. data/vendor/faiss/faiss/build.h +15 -0
  96. data/vendor/faiss/faiss/clone_index.cpp +48 -47
  97. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
  98. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
  99. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
  100. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
  101. data/vendor/faiss/faiss/factory_tools.cpp +5 -0
  102. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
  103. data/vendor/faiss/faiss/gpu/GpuResources.h +1 -1
  104. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +9 -9
  105. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +4 -3
  106. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
  107. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
  108. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
  109. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
  110. data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
  111. data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
  112. data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
  113. data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
  114. data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
  115. data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
  116. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +51 -0
  117. data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
  118. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +66 -0
  119. data/vendor/faiss/faiss/gpu_metal/MetalResources.h +79 -0
  120. data/vendor/faiss/faiss/gpu_metal/StandardMetalResources.h +35 -0
  121. data/vendor/faiss/faiss/impl/AdSampling.cpp +103 -0
  122. data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
  123. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +29 -25
  124. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
  125. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
  126. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -0
  127. data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
  128. data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
  129. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +16 -16
  130. data/vendor/faiss/faiss/impl/CodePacker.cpp +3 -3
  131. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +1 -1
  132. data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
  133. data/vendor/faiss/faiss/impl/FaissAssert.h +6 -3
  134. data/vendor/faiss/faiss/impl/FaissException.h +50 -3
  135. data/vendor/faiss/faiss/impl/HNSW.cpp +92 -317
  136. data/vendor/faiss/faiss/impl/HNSW.h +13 -34
  137. data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
  138. data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
  139. data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
  140. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +82 -77
  141. data/vendor/faiss/faiss/impl/NNDescent.cpp +62 -25
  142. data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
  143. data/vendor/faiss/faiss/impl/NSG.cpp +38 -21
  144. data/vendor/faiss/faiss/impl/NSG.h +4 -4
  145. data/vendor/faiss/faiss/impl/Panorama.cpp +23 -6
  146. data/vendor/faiss/faiss/impl/Panorama.h +258 -87
  147. data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
  148. data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
  149. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +46 -32
  150. data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
  151. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
  152. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
  153. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +30 -23
  154. data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
  155. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +55 -49
  156. data/vendor/faiss/faiss/impl/RaBitQUtils.h +65 -0
  157. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +296 -283
  158. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +26 -23
  159. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
  160. data/vendor/faiss/faiss/impl/ResultHandler.h +99 -75
  161. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +52 -4
  162. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +27 -1
  163. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
  164. data/vendor/faiss/faiss/impl/VisitedTable.h +7 -0
  165. data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
  166. data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
  167. data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
  168. data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
  169. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
  170. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
  171. data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
  172. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
  173. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
  174. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
  175. data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
  176. data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
  177. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
  178. data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
  179. data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
  180. data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
  181. data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
  182. data/vendor/faiss/faiss/impl/expanded_scanners.h +8 -3
  183. data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
  184. data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
  185. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
  186. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
  187. data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
  188. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +268 -0
  189. data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +169 -2
  190. data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
  191. data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
  192. data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
  193. data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
  194. data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
  195. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
  196. data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -356
  197. data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
  198. data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
  199. data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +282 -134
  200. data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
  201. data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
  202. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +91 -0
  203. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -0
  204. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +104 -0
  205. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +111 -0
  206. data/vendor/faiss/faiss/impl/index_read.cpp +1132 -45
  207. data/vendor/faiss/faiss/impl/index_read_utils.h +1 -1
  208. data/vendor/faiss/faiss/impl/index_write.cpp +95 -13
  209. data/vendor/faiss/faiss/impl/io.cpp +6 -6
  210. data/vendor/faiss/faiss/impl/io_macros.h +33 -16
  211. data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
  212. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +37 -23
  213. data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
  214. data/vendor/faiss/faiss/impl/mapped_io.cpp +6 -6
  215. data/vendor/faiss/faiss/impl/platform_macros.h +11 -4
  216. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
  217. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
  218. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
  219. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
  220. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +21 -0
  221. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +21 -0
  222. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +21 -0
  223. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx2.cpp → pq_code_distance-avx2.h} +9 -13
  224. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx512.cpp → pq_code_distance-avx512.h} +9 -57
  225. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +29 -111
  226. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
  227. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +238 -5
  228. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +5 -7
  229. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +68 -0
  230. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +311 -477
  231. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
  232. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +1 -1
  233. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +3 -2
  234. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +102 -11
  235. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +27 -1
  236. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +3 -3
  237. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +148 -0
  238. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +167 -0
  239. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +59 -0
  240. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +163 -0
  241. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +311 -0
  242. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +192 -8
  243. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +12 -0
  244. data/vendor/faiss/faiss/impl/simd_dispatch.h +100 -66
  245. data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
  246. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +264 -172
  247. data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
  248. data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
  249. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
  250. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +270 -218
  251. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
  252. data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
  253. data/vendor/faiss/faiss/impl/svs_io.h +8 -2
  254. data/vendor/faiss/faiss/index_factory.cpp +86 -18
  255. data/vendor/faiss/faiss/index_io.h +24 -0
  256. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +66 -16
  257. data/vendor/faiss/faiss/invlists/DirectMap.cpp +24 -14
  258. data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
  259. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +157 -73
  260. data/vendor/faiss/faiss/invlists/InvertedLists.h +86 -23
  261. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
  262. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +13 -13
  263. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  264. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +1 -1
  265. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
  266. data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
  267. data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
  268. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
  269. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
  270. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
  271. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
  272. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +25 -1
  273. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +18 -2
  274. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +1 -1
  275. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +12 -3
  276. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +7 -2
  277. data/vendor/faiss/faiss/utils/Heap.cpp +10 -10
  278. data/vendor/faiss/faiss/utils/NeuralNet.cpp +47 -36
  279. data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
  280. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
  281. data/vendor/faiss/faiss/utils/distances.cpp +390 -560
  282. data/vendor/faiss/faiss/utils/distances.h +20 -1
  283. data/vendor/faiss/faiss/utils/distances_dispatch.h +117 -37
  284. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
  285. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
  286. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
  287. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
  288. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
  289. data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
  290. data/vendor/faiss/faiss/utils/distances_simd.cpp +5 -177
  291. data/vendor/faiss/faiss/utils/extra_distances.cpp +9 -8
  292. data/vendor/faiss/faiss/utils/extra_distances.h +32 -6
  293. data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
  294. data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
  295. data/vendor/faiss/faiss/utils/hamming.h +92 -2
  296. data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
  297. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +15 -0
  298. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
  299. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
  300. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +234 -0
  301. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-generic.h +368 -0
  302. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +322 -0
  303. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-rvv.h +39 -0
  304. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer.h +146 -0
  305. data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +481 -0
  306. data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +15 -0
  307. data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +15 -0
  308. data/vendor/faiss/faiss/utils/partitioning.cpp +66 -987
  309. data/vendor/faiss/faiss/utils/partitioning.h +31 -0
  310. data/vendor/faiss/faiss/utils/popcount.h +29 -0
  311. data/vendor/faiss/faiss/utils/pq_code_distance.h +2 -2
  312. data/vendor/faiss/faiss/utils/prefetch.h +2 -2
  313. data/vendor/faiss/faiss/utils/quantize_lut.cpp +30 -30
  314. data/vendor/faiss/faiss/utils/quantize_lut.h +1 -1
  315. data/vendor/faiss/faiss/utils/rabitq_simd.h +57 -536
  316. data/vendor/faiss/faiss/utils/random.cpp +6 -6
  317. data/vendor/faiss/faiss/utils/simd_impl/IVFFlatScanner-inl.h +51 -0
  318. data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +5 -1
  319. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +213 -4
  320. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +163 -10
  321. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +250 -4
  322. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +7 -4
  323. data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +189 -0
  324. data/vendor/faiss/faiss/utils/simd_impl/distances_simdlib256.h +195 -0
  325. data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +2 -1
  326. data/vendor/faiss/faiss/utils/{distances_fused/simdlib_based.h → simd_impl/exhaustive_L2sqr_blas_cmax.h} +5 -10
  327. data/vendor/faiss/faiss/utils/simd_impl/hamming_impl.h +481 -0
  328. data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +14 -0
  329. data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +14 -0
  330. data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +1085 -0
  331. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +355 -0
  332. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +477 -0
  333. data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +55 -0
  334. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
  335. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
  336. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
  337. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
  338. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
  339. data/vendor/faiss/faiss/utils/simd_levels.cpp +17 -5
  340. data/vendor/faiss/faiss/utils/simd_levels.h +93 -1
  341. data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
  342. data/vendor/faiss/faiss/utils/utils.cpp +5 -5
  343. data/vendor/faiss/faiss/utils/utils.h +3 -3
  344. metadata +119 -34
  345. data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
  346. data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
  347. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -224
  348. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -230
  349. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
  350. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
  351. data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
  352. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
  353. data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -235
  354. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
  355. data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
  356. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -449
  357. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
  358. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
  359. data/vendor/faiss/faiss/utils/simdlib.h +0 -42
  360. data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -365
  361. /data/ext/faiss/{utils_rb.h → utils.h} +0 -0
@@ -0,0 +1,185 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ /**
11
+ * @file accumulate_loops_512.h
12
+ * @brief 512-bit QBS accumulation loop for AVX512 per-ISA TUs.
13
+ *
14
+ * Mirrors accumulate_loops.h's QBS path but uses pq4_kernel_qbs_512
15
+ * (from kernels_simd512.h) instead of pq4_kernel_qbs_256.
16
+ *
17
+ * The 512-bit kernels produce simd16uint16_tpl<AVX2> results (via
18
+ * combine4x2). FixedStorage512 stores these results without virtual
19
+ * dispatch, then forwards them to the outer handler via
20
+ * to_other_handler().
21
+ *
22
+ * Only included from the AVX512 per-ISA TU (impl-avx512.cpp) via
23
+ * dispatching.h's conditional include.
24
+ */
25
+
26
+ #if defined(COMPILE_SIMD_AVX512) && defined(__AVX512F__)
27
+
28
+ #include <cassert>
29
+
30
+ #include <faiss/impl/FaissAssert.h>
31
+ #include <faiss/impl/fast_scan/accumulate_loops.h>
32
+ #include <faiss/impl/fast_scan/kernels_simd512.h>
33
+ #include <faiss/impl/fast_scan/simd_result_handlers.h>
34
+
35
+ namespace faiss {
36
+
37
+ using namespace simd_result_handlers;
38
+
39
+ /***************************************************************
40
+ * FixedStorage512: non-virtual intermediate result storage
41
+ * for 512-bit kernels.
42
+ *
43
+ * Does NOT inherit from SIMDResultHandler — the virtual handle()
44
+ * signature is pinned to simd16uint16_tpl<NONE> in DD mode, but
45
+ * 512-bit kernels produce simd16uint16_tpl<AVX2>. By avoiding
46
+ * inheritance, handle() can accept AVX2-level types directly.
47
+ *
48
+ * to_other_handler() passes AVX2-level values directly to the
49
+ * outer handler.
50
+ ***************************************************************/
51
+
52
+ template <int NQ, int BB>
53
+ struct FixedStorage512 {
54
+ using simd16uint16_avx2 = simd16uint16_tpl<SIMDLevel::AVX2>;
55
+
56
+ simd16uint16_avx2 dis[NQ][BB];
57
+ int i0 = 0;
58
+
59
+ void handle(
60
+ size_t q,
61
+ size_t b,
62
+ simd16uint16_avx2 d0,
63
+ simd16uint16_avx2 d1) {
64
+ dis[q + i0][2 * b] = d0;
65
+ dis[q + i0][2 * b + 1] = d1;
66
+ }
67
+
68
+ void set_block_origin(size_t i0_in, size_t) {
69
+ this->i0 = i0_in;
70
+ }
71
+
72
+ template <class OtherResultHandler>
73
+ void to_other_handler(OtherResultHandler& other) const {
74
+ for (int q = 0; q < NQ; q++) {
75
+ for (int b = 0; b < BB; b += 2) {
76
+ other.handle(q, b / 2, dis[q][b], dis[q][b + 1]);
77
+ }
78
+ }
79
+ }
80
+ };
81
+
82
+ /***************************************************************
83
+ * QBS path: 512-bit kernel variants
84
+ ***************************************************************/
85
+
86
+ template <int QBS, class ResultHandler, class Scaler>
87
+ void accumulate_q_4step_512(
88
+ size_t ntotal2,
89
+ int nsq,
90
+ const uint8_t* codes,
91
+ const uint8_t* LUT0,
92
+ ResultHandler& res,
93
+ const Scaler& scaler,
94
+ size_t block_stride) {
95
+ constexpr int Q1 = QBS & 15;
96
+ constexpr int Q2 = (QBS >> 4) & 15;
97
+ constexpr int Q3 = (QBS >> 8) & 15;
98
+ constexpr int Q4 = (QBS >> 12) & 15;
99
+ constexpr int SQ = Q1 + Q2 + Q3 + Q4;
100
+
101
+ for_each_block<32>(ntotal2, codes, block_stride, res, [&](size_t) {
102
+ FixedStorage512<SQ, 2> res2;
103
+ const uint8_t* LUT = LUT0;
104
+ pq4_kernel_qbs_512<Q1>(nsq, codes, LUT, res2, scaler);
105
+ LUT += Q1 * nsq * 16;
106
+ if (Q2 > 0) {
107
+ res2.set_block_origin(Q1, 0);
108
+ pq4_kernel_qbs_512<Q2>(nsq, codes, LUT, res2, scaler);
109
+ LUT += Q2 * nsq * 16;
110
+ }
111
+ if (Q3 > 0) {
112
+ res2.set_block_origin(Q1 + Q2, 0);
113
+ pq4_kernel_qbs_512<Q3>(nsq, codes, LUT, res2, scaler);
114
+ LUT += Q3 * nsq * 16;
115
+ }
116
+ if (Q4 > 0) {
117
+ res2.set_block_origin(Q1 + Q2 + Q3, 0);
118
+ pq4_kernel_qbs_512<Q4>(nsq, codes, LUT, res2, scaler);
119
+ }
120
+ res2.to_other_handler(res);
121
+ });
122
+ }
123
+
124
+ template <class ResultHandler, class Scaler>
125
+ void pq4_accumulate_loop_qbs_fixed_scaler_512(
126
+ int qbs,
127
+ size_t ntotal2,
128
+ int nsq,
129
+ const uint8_t* codes,
130
+ const uint8_t* LUT0,
131
+ ResultHandler& res,
132
+ const Scaler& scaler,
133
+ size_t block_stride) {
134
+ assert(nsq % 2 == 0);
135
+ assert(is_aligned_pointer(codes));
136
+ assert(is_aligned_pointer(LUT0));
137
+
138
+ switch (qbs) {
139
+ #define FAISS_QBS512_DISPATCH(QBS) \
140
+ case QBS: \
141
+ accumulate_q_4step_512<QBS>( \
142
+ ntotal2, nsq, codes, LUT0, res, scaler, block_stride); \
143
+ return;
144
+ FAISS_QBS512_DISPATCH(0x3333); // 12
145
+ FAISS_QBS512_DISPATCH(0x2333); // 11
146
+ FAISS_QBS512_DISPATCH(0x2233); // 10
147
+ FAISS_QBS512_DISPATCH(0x333); // 9
148
+ FAISS_QBS512_DISPATCH(0x2223); // 9
149
+ FAISS_QBS512_DISPATCH(0x233); // 8
150
+ FAISS_QBS512_DISPATCH(0x1223); // 8
151
+ FAISS_QBS512_DISPATCH(0x223); // 7
152
+ FAISS_QBS512_DISPATCH(0x34); // 7
153
+ FAISS_QBS512_DISPATCH(0x133); // 7
154
+ FAISS_QBS512_DISPATCH(0x6); // 6
155
+ FAISS_QBS512_DISPATCH(0x33); // 6
156
+ FAISS_QBS512_DISPATCH(0x123); // 6
157
+ FAISS_QBS512_DISPATCH(0x222); // 6
158
+ FAISS_QBS512_DISPATCH(0x23); // 5
159
+ FAISS_QBS512_DISPATCH(0x5); // 5
160
+ FAISS_QBS512_DISPATCH(0x13); // 4
161
+ FAISS_QBS512_DISPATCH(0x22); // 4
162
+ FAISS_QBS512_DISPATCH(0x4); // 4
163
+ FAISS_QBS512_DISPATCH(0x3); // 3
164
+ FAISS_QBS512_DISPATCH(0x21); // 3
165
+ FAISS_QBS512_DISPATCH(0x2); // 2
166
+ FAISS_QBS512_DISPATCH(0x1); // 1
167
+ #undef FAISS_QBS512_DISPATCH
168
+ }
169
+
170
+ // Fallback for unknown QBS values: use 256-bit path.
171
+ // This is rare — pq4_preferred_qbs() covers all values above.
172
+ if constexpr (Scaler::nscale == 0) {
173
+ DummyScaler<SIMDLevel::AVX2> scaler_avx2;
174
+ pq4_accumulate_loop_qbs_fixed_scaler_256<SIMDLevel::AVX2>(
175
+ qbs, ntotal2, nsq, codes, LUT0, res, scaler_avx2, block_stride);
176
+ } else {
177
+ NormTableScaler<SIMDLevel::AVX2> scaler_avx2(scaler.scale_int);
178
+ pq4_accumulate_loop_qbs_fixed_scaler_256<SIMDLevel::AVX2>(
179
+ qbs, ntotal2, nsq, codes, LUT0, res, scaler_avx2, block_stride);
180
+ }
181
+ }
182
+
183
+ } // namespace faiss
184
+
185
+ #endif // COMPILE_SIMD_AVX512 && __AVX512F__
@@ -0,0 +1,229 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include <cassert>
11
+
12
+ #include <faiss/impl/FaissAssert.h>
13
+ #include <faiss/impl/fast_scan/kernels_simd256.h>
14
+ #include <faiss/impl/fast_scan/kernels_simd512.h>
15
+ #include <faiss/impl/fast_scan/simd_result_handlers.h>
16
+
17
+ namespace faiss {
18
+
19
+ using namespace simd_result_handlers;
20
+
21
+ /*
22
+ * Unified kernel: selects 256-bit vs 512-bit path based on
23
+ * compile-time __AVX512F__ guard.
24
+ *
25
+ * KernelSL selects the SIMD type width used for the inner accumulation
26
+ * loop. In DD mode the caller passes the dispatch level so the kernel
27
+ * uses real AVX2 types rather than the emulated-scalar fallback.
28
+ */
29
+ template <
30
+ int NQ,
31
+ SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
32
+ class ResultHandler,
33
+ class Scaler>
34
+ void kernel_accumulate_block(
35
+ int nsq,
36
+ const uint8_t* codes,
37
+ const uint8_t* LUT,
38
+ ResultHandler& res,
39
+ const Scaler& scaler) {
40
+ #ifdef __AVX512F__
41
+ if constexpr (
42
+ KernelSL == SIMDLevel::AVX512 ||
43
+ KernelSL == SIMDLevel::AVX512_SPR) {
44
+ pq4_kernel_qbs_512<NQ>(nsq, codes, LUT, res, scaler);
45
+ } else {
46
+ pq4_kernel_qbs_256<NQ, KernelSL>(nsq, codes, LUT, res, scaler);
47
+ }
48
+ #else
49
+ pq4_kernel_qbs_256<NQ, KernelSL>(nsq, codes, LUT, res, scaler);
50
+ #endif
51
+ }
52
+
53
+ // handle at most 4 blocks of queries
54
+ template <
55
+ int QBS,
56
+ SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
57
+ class ResultHandler,
58
+ class Scaler>
59
+ void accumulate_q_4step(
60
+ size_t ntotal2,
61
+ int nsq,
62
+ const uint8_t* codes,
63
+ const uint8_t* LUT0,
64
+ ResultHandler& res,
65
+ const Scaler& scaler,
66
+ size_t block_stride) {
67
+ constexpr int Q1 = QBS & 15;
68
+ constexpr int Q2 = (QBS >> 4) & 15;
69
+ constexpr int Q3 = (QBS >> 8) & 15;
70
+ constexpr int Q4 = (QBS >> 12) & 15;
71
+ constexpr int SQ = Q1 + Q2 + Q3 + Q4;
72
+
73
+ for_each_block<32>(ntotal2, codes, block_stride, res, [&](size_t) {
74
+ FixedStorageHandler<SQ, 2, KernelSL> res2;
75
+ const uint8_t* LUT = LUT0;
76
+ kernel_accumulate_block<Q1, KernelSL>(nsq, codes, LUT, res2, scaler);
77
+ LUT += Q1 * nsq * 16;
78
+ if (Q2 > 0) {
79
+ res2.set_block_origin(Q1, 0);
80
+ kernel_accumulate_block<Q2, KernelSL>(
81
+ nsq, codes, LUT, res2, scaler);
82
+ LUT += Q2 * nsq * 16;
83
+ }
84
+ if (Q3 > 0) {
85
+ res2.set_block_origin(Q1 + Q2, 0);
86
+ kernel_accumulate_block<Q3, KernelSL>(
87
+ nsq, codes, LUT, res2, scaler);
88
+ LUT += Q3 * nsq * 16;
89
+ }
90
+ if (Q4 > 0) {
91
+ res2.set_block_origin(Q1 + Q2 + Q3, 0);
92
+ kernel_accumulate_block<Q4, KernelSL>(
93
+ nsq, codes, LUT, res2, scaler);
94
+ }
95
+ res2.to_other_handler(res);
96
+ });
97
+ }
98
+
99
+ template <
100
+ int NQ,
101
+ SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
102
+ class ResultHandler,
103
+ class Scaler>
104
+ void kernel_accumulate_block_loop(
105
+ size_t ntotal2,
106
+ int nsq,
107
+ const uint8_t* codes,
108
+ const uint8_t* LUT,
109
+ ResultHandler& res,
110
+ const Scaler& scaler,
111
+ size_t block_stride) {
112
+ for_each_block<32>(ntotal2, codes, block_stride, res, [&](size_t) {
113
+ kernel_accumulate_block<NQ, KernelSL>(nsq, codes, LUT, res, scaler);
114
+ });
115
+ }
116
+
117
+ // non-template version of accumulate kernel -- dispatches dynamically
118
+ template <
119
+ SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
120
+ class ResultHandler,
121
+ class Scaler>
122
+ void accumulate(
123
+ int nq,
124
+ size_t ntotal2,
125
+ int nsq,
126
+ const uint8_t* codes,
127
+ const uint8_t* LUT,
128
+ ResultHandler& res,
129
+ const Scaler& scaler,
130
+ size_t block_stride) {
131
+ assert(nsq % 2 == 0);
132
+ assert(is_aligned_pointer(LUT));
133
+
134
+ #define DISPATCH(NQ) \
135
+ case NQ: \
136
+ kernel_accumulate_block_loop<NQ, KernelSL>( \
137
+ ntotal2, nsq, codes, LUT, res, scaler, block_stride); \
138
+ return
139
+
140
+ switch (nq) {
141
+ DISPATCH(1);
142
+ DISPATCH(2);
143
+ DISPATCH(3);
144
+ DISPATCH(4);
145
+ }
146
+ FAISS_THROW_FMT("accumulate nq=%d not instantiated", nq);
147
+
148
+ #undef DISPATCH
149
+ }
150
+
151
+ template <
152
+ SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
153
+ class ResultHandler,
154
+ class Scaler>
155
+ void pq4_accumulate_loop_qbs_fixed_scaler(
156
+ int qbs,
157
+ size_t ntotal2,
158
+ int nsq,
159
+ const uint8_t* codes,
160
+ const uint8_t* LUT0,
161
+ ResultHandler& res,
162
+ const Scaler& scaler,
163
+ size_t block_stride = 0) {
164
+ assert(nsq % 2 == 0);
165
+ assert(is_aligned_pointer(codes));
166
+ assert(is_aligned_pointer(LUT0));
167
+
168
+ // try out optimized versions
169
+ switch (qbs) {
170
+ #define DISPATCH(QBS) \
171
+ case QBS: \
172
+ accumulate_q_4step<QBS, KernelSL>( \
173
+ ntotal2, nsq, codes, LUT0, res, scaler, block_stride); \
174
+ return;
175
+ DISPATCH(0x3333); // 12
176
+ DISPATCH(0x2333); // 11
177
+ DISPATCH(0x2233); // 10
178
+ DISPATCH(0x333); // 9
179
+ DISPATCH(0x2223); // 9
180
+ DISPATCH(0x233); // 8
181
+ DISPATCH(0x1223); // 8
182
+ DISPATCH(0x223); // 7
183
+ DISPATCH(0x34); // 7
184
+ DISPATCH(0x133); // 7
185
+ DISPATCH(0x6); // 6
186
+ DISPATCH(0x33); // 6
187
+ DISPATCH(0x123); // 6
188
+ DISPATCH(0x222); // 6
189
+ DISPATCH(0x23); // 5
190
+ DISPATCH(0x5); // 5
191
+ DISPATCH(0x13); // 4
192
+ DISPATCH(0x22); // 4
193
+ DISPATCH(0x4); // 4
194
+ DISPATCH(0x3); // 3
195
+ DISPATCH(0x21); // 3
196
+ DISPATCH(0x2); // 2
197
+ DISPATCH(0x1); // 1
198
+ #undef DISPATCH
199
+ }
200
+
201
+ // default implementation where qbs is not known at compile time
202
+ for_each_block<32>(ntotal2, codes, block_stride, res, [&](size_t j0) {
203
+ const uint8_t* LUT = LUT0;
204
+ int qi = qbs;
205
+ int i0 = 0;
206
+ while (qi) {
207
+ int nq = qi & 15;
208
+ qi >>= 4;
209
+ res.set_block_origin(i0, j0);
210
+ #define DISPATCH(NQ) \
211
+ case NQ: \
212
+ kernel_accumulate_block<NQ, KernelSL>(nsq, codes, LUT, res, scaler); \
213
+ break
214
+ switch (nq) {
215
+ DISPATCH(1);
216
+ DISPATCH(2);
217
+ DISPATCH(3);
218
+ DISPATCH(4);
219
+ #undef DISPATCH
220
+ default:
221
+ FAISS_THROW_FMT("accumulate nq=%d not instantiated", nq);
222
+ }
223
+ i0 += nq;
224
+ LUT += nq * nsq * 16;
225
+ }
226
+ });
227
+ }
228
+
229
+ } // namespace faiss
@@ -0,0 +1,268 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ /**
11
+ * @file dispatching.h
12
+ * @brief Per-SIMD TU dispatch template for fast scan.
13
+ *
14
+ * This header is included once per SIMD TU with THE_LEVEL_TO_DISPATCH
15
+ * set to the desired SIMDLevel. It provides:
16
+ * - ScannerMixIn: wraps a handler + calls kernel at the TU's SIMD level
17
+ * - make_fast_scan_scanner_impl<SL>: factory specialization
18
+ *
19
+ * Usage (in a per-SIMD .cpp file):
20
+ * #define THE_LEVEL_TO_DISPATCH SIMDLevel::AVX2
21
+ * #include <faiss/impl/fast_scan/dispatching.h>
22
+ *
23
+ * Kernel helpers come from accumulate_loops.h (search_1 multi-BB path
24
+ * and QBS 256-bit path) and accumulate_loops_512.h (QBS 512-bit path,
25
+ * AVX512 TU only).
26
+ */
27
+
28
+ #ifndef THE_LEVEL_TO_DISPATCH
29
+ #error "Define THE_LEVEL_TO_DISPATCH before including this header"
30
+ #endif
31
+
32
+ #include <memory>
33
+
34
+ #include <faiss/impl/fast_scan/accumulate_loops.h>
35
+ #include <faiss/impl/fast_scan/fast_scan.h>
36
+
37
+ #if defined(COMPILE_SIMD_AVX512) && defined(__AVX512F__)
38
+ #include <faiss/impl/fast_scan/accumulate_loops_512.h>
39
+ #endif
40
+
41
+ namespace faiss {
42
+
43
+ using namespace simd_result_handlers;
44
+
45
+ /***************************************************************
46
+ * ScannerMixIn: wraps a concrete handler + calls accumulation
47
+ * kernels. Lives behind the virtual FastScanCodeScanner interface
48
+ * so callers don't need to know the handler type.
49
+ ***************************************************************/
50
+
51
+ template <class Handler>
52
+ struct ScannerMixIn : FastScanCodeScanner {
53
+ Handler handler_;
54
+
55
+ template <typename... Args>
56
+ explicit ScannerMixIn(Args&&... args)
57
+ : handler_(std::forward<Args>(args)...) {}
58
+
59
+ SIMDResultHandlerToFloat* handler() override {
60
+ return &handler_;
61
+ }
62
+
63
+ void accumulate_loop(
64
+ int nq,
65
+ size_t nb,
66
+ int bbs,
67
+ int nsq,
68
+ const uint8_t* codes,
69
+ const uint8_t* LUT,
70
+ int pq2x4_scale,
71
+ size_t block_stride) override {
72
+ if (pq2x4_scale) {
73
+ NormTableScaler<THE_LEVEL_TO_DISPATCH> scaler(pq2x4_scale);
74
+ pq4_accumulate_loop_fixed_scaler<THE_LEVEL_TO_DISPATCH>(
75
+ nq,
76
+ nb,
77
+ bbs,
78
+ nsq,
79
+ codes,
80
+ LUT,
81
+ handler_,
82
+ scaler,
83
+ block_stride);
84
+ } else {
85
+ DummyScaler<THE_LEVEL_TO_DISPATCH> dummy;
86
+ pq4_accumulate_loop_fixed_scaler<THE_LEVEL_TO_DISPATCH>(
87
+ nq,
88
+ nb,
89
+ bbs,
90
+ nsq,
91
+ codes,
92
+ LUT,
93
+ handler_,
94
+ dummy,
95
+ block_stride);
96
+ }
97
+ }
98
+
99
+ void accumulate_loop_qbs(
100
+ int qbs,
101
+ size_t nb,
102
+ int nsq,
103
+ const uint8_t* codes,
104
+ const uint8_t* LUT,
105
+ int pq2x4_scale,
106
+ size_t block_stride) override {
107
+ #if defined(COMPILE_SIMD_AVX512) && defined(__AVX512F__)
108
+ constexpr bool use_avx512_qbs =
109
+ (THE_LEVEL_TO_DISPATCH == SIMDLevel::AVX512 ||
110
+ THE_LEVEL_TO_DISPATCH == SIMDLevel::AVX512_SPR);
111
+ #else
112
+ constexpr bool use_avx512_qbs = false;
113
+ #endif
114
+ if constexpr (use_avx512_qbs) {
115
+ // Use 512-bit QBS kernels with properly-leveled scalers.
116
+ if (pq2x4_scale) {
117
+ NormTableScaler<THE_LEVEL_TO_DISPATCH> scaler(pq2x4_scale);
118
+ pq4_accumulate_loop_qbs_fixed_scaler_512(
119
+ qbs,
120
+ nb,
121
+ nsq,
122
+ codes,
123
+ LUT,
124
+ handler_,
125
+ scaler,
126
+ block_stride);
127
+ } else {
128
+ DummyScaler<THE_LEVEL_TO_DISPATCH> dummy;
129
+ pq4_accumulate_loop_qbs_fixed_scaler_512(
130
+ qbs,
131
+ nb,
132
+ nsq,
133
+ codes,
134
+ LUT,
135
+ handler_,
136
+ dummy,
137
+ block_stride);
138
+ }
139
+ } else {
140
+ if (pq2x4_scale) {
141
+ NormTableScaler<THE_LEVEL_TO_DISPATCH> scaler(pq2x4_scale);
142
+ pq4_accumulate_loop_qbs_fixed_scaler_256<THE_LEVEL_TO_DISPATCH>(
143
+ qbs,
144
+ nb,
145
+ nsq,
146
+ codes,
147
+ LUT,
148
+ handler_,
149
+ scaler,
150
+ block_stride);
151
+ } else {
152
+ DummyScaler<THE_LEVEL_TO_DISPATCH> dummy;
153
+ pq4_accumulate_loop_qbs_fixed_scaler_256<THE_LEVEL_TO_DISPATCH>(
154
+ qbs,
155
+ nb,
156
+ nsq,
157
+ codes,
158
+ LUT,
159
+ handler_,
160
+ dummy,
161
+ block_stride);
162
+ }
163
+ }
164
+ }
165
+ };
166
+
167
+ /***************************************************************
168
+ * Factory specialization for this SIMD level.
169
+ *
170
+ * Combinatorial dispatch: is_max × with_id_map × handler type
171
+ * k == 1: SingleResultHandler
172
+ * impl even: HeapHandler
173
+ * impl odd: ReservoirHandler (capacity = 2*k)
174
+ ***************************************************************/
175
+
176
+ template <>
177
+ std::unique_ptr<FastScanCodeScanner> make_fast_scan_scanner_impl<
178
+ THE_LEVEL_TO_DISPATCH>(
179
+ bool is_max,
180
+ int impl,
181
+ size_t nq,
182
+ size_t ntotal,
183
+ int64_t k,
184
+ float* distances,
185
+ int64_t* ids,
186
+ const IDSelector* sel,
187
+ bool with_id_map) {
188
+ // Helper lambda: given comparator C and with_id_map W, select handler
189
+ auto make = [&]<class C, bool W>() -> std::unique_ptr<FastScanCodeScanner> {
190
+ if (k == 1) {
191
+ using H = SingleResultHandler<C, W, THE_LEVEL_TO_DISPATCH>;
192
+ return std::make_unique<ScannerMixIn<H>>(
193
+ nq, ntotal, distances, ids, sel);
194
+ } else if (impl % 2 == 0) {
195
+ using H = HeapHandler<C, W, THE_LEVEL_TO_DISPATCH>;
196
+ return std::make_unique<ScannerMixIn<H>>(
197
+ nq, ntotal, k, distances, ids, sel);
198
+ } else {
199
+ using H = ReservoirHandler<C, W, THE_LEVEL_TO_DISPATCH>;
200
+ return std::make_unique<ScannerMixIn<H>>(
201
+ nq, ntotal, size_t(k), size_t(2 * k), distances, ids, sel);
202
+ }
203
+ };
204
+
205
+ if (is_max) {
206
+ if (with_id_map) {
207
+ return make.template operator()<CMax<uint16_t, int64_t>, true>();
208
+ } else {
209
+ return make.template operator()<CMax<uint16_t, int>, false>();
210
+ }
211
+ } else {
212
+ if (with_id_map) {
213
+ return make.template operator()<CMin<uint16_t, int64_t>, true>();
214
+ } else {
215
+ return make.template operator()<CMin<uint16_t, int>, false>();
216
+ }
217
+ }
218
+ }
219
+
220
+ /***************************************************************
221
+ * Range search scanner factories.
222
+ ***************************************************************/
223
+
224
+ template <>
225
+ std::unique_ptr<FastScanCodeScanner> make_range_scanner_impl<
226
+ THE_LEVEL_TO_DISPATCH>(
227
+ bool is_max,
228
+ RangeSearchResult& rres,
229
+ float radius,
230
+ size_t ntotal,
231
+ const IDSelector* sel) {
232
+ if (is_max) {
233
+ using C = CMax<uint16_t, int64_t>;
234
+ return std::make_unique<
235
+ ScannerMixIn<RangeHandler<C, true, THE_LEVEL_TO_DISPATCH>>>(
236
+ rres, radius, ntotal, sel);
237
+ } else {
238
+ using C = CMin<uint16_t, int64_t>;
239
+ return std::make_unique<
240
+ ScannerMixIn<RangeHandler<C, true, THE_LEVEL_TO_DISPATCH>>>(
241
+ rres, radius, ntotal, sel);
242
+ }
243
+ }
244
+
245
+ template <>
246
+ std::unique_ptr<FastScanCodeScanner> make_partial_range_scanner_impl<
247
+ THE_LEVEL_TO_DISPATCH>(
248
+ bool is_max,
249
+ RangeSearchPartialResult& pres,
250
+ float radius,
251
+ size_t ntotal,
252
+ size_t q0,
253
+ size_t q1,
254
+ const IDSelector* sel) {
255
+ if (is_max) {
256
+ using C = CMax<uint16_t, int64_t>;
257
+ return std::make_unique<ScannerMixIn<
258
+ PartialRangeHandler<C, true, THE_LEVEL_TO_DISPATCH>>>(
259
+ pres, radius, ntotal, q0, q1, sel);
260
+ } else {
261
+ using C = CMin<uint16_t, int64_t>;
262
+ return std::make_unique<ScannerMixIn<
263
+ PartialRangeHandler<C, true, THE_LEVEL_TO_DISPATCH>>>(
264
+ pres, radius, ntotal, q0, q1, sel);
265
+ }
266
+ }
267
+
268
+ } // namespace faiss