faiss 0.5.3 → 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 (379) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/ext/faiss/ext.cpp +1 -1
  4. data/ext/faiss/extconf.rb +4 -4
  5. data/ext/faiss/index.cpp +63 -45
  6. data/ext/faiss/index_binary.cpp +37 -27
  7. data/ext/faiss/kmeans.cpp +9 -8
  8. data/ext/faiss/pca_matrix.cpp +9 -7
  9. data/ext/faiss/product_quantizer.cpp +13 -11
  10. data/ext/faiss/utils.cpp +4 -2
  11. data/ext/faiss/utils.h +4 -0
  12. data/lib/faiss/version.rb +1 -1
  13. data/lib/faiss.rb +1 -1
  14. data/vendor/faiss/faiss/AutoTune.cpp +214 -82
  15. data/vendor/faiss/faiss/AutoTune.h +14 -1
  16. data/vendor/faiss/faiss/Clustering.cpp +97 -249
  17. data/vendor/faiss/faiss/Clustering.h +18 -0
  18. data/vendor/faiss/faiss/IVFlib.cpp +67 -44
  19. data/vendor/faiss/faiss/Index.cpp +25 -12
  20. data/vendor/faiss/faiss/Index.h +26 -4
  21. data/vendor/faiss/faiss/Index2Layer.cpp +37 -53
  22. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +68 -61
  23. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +36 -34
  24. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +4 -1
  25. data/vendor/faiss/faiss/IndexBinary.cpp +6 -3
  26. data/vendor/faiss/faiss/IndexBinary.h +4 -4
  27. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +1 -1
  28. data/vendor/faiss/faiss/IndexBinaryFlat.h +1 -1
  29. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -4
  30. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +92 -95
  31. data/vendor/faiss/faiss/IndexBinaryHNSW.h +9 -3
  32. data/vendor/faiss/faiss/IndexBinaryHash.cpp +45 -236
  33. data/vendor/faiss/faiss/IndexBinaryHash.h +6 -6
  34. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +120 -414
  35. data/vendor/faiss/faiss/IndexFastScan.cpp +105 -129
  36. data/vendor/faiss/faiss/IndexFastScan.h +35 -24
  37. data/vendor/faiss/faiss/IndexFlat.cpp +216 -152
  38. data/vendor/faiss/faiss/IndexFlat.h +32 -14
  39. data/vendor/faiss/faiss/IndexFlatCodes.cpp +88 -41
  40. data/vendor/faiss/faiss/IndexFlatCodes.h +7 -1
  41. data/vendor/faiss/faiss/IndexHNSW.cpp +299 -187
  42. data/vendor/faiss/faiss/IndexHNSW.h +30 -14
  43. data/vendor/faiss/faiss/IndexIDMap.cpp +26 -22
  44. data/vendor/faiss/faiss/IndexIDMap.h +9 -7
  45. data/vendor/faiss/faiss/IndexIVF.cpp +535 -405
  46. data/vendor/faiss/faiss/IndexIVF.h +47 -16
  47. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +77 -74
  48. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +105 -99
  49. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +6 -3
  50. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +379 -249
  51. data/vendor/faiss/faiss/IndexIVFFastScan.h +65 -60
  52. data/vendor/faiss/faiss/IndexIVFFlat.cpp +41 -124
  53. data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
  54. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +89 -138
  55. data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
  56. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
  57. data/vendor/faiss/faiss/IndexIVFPQ.cpp +77 -907
  58. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +184 -122
  59. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
  60. data/vendor/faiss/faiss/IndexIVFPQR.cpp +23 -18
  61. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +59 -60
  62. data/vendor/faiss/faiss/IndexIVFRaBitQ.h +4 -3
  63. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +564 -416
  64. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +269 -111
  65. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +41 -127
  66. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
  67. data/vendor/faiss/faiss/IndexLSH.cpp +44 -25
  68. data/vendor/faiss/faiss/IndexLattice.cpp +41 -36
  69. data/vendor/faiss/faiss/IndexNNDescent.cpp +37 -21
  70. data/vendor/faiss/faiss/IndexNNDescent.h +2 -2
  71. data/vendor/faiss/faiss/IndexNSG.cpp +40 -23
  72. data/vendor/faiss/faiss/IndexNSG.h +0 -2
  73. data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +32 -12
  74. data/vendor/faiss/faiss/IndexPQ.cpp +129 -213
  75. data/vendor/faiss/faiss/IndexPQ.h +3 -2
  76. data/vendor/faiss/faiss/IndexPQFastScan.cpp +20 -14
  77. data/vendor/faiss/faiss/IndexPQFastScan.h +3 -0
  78. data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -18
  79. data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
  80. data/vendor/faiss/faiss/IndexRaBitQ.cpp +31 -43
  81. data/vendor/faiss/faiss/IndexRaBitQ.h +4 -3
  82. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +135 -317
  83. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +192 -34
  84. data/vendor/faiss/faiss/IndexRefine.cpp +30 -55
  85. data/vendor/faiss/faiss/IndexRefine.h +4 -4
  86. data/vendor/faiss/faiss/IndexReplicas.cpp +6 -6
  87. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +15 -14
  88. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +1 -1
  89. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +82 -14
  90. data/vendor/faiss/faiss/IndexShards.cpp +13 -13
  91. data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
  92. data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
  93. data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
  94. data/vendor/faiss/faiss/MetaIndexes.h +1 -1
  95. data/vendor/faiss/faiss/MetricType.h +29 -6
  96. data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
  97. data/vendor/faiss/faiss/SuperKMeans.h +97 -0
  98. data/vendor/faiss/faiss/VectorTransform.cpp +349 -141
  99. data/vendor/faiss/faiss/VectorTransform.h +39 -16
  100. data/vendor/faiss/faiss/build.cpp +23 -0
  101. data/vendor/faiss/faiss/build.h +15 -0
  102. data/vendor/faiss/faiss/clone_index.cpp +55 -51
  103. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
  104. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
  105. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
  106. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
  107. data/vendor/faiss/faiss/{cppcontrib/factory_tools.cpp → factory_tools.cpp} +6 -1
  108. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +1 -1
  109. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
  110. data/vendor/faiss/faiss/gpu/GpuResources.h +1 -1
  111. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +9 -9
  112. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +4 -3
  113. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
  114. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
  115. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
  116. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
  117. data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
  118. data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
  119. data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
  120. data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
  121. data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
  122. data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
  123. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +51 -0
  124. data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
  125. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +66 -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/impl/AdSampling.cpp +103 -0
  129. data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
  130. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +64 -34
  131. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
  132. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
  133. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -28
  134. data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
  135. data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
  136. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +367 -0
  137. data/vendor/faiss/faiss/impl/ClusteringInitialization.h +107 -0
  138. data/vendor/faiss/faiss/impl/CodePacker.cpp +7 -3
  139. data/vendor/faiss/faiss/impl/CodePacker.h +11 -3
  140. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +83 -0
  141. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.h +47 -0
  142. data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
  143. data/vendor/faiss/faiss/impl/FaissAssert.h +64 -3
  144. data/vendor/faiss/faiss/impl/FaissException.h +50 -3
  145. data/vendor/faiss/faiss/impl/HNSW.cpp +117 -351
  146. data/vendor/faiss/faiss/impl/HNSW.h +21 -40
  147. data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
  148. data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
  149. data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
  150. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +114 -102
  151. data/vendor/faiss/faiss/impl/NNDescent.cpp +63 -26
  152. data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
  153. data/vendor/faiss/faiss/impl/NSG.cpp +44 -26
  154. data/vendor/faiss/faiss/impl/NSG.h +20 -10
  155. data/vendor/faiss/faiss/impl/Panorama.cpp +76 -52
  156. data/vendor/faiss/faiss/impl/Panorama.h +265 -78
  157. data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
  158. data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
  159. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +62 -37
  160. data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
  161. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
  162. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
  163. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +99 -80
  164. data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
  165. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +135 -37
  166. data/vendor/faiss/faiss/impl/RaBitQUtils.h +148 -21
  167. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +298 -301
  168. data/vendor/faiss/faiss/impl/RaBitQuantizer.h +3 -10
  169. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +15 -41
  170. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.h +0 -4
  171. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +40 -32
  172. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
  173. data/vendor/faiss/faiss/impl/ResultHandler.h +218 -113
  174. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +119 -2362
  175. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +27 -3
  176. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
  177. data/vendor/faiss/faiss/impl/VisitedTable.cpp +42 -0
  178. data/vendor/faiss/faiss/impl/VisitedTable.h +76 -0
  179. data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
  180. data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
  181. data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
  182. data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
  183. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
  184. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
  185. data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
  186. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
  187. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
  188. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
  189. data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
  190. data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
  191. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
  192. data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
  193. data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
  194. data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
  195. data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
  196. data/vendor/faiss/faiss/impl/expanded_scanners.h +163 -0
  197. data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
  198. data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
  199. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
  200. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
  201. data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
  202. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +268 -0
  203. data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +176 -4
  204. data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
  205. data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
  206. data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
  207. data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
  208. data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
  209. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
  210. data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -348
  211. data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
  212. data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
  213. data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +290 -142
  214. data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
  215. data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
  216. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +91 -0
  217. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -0
  218. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +104 -0
  219. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +111 -0
  220. data/vendor/faiss/faiss/impl/index_read.cpp +1950 -505
  221. data/vendor/faiss/faiss/impl/index_read_utils.h +1 -2
  222. data/vendor/faiss/faiss/impl/index_write.cpp +112 -21
  223. data/vendor/faiss/faiss/impl/io.cpp +6 -6
  224. data/vendor/faiss/faiss/impl/io_macros.h +33 -16
  225. data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
  226. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +81 -40
  227. data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
  228. data/vendor/faiss/faiss/impl/mapped_io.cpp +15 -8
  229. data/vendor/faiss/faiss/impl/platform_macros.h +11 -4
  230. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
  231. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
  232. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
  233. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
  234. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +21 -0
  235. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +21 -0
  236. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +21 -0
  237. data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx2.h → pq_code_distance/pq_code_distance-avx2.h} +43 -220
  238. data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx512.h → pq_code_distance/pq_code_distance-avx512.h} +25 -112
  239. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +59 -0
  240. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
  241. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +256 -0
  242. data/vendor/faiss/faiss/impl/{code_distance/code_distance-sve.h → pq_code_distance/pq_code_distance-sve.cpp} +57 -146
  243. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +68 -0
  244. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +320 -483
  245. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
  246. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +121 -0
  247. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +137 -0
  248. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +371 -0
  249. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +190 -0
  250. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +94 -0
  251. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +603 -0
  252. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +597 -0
  253. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +388 -0
  254. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +630 -0
  255. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +311 -0
  256. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +387 -0
  257. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +54 -0
  258. data/vendor/faiss/faiss/impl/simd_dispatch.h +173 -0
  259. data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
  260. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +274 -171
  261. data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
  262. data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
  263. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
  264. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +275 -217
  265. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
  266. data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
  267. data/vendor/faiss/faiss/impl/svs_io.h +8 -2
  268. data/vendor/faiss/faiss/index_factory.cpp +115 -28
  269. data/vendor/faiss/faiss/index_io.h +53 -3
  270. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +73 -20
  271. data/vendor/faiss/faiss/invlists/DirectMap.cpp +24 -14
  272. data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
  273. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +157 -73
  274. data/vendor/faiss/faiss/invlists/InvertedLists.h +86 -23
  275. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
  276. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +14 -14
  277. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  278. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +9 -19
  279. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
  280. data/vendor/faiss/faiss/svs/IndexSVSFlat.h +2 -0
  281. data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
  282. data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
  283. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
  284. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
  285. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
  286. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
  287. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +25 -1
  288. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +19 -2
  289. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +1 -1
  290. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +19 -2
  291. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +14 -0
  292. data/vendor/faiss/faiss/utils/Heap.cpp +56 -10
  293. data/vendor/faiss/faiss/utils/Heap.h +21 -0
  294. data/vendor/faiss/faiss/utils/NeuralNet.cpp +54 -40
  295. data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
  296. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
  297. data/vendor/faiss/faiss/utils/distances.cpp +507 -559
  298. data/vendor/faiss/faiss/utils/distances.h +118 -1
  299. data/vendor/faiss/faiss/utils/distances_dispatch.h +250 -0
  300. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
  301. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
  302. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
  303. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
  304. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
  305. data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
  306. data/vendor/faiss/faiss/utils/distances_simd.cpp +72 -3681
  307. data/vendor/faiss/faiss/utils/extra_distances.cpp +60 -102
  308. data/vendor/faiss/faiss/utils/extra_distances.h +79 -7
  309. data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
  310. data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
  311. data/vendor/faiss/faiss/utils/hamming.h +92 -2
  312. data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
  313. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +15 -0
  314. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
  315. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
  316. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +234 -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 -987
  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 +251 -0
  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 +124 -343
  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 +154 -0
  335. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +777 -0
  336. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +306 -0
  337. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +1431 -0
  338. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +1095 -0
  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 +392 -0
  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 +1085 -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_neon.cpp +55 -0
  350. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
  351. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
  352. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
  353. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
  354. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
  355. data/vendor/faiss/faiss/utils/simd_levels.cpp +334 -0
  356. data/vendor/faiss/faiss/utils/simd_levels.h +183 -0
  357. data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
  358. data/vendor/faiss/faiss/utils/utils.cpp +21 -14
  359. data/vendor/faiss/faiss/utils/utils.h +3 -3
  360. metadata +156 -42
  361. data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
  362. data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
  363. data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +0 -81
  364. data/vendor/faiss/faiss/impl/code_distance/code_distance.h +0 -186
  365. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -216
  366. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -224
  367. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
  368. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
  369. data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
  370. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
  371. data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -228
  372. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
  373. data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
  374. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -450
  375. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
  376. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
  377. data/vendor/faiss/faiss/utils/simdlib.h +0 -42
  378. data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -296
  379. /data/vendor/faiss/faiss/{cppcontrib/factory_tools.h → factory_tools.h} +0 -0
@@ -0,0 +1,237 @@
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.h
12
+ * @brief Shared accumulation loop helpers for fast-scan search paths.
13
+ *
14
+ * Contains:
15
+ * - accumulate_fixed_blocks / pq4_accumulate_loop_fixed_scaler
16
+ * (search_1 multi-BB path, bbs > 32)
17
+ * - accumulate_q_4step_256 / pq4_accumulate_loop_qbs_fixed_scaler_256
18
+ * (QBS path, bbs == 32, 256-bit kernel only)
19
+ *
20
+ * The QBS helpers here use pq4_kernel_qbs_256 exclusively (not
21
+ * decompose_qbs.h) because decompose_qbs.h includes kernels_simd512.h
22
+ * whose 512-bit types need explicit SIMD levels. The 512-bit QBS path
23
+ * lives in accumulate_loops_512.h, used by the AVX512 per-ISA TU.
24
+ *
25
+ * All functions live in `namespace faiss` (not anonymous) so they can be
26
+ * shared by both the per-SIMD TU dispatcher (dispatching.h) and the old
27
+ * free-function search paths (pq4_fast_scan_search_1.cpp).
28
+ *
29
+ * The QBS helpers here always use pq4_kernel_qbs_256 (never 512-bit).
30
+ * This is required for the per-SIMD DD TUs where SINGLE_SIMD_LEVEL=NONE
31
+ * leaves 512-bit types empty. The old pq4_fast_scan_search_qbs.cpp
32
+ * continues to use decompose_qbs.h which includes both 256 and 512 paths.
33
+ */
34
+
35
+ #include <cassert>
36
+
37
+ #include <faiss/impl/FaissAssert.h>
38
+ #include <faiss/impl/fast_scan/LookupTableScaler.h>
39
+ #include <faiss/impl/fast_scan/kernels_simd256.h>
40
+ #include <faiss/impl/fast_scan/simd_result_handlers.h>
41
+
42
+ namespace faiss {
43
+
44
+ using namespace simd_result_handlers;
45
+
46
+ /***************************************************************
47
+ * Search_1 path helpers (multi-BB kernel, bbs > 32)
48
+ ***************************************************************/
49
+
50
+ template <
51
+ int NQ,
52
+ int BB,
53
+ SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
54
+ class ResultHandler,
55
+ class Scaler>
56
+ void accumulate_fixed_blocks(
57
+ size_t nb,
58
+ int nsq,
59
+ const uint8_t* codes,
60
+ const uint8_t* LUT,
61
+ ResultHandler& res,
62
+ const Scaler& scaler,
63
+ size_t block_stride) {
64
+ constexpr int bbs = 32 * BB;
65
+ for_each_block<bbs>(nb, codes, block_stride, res, [&](size_t) {
66
+ FixedStorageHandler<NQ, 2 * BB, KernelSL> res2;
67
+ kernel_accumulate_block<NQ, BB, KernelSL>(
68
+ nsq, codes, LUT, res2, scaler);
69
+ res2.to_other_handler(res);
70
+ });
71
+ }
72
+
73
+ template <
74
+ SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
75
+ class ResultHandler,
76
+ class Scaler>
77
+ void pq4_accumulate_loop_fixed_scaler(
78
+ int nq,
79
+ size_t nb,
80
+ int bbs,
81
+ int nsq,
82
+ const uint8_t* codes,
83
+ const uint8_t* LUT,
84
+ ResultHandler& res,
85
+ const Scaler& scaler,
86
+ size_t block_stride) {
87
+ FAISS_THROW_IF_NOT(is_aligned_pointer(codes));
88
+ FAISS_THROW_IF_NOT(is_aligned_pointer(LUT));
89
+ FAISS_THROW_IF_NOT(bbs % 32 == 0);
90
+ FAISS_THROW_IF_NOT(nb % bbs == 0);
91
+
92
+ #define FAISS_ACCLOOP_DISPATCH(NQ, BB) \
93
+ case NQ * 1000 + BB: \
94
+ accumulate_fixed_blocks<NQ, BB, KernelSL>( \
95
+ nb, nsq, codes, LUT, res, scaler, block_stride); \
96
+ break
97
+
98
+ switch (nq * 1000 + bbs / 32) {
99
+ FAISS_ACCLOOP_DISPATCH(1, 1);
100
+ FAISS_ACCLOOP_DISPATCH(1, 2);
101
+ FAISS_ACCLOOP_DISPATCH(1, 3);
102
+ FAISS_ACCLOOP_DISPATCH(1, 4);
103
+ FAISS_ACCLOOP_DISPATCH(1, 5);
104
+ FAISS_ACCLOOP_DISPATCH(2, 1);
105
+ FAISS_ACCLOOP_DISPATCH(2, 2);
106
+ FAISS_ACCLOOP_DISPATCH(3, 1);
107
+ FAISS_ACCLOOP_DISPATCH(4, 1);
108
+ default:
109
+ FAISS_THROW_FMT("nq=%d bbs=%d not instantiated", nq, bbs);
110
+ }
111
+ #undef FAISS_ACCLOOP_DISPATCH
112
+ }
113
+
114
+ /***************************************************************
115
+ * QBS path helpers (bbs == 32, 256-bit kernel only)
116
+ ***************************************************************/
117
+
118
+ template <
119
+ int QBS,
120
+ SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
121
+ class ResultHandler,
122
+ class Scaler>
123
+ void accumulate_q_4step_256(
124
+ size_t ntotal2,
125
+ int nsq,
126
+ const uint8_t* codes,
127
+ const uint8_t* LUT0,
128
+ ResultHandler& res,
129
+ const Scaler& scaler,
130
+ size_t block_stride) {
131
+ constexpr int Q1 = QBS & 15;
132
+ constexpr int Q2 = (QBS >> 4) & 15;
133
+ constexpr int Q3 = (QBS >> 8) & 15;
134
+ constexpr int Q4 = (QBS >> 12) & 15;
135
+ constexpr int SQ = Q1 + Q2 + Q3 + Q4;
136
+
137
+ for_each_block<32>(ntotal2, codes, block_stride, res, [&](size_t) {
138
+ FixedStorageHandler<SQ, 2, KernelSL> res2;
139
+ const uint8_t* LUT = LUT0;
140
+ pq4_kernel_qbs_256<Q1, KernelSL>(nsq, codes, LUT, res2, scaler);
141
+ LUT += Q1 * nsq * 16;
142
+ if (Q2 > 0) {
143
+ res2.set_block_origin(Q1, 0);
144
+ pq4_kernel_qbs_256<Q2, KernelSL>(nsq, codes, LUT, res2, scaler);
145
+ LUT += Q2 * nsq * 16;
146
+ }
147
+ if (Q3 > 0) {
148
+ res2.set_block_origin(Q1 + Q2, 0);
149
+ pq4_kernel_qbs_256<Q3, KernelSL>(nsq, codes, LUT, res2, scaler);
150
+ LUT += Q3 * nsq * 16;
151
+ }
152
+ if (Q4 > 0) {
153
+ res2.set_block_origin(Q1 + Q2 + Q3, 0);
154
+ pq4_kernel_qbs_256<Q4, KernelSL>(nsq, codes, LUT, res2, scaler);
155
+ }
156
+ res2.to_other_handler(res);
157
+ });
158
+ }
159
+
160
+ template <
161
+ SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
162
+ class ResultHandler,
163
+ class Scaler>
164
+ void pq4_accumulate_loop_qbs_fixed_scaler_256(
165
+ int qbs,
166
+ size_t ntotal2,
167
+ int nsq,
168
+ const uint8_t* codes,
169
+ const uint8_t* LUT0,
170
+ ResultHandler& res,
171
+ const Scaler& scaler,
172
+ size_t block_stride) {
173
+ assert(nsq % 2 == 0);
174
+ assert(is_aligned_pointer(codes));
175
+ assert(is_aligned_pointer(LUT0));
176
+
177
+ switch (qbs) {
178
+ #define FAISS_QBS256_DISPATCH(QBS) \
179
+ case QBS: \
180
+ accumulate_q_4step_256<QBS, KernelSL>( \
181
+ ntotal2, nsq, codes, LUT0, res, scaler, block_stride); \
182
+ return;
183
+ FAISS_QBS256_DISPATCH(0x3333); // 12
184
+ FAISS_QBS256_DISPATCH(0x2333); // 11
185
+ FAISS_QBS256_DISPATCH(0x2233); // 10
186
+ FAISS_QBS256_DISPATCH(0x333); // 9
187
+ FAISS_QBS256_DISPATCH(0x2223); // 9
188
+ FAISS_QBS256_DISPATCH(0x233); // 8
189
+ FAISS_QBS256_DISPATCH(0x1223); // 8
190
+ FAISS_QBS256_DISPATCH(0x223); // 7
191
+ FAISS_QBS256_DISPATCH(0x34); // 7
192
+ FAISS_QBS256_DISPATCH(0x133); // 7
193
+ FAISS_QBS256_DISPATCH(0x6); // 6
194
+ FAISS_QBS256_DISPATCH(0x33); // 6
195
+ FAISS_QBS256_DISPATCH(0x123); // 6
196
+ FAISS_QBS256_DISPATCH(0x222); // 6
197
+ FAISS_QBS256_DISPATCH(0x23); // 5
198
+ FAISS_QBS256_DISPATCH(0x5); // 5
199
+ FAISS_QBS256_DISPATCH(0x13); // 4
200
+ FAISS_QBS256_DISPATCH(0x22); // 4
201
+ FAISS_QBS256_DISPATCH(0x4); // 4
202
+ FAISS_QBS256_DISPATCH(0x3); // 3
203
+ FAISS_QBS256_DISPATCH(0x21); // 3
204
+ FAISS_QBS256_DISPATCH(0x2); // 2
205
+ FAISS_QBS256_DISPATCH(0x1); // 1
206
+ #undef FAISS_QBS256_DISPATCH
207
+ }
208
+
209
+ // Default: qbs not known at compile time
210
+ for_each_block<32>(ntotal2, codes, block_stride, res, [&](size_t j0) {
211
+ const uint8_t* LUT = LUT0;
212
+ int qi = qbs;
213
+ int i0 = 0;
214
+ while (qi) {
215
+ int nq = qi & 15;
216
+ qi >>= 4;
217
+ res.set_block_origin(i0, j0);
218
+ #define FAISS_NQ256_DISPATCH(NQ) \
219
+ case NQ: \
220
+ pq4_kernel_qbs_256<NQ, KernelSL>(nsq, codes, LUT, res, scaler); \
221
+ break
222
+ switch (nq) {
223
+ FAISS_NQ256_DISPATCH(1);
224
+ FAISS_NQ256_DISPATCH(2);
225
+ FAISS_NQ256_DISPATCH(3);
226
+ FAISS_NQ256_DISPATCH(4);
227
+ #undef FAISS_NQ256_DISPATCH
228
+ default:
229
+ FAISS_THROW_FMT("accumulate nq=%d not instantiated", nq);
230
+ }
231
+ i0 += nq;
232
+ LUT += nq * nsq * 16;
233
+ }
234
+ });
235
+ }
236
+
237
+ } // namespace faiss
@@ -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