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,603 @@
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
+ #ifdef COMPILE_SIMD_AVX2
9
+
10
+ #include <faiss/impl/simdlib/simdlib_avx2.h>
11
+
12
+ #include <cstring>
13
+
14
+ #include <faiss/impl/scalar_quantizer/codecs.h>
15
+ #include <faiss/impl/scalar_quantizer/distance_computers.h>
16
+ #include <faiss/impl/scalar_quantizer/quantizers.h>
17
+ #include <faiss/impl/scalar_quantizer/scanners.h>
18
+ #include <faiss/impl/scalar_quantizer/similarities.h>
19
+
20
+ namespace faiss {
21
+
22
+ namespace scalar_quantizer {
23
+
24
+ using simd8float32 = faiss::simd8float32_tpl<SIMDLevel::AVX2>;
25
+
26
+ namespace {
27
+
28
+ FAISS_ALWAYS_INLINE uint16_t load_u16(const uint8_t* ptr) {
29
+ uint16_t value;
30
+ std::memcpy(&value, ptr, sizeof(value));
31
+ return value;
32
+ }
33
+
34
+ FAISS_ALWAYS_INLINE uint32_t load_u32(const uint8_t* ptr) {
35
+ uint32_t value;
36
+ std::memcpy(&value, ptr, sizeof(value));
37
+ return value;
38
+ }
39
+
40
+ FAISS_ALWAYS_INLINE uint32_t load_u24(const uint8_t* ptr) {
41
+ return static_cast<uint32_t>(ptr[0]) |
42
+ (static_cast<uint32_t>(ptr[1]) << 8) |
43
+ (static_cast<uint32_t>(ptr[2]) << 16);
44
+ }
45
+
46
+ FAISS_ALWAYS_INLINE __m256i unpack_8x1bit_to_u32(const uint8_t* code, int i) {
47
+ const uint32_t packed = code[static_cast<size_t>(i) >> 3];
48
+ const __m256i shifts = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
49
+ const __m256i indices =
50
+ _mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
51
+ return _mm256_and_si256(indices, _mm256_set1_epi32(0x1));
52
+ }
53
+
54
+ FAISS_ALWAYS_INLINE __m256i unpack_8x2bit_to_u32(const uint8_t* code, int i) {
55
+ const uint32_t packed = load_u16(code + (static_cast<size_t>(i) >> 2));
56
+ const __m256i shifts = _mm256_setr_epi32(0, 2, 4, 6, 8, 10, 12, 14);
57
+ const __m256i indices =
58
+ _mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
59
+ return _mm256_and_si256(indices, _mm256_set1_epi32(0x3));
60
+ }
61
+
62
+ FAISS_ALWAYS_INLINE __m256i unpack_8x3bit_to_u32(const uint8_t* code, int i) {
63
+ const uint32_t packed =
64
+ load_u24(code + ((static_cast<size_t>(i) >> 3) * 3));
65
+ const __m256i shifts = _mm256_setr_epi32(0, 3, 6, 9, 12, 15, 18, 21);
66
+ const __m256i indices =
67
+ _mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
68
+ return _mm256_and_si256(indices, _mm256_set1_epi32(0x7));
69
+ }
70
+
71
+ FAISS_ALWAYS_INLINE __m256i unpack_8x4bit_to_u32(const uint8_t* code, int i) {
72
+ const uint32_t packed = load_u32(code + (static_cast<size_t>(i) >> 1));
73
+ const __m256i shifts = _mm256_setr_epi32(0, 4, 8, 12, 16, 20, 24, 28);
74
+ const __m256i indices =
75
+ _mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
76
+ return _mm256_and_si256(indices, _mm256_set1_epi32(0xf));
77
+ }
78
+
79
+ } // namespace
80
+
81
+ /**********************************************************
82
+ * Codecs
83
+ **********************************************************/
84
+
85
+ template <>
86
+ struct Codec8bit<SIMDLevel::AVX2> : Codec8bit<SIMDLevel::NONE> {
87
+ static FAISS_ALWAYS_INLINE simd8float32
88
+ decode_8_components(const uint8_t* code, size_t i) {
89
+ const uint64_t c8 = *(uint64_t*)(code + i);
90
+
91
+ const __m128i i8 = _mm_set1_epi64x(c8);
92
+ const __m256i i32 = _mm256_cvtepu8_epi32(i8);
93
+ const __m256 f8 = _mm256_cvtepi32_ps(i32);
94
+ const __m256 half_one_255 = _mm256_set1_ps(0.5f / 255.f);
95
+ const __m256 one_255 = _mm256_set1_ps(1.f / 255.f);
96
+ return simd8float32(_mm256_fmadd_ps(f8, one_255, half_one_255));
97
+ }
98
+ };
99
+
100
+ template <>
101
+ struct Codec4bit<SIMDLevel::AVX2> : Codec4bit<SIMDLevel::NONE> {
102
+ static FAISS_ALWAYS_INLINE simd8float32
103
+ decode_8_components(const uint8_t* code, size_t i) {
104
+ uint32_t c4 = *(uint32_t*)(code + (i >> 1));
105
+ uint32_t mask = 0x0f0f0f0f;
106
+ uint32_t c4ev = c4 & mask;
107
+ uint32_t c4od = (c4 >> 4) & mask;
108
+
109
+ // the 8 lower bytes of c8 contain the values
110
+ __m128i c8 =
111
+ _mm_unpacklo_epi8(_mm_set1_epi32(c4ev), _mm_set1_epi32(c4od));
112
+ __m128i c4lo = _mm_cvtepu8_epi32(c8);
113
+ __m128i c4hi = _mm_cvtepu8_epi32(_mm_srli_si128(c8, 4));
114
+ __m256i i8 = _mm256_castsi128_si256(c4lo);
115
+ i8 = _mm256_insertf128_si256(i8, c4hi, 1);
116
+ __m256 f8 = _mm256_cvtepi32_ps(i8);
117
+ __m256 half = _mm256_set1_ps(0.5f);
118
+ f8 = _mm256_add_ps(f8, half);
119
+ __m256 one_255 = _mm256_set1_ps(1.f / 15.f);
120
+ return simd8float32(_mm256_mul_ps(f8, one_255));
121
+ }
122
+ };
123
+
124
+ template <>
125
+ struct Codec6bit<SIMDLevel::AVX2> : Codec6bit<SIMDLevel::NONE> {
126
+ /* Load 6 bytes that represent 8 6-bit values, return them as a
127
+ * 8*32 bit vector register */
128
+ static FAISS_ALWAYS_INLINE __m256i load6(const uint16_t* code16) {
129
+ const __m128i perm = _mm_set_epi8(
130
+ -1, 5, 5, 4, 4, 3, -1, 3, -1, 2, 2, 1, 1, 0, -1, 0);
131
+ const __m256i shifts = _mm256_set_epi32(2, 4, 6, 0, 2, 4, 6, 0);
132
+
133
+ // load 6 bytes
134
+ __m128i c1 =
135
+ _mm_set_epi16(0, 0, 0, 0, 0, code16[2], code16[1], code16[0]);
136
+
137
+ // put in 8 * 32 bits
138
+ __m128i c2 = _mm_shuffle_epi8(c1, perm);
139
+ __m256i c3 = _mm256_cvtepi16_epi32(c2);
140
+
141
+ // shift and mask out useless bits
142
+ __m256i c4 = _mm256_srlv_epi32(c3, shifts);
143
+ __m256i c5 = _mm256_and_si256(_mm256_set1_epi32(63), c4);
144
+ return c5;
145
+ }
146
+
147
+ static FAISS_ALWAYS_INLINE simd8float32
148
+ decode_8_components(const uint8_t* code, size_t i) {
149
+ // // Faster code for Intel CPUs or AMD Zen3+, just keeping it here
150
+ // // for the reference, maybe, it becomes used one day.
151
+ // const uint16_t* data16 = (const uint16_t*)(code + (i >> 2) * 3);
152
+ // const uint32_t* data32 = (const uint32_t*)data16;
153
+ // const uint64_t val = *data32 + ((uint64_t)data16[2] << 32);
154
+ // const uint64_t vext = _pdep_u64(val, 0x3F3F3F3F3F3F3F3FULL);
155
+ // const __m128i i8 = _mm_set1_epi64x(vext);
156
+ // const __m256i i32 = _mm256_cvtepi8_epi32(i8);
157
+ // const __m256 f8 = _mm256_cvtepi32_ps(i32);
158
+ // const __m256 half_one_255 = _mm256_set1_ps(0.5f / 63.f);
159
+ // const __m256 one_255 = _mm256_set1_ps(1.f / 63.f);
160
+ // return _mm256_fmadd_ps(f8, one_255, half_one_255);
161
+
162
+ __m256i i8 = load6((const uint16_t*)(code + (i >> 2) * 3));
163
+ __m256 f8 = _mm256_cvtepi32_ps(i8);
164
+ // this could also be done with bit manipulations but it is
165
+ // not obviously faster
166
+ const __m256 half_one_255 = _mm256_set1_ps(0.5f / 63.f);
167
+ const __m256 one_255 = _mm256_set1_ps(1.f / 63.f);
168
+ return simd8float32(_mm256_fmadd_ps(f8, one_255, half_one_255));
169
+ }
170
+ };
171
+
172
+ /**********************************************************
173
+ * Quantizers (uniform and non-uniform)
174
+ **********************************************************/
175
+
176
+ template <class Codec>
177
+ struct QuantizerTemplate<
178
+ Codec,
179
+ QuantizerTemplateScaling::UNIFORM,
180
+ SIMDLevel::AVX2>
181
+ : QuantizerTemplate<
182
+ Codec,
183
+ QuantizerTemplateScaling::UNIFORM,
184
+ SIMDLevel::NONE> {
185
+ QuantizerTemplate(size_t d, const std::vector<float>& trained)
186
+ : QuantizerTemplate<
187
+ Codec,
188
+ QuantizerTemplateScaling::UNIFORM,
189
+ SIMDLevel::NONE>(d, trained) {
190
+ assert(d % 8 == 0);
191
+ }
192
+
193
+ FAISS_ALWAYS_INLINE simd8float32
194
+ reconstruct_8_components(const uint8_t* code, int i) const {
195
+ __m256 xi = Codec::decode_8_components(code, i).f;
196
+ return simd8float32(_mm256_fmadd_ps(
197
+ xi, _mm256_set1_ps(this->vdiff), _mm256_set1_ps(this->vmin)));
198
+ }
199
+ };
200
+
201
+ template <class Codec>
202
+ struct QuantizerTemplate<
203
+ Codec,
204
+ QuantizerTemplateScaling::NON_UNIFORM,
205
+ SIMDLevel::AVX2>
206
+ : QuantizerTemplate<
207
+ Codec,
208
+ QuantizerTemplateScaling::NON_UNIFORM,
209
+ SIMDLevel::NONE> {
210
+ QuantizerTemplate(size_t d, const std::vector<float>& trained)
211
+ : QuantizerTemplate<
212
+ Codec,
213
+ QuantizerTemplateScaling::NON_UNIFORM,
214
+ SIMDLevel::NONE>(d, trained) {
215
+ assert(d % 8 == 0);
216
+ }
217
+
218
+ FAISS_ALWAYS_INLINE simd8float32
219
+ reconstruct_8_components(const uint8_t* code, int i) const {
220
+ __m256 xi = Codec::decode_8_components(code, i).f;
221
+ return simd8float32(_mm256_fmadd_ps(
222
+ xi,
223
+ _mm256_loadu_ps(this->vdiff + i),
224
+ _mm256_loadu_ps(this->vmin + i)));
225
+ }
226
+ };
227
+
228
+ /**********************************************************
229
+ * TurboQuant MSE quantizer
230
+ **********************************************************/
231
+
232
+ #define DEFINE_TQMSE_AVX2_SPECIALIZATION(NBITS, INDEX_EXPR) \
233
+ template <> \
234
+ struct QuantizerTurboQuantMSE<NBITS, SIMDLevel::AVX2> \
235
+ : QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE> { \
236
+ using Base = QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE>; \
237
+ \
238
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained) \
239
+ : Base(d, trained) { \
240
+ assert(d % 8 == 0); \
241
+ } \
242
+ \
243
+ FAISS_ALWAYS_INLINE simd8float32 \
244
+ reconstruct_8_components(const uint8_t* code, int i) const { \
245
+ const __m256i indices = (INDEX_EXPR); \
246
+ return simd8float32(_mm256_i32gather_ps( \
247
+ this->centroids, indices, sizeof(float))); \
248
+ } \
249
+ }
250
+
251
+ DEFINE_TQMSE_AVX2_SPECIALIZATION(1, unpack_8x1bit_to_u32(code, i));
252
+ DEFINE_TQMSE_AVX2_SPECIALIZATION(2, unpack_8x2bit_to_u32(code, i));
253
+ DEFINE_TQMSE_AVX2_SPECIALIZATION(3, unpack_8x3bit_to_u32(code, i));
254
+ DEFINE_TQMSE_AVX2_SPECIALIZATION(4, unpack_8x4bit_to_u32(code, i));
255
+
256
+ #undef DEFINE_TQMSE_AVX2_SPECIALIZATION
257
+
258
+ template <>
259
+ struct QuantizerTurboQuantMSE<8, SIMDLevel::AVX2>
260
+ : QuantizerTurboQuantMSE<8, SIMDLevel::NONE> {
261
+ using Base = QuantizerTurboQuantMSE<8, SIMDLevel::NONE>;
262
+
263
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained)
264
+ : Base(d, trained) {
265
+ assert(d % 8 == 0);
266
+ }
267
+
268
+ FAISS_ALWAYS_INLINE simd8float32
269
+ reconstruct_8_components(const uint8_t* code, int i) const {
270
+ const __m128i packed = _mm_loadl_epi64(
271
+ (const __m128i*)(code + static_cast<size_t>(i)));
272
+ const __m256i indices = _mm256_cvtepu8_epi32(packed);
273
+ return simd8float32(
274
+ _mm256_i32gather_ps(this->centroids, indices, sizeof(float)));
275
+ }
276
+ };
277
+
278
+ /**********************************************************
279
+ * FP16 Quantizer
280
+ **********************************************************/
281
+
282
+ template <>
283
+ struct QuantizerFP16<SIMDLevel::AVX2> : QuantizerFP16<SIMDLevel::NONE> {
284
+ QuantizerFP16(size_t d, const std::vector<float>& trained)
285
+ : QuantizerFP16<SIMDLevel::NONE>(d, trained) {
286
+ assert(d % 8 == 0);
287
+ }
288
+
289
+ FAISS_ALWAYS_INLINE simd8float32
290
+ reconstruct_8_components(const uint8_t* code, int i) const {
291
+ __m128i codei = _mm_loadu_si128((const __m128i*)(code + 2 * i));
292
+ return simd8float32(_mm256_cvtph_ps(codei));
293
+ }
294
+ };
295
+
296
+ /**********************************************************
297
+ * BF16 Quantizer
298
+ **********************************************************/
299
+
300
+ template <>
301
+ struct QuantizerBF16<SIMDLevel::AVX2> : QuantizerBF16<SIMDLevel::NONE> {
302
+ QuantizerBF16(size_t d, const std::vector<float>& trained)
303
+ : QuantizerBF16<SIMDLevel::NONE>(d, trained) {
304
+ assert(d % 8 == 0);
305
+ }
306
+
307
+ FAISS_ALWAYS_INLINE simd8float32
308
+ reconstruct_8_components(const uint8_t* code, int i) const {
309
+ __m128i code_128i = _mm_loadu_si128((const __m128i*)(code + 2 * i));
310
+ __m256i code_256i = _mm256_cvtepu16_epi32(code_128i);
311
+ code_256i = _mm256_slli_epi32(code_256i, 16);
312
+ return simd8float32(_mm256_castsi256_ps(code_256i));
313
+ }
314
+ };
315
+
316
+ /**********************************************************
317
+ * 8bit Direct Quantizer
318
+ **********************************************************/
319
+
320
+ template <>
321
+ struct Quantizer8bitDirect<SIMDLevel::AVX2>
322
+ : Quantizer8bitDirect<SIMDLevel::NONE> {
323
+ Quantizer8bitDirect(size_t d, const std::vector<float>& trained)
324
+ : Quantizer8bitDirect<SIMDLevel::NONE>(d, trained) {
325
+ assert(d % 8 == 0);
326
+ }
327
+
328
+ FAISS_ALWAYS_INLINE simd8float32
329
+ reconstruct_8_components(const uint8_t* code, int i) const {
330
+ __m128i x8 = _mm_loadl_epi64((__m128i*)(code + i)); // 8 * int8
331
+ __m256i y8 = _mm256_cvtepu8_epi32(x8); // 8 * int32
332
+ return simd8float32(_mm256_cvtepi32_ps(y8)); // 8 * float32
333
+ }
334
+ };
335
+
336
+ /**********************************************************
337
+ * 8bit Direct Signed Quantizer
338
+ **********************************************************/
339
+
340
+ template <>
341
+ struct Quantizer8bitDirectSigned<SIMDLevel::AVX2>
342
+ : Quantizer8bitDirectSigned<SIMDLevel::NONE> {
343
+ Quantizer8bitDirectSigned(size_t d, const std::vector<float>& trained)
344
+ : Quantizer8bitDirectSigned<SIMDLevel::NONE>(d, trained) {
345
+ assert(d % 8 == 0);
346
+ }
347
+
348
+ FAISS_ALWAYS_INLINE simd8float32
349
+ reconstruct_8_components(const uint8_t* code, int i) const {
350
+ __m128i x8 = _mm_loadl_epi64((__m128i*)(code + i)); // 8 * int8
351
+ __m256i y8 = _mm256_cvtepu8_epi32(x8); // 8 * int32
352
+ __m256i c8 = _mm256_set1_epi32(128);
353
+ __m256i z8 = _mm256_sub_epi32(y8, c8); // subtract 128 from all lanes
354
+ return simd8float32(_mm256_cvtepi32_ps(z8)); // 8 * float32
355
+ }
356
+ };
357
+
358
+ /**********************************************************
359
+ * SimilarityL2 and SimilarityIP
360
+ **********************************************************/
361
+
362
+ template <>
363
+ struct SimilarityL2<SIMDLevel::AVX2> {
364
+ static constexpr int simdwidth = 8;
365
+ static constexpr SIMDLevel simd_level = SIMDLevel::AVX2;
366
+ static constexpr MetricType metric_type = METRIC_L2;
367
+
368
+ const float *y, *yi;
369
+
370
+ explicit SimilarityL2(const float* y) : y(y), yi(nullptr) {}
371
+ simd8float32 accu8 = {};
372
+
373
+ FAISS_ALWAYS_INLINE void begin_8() {
374
+ accu8.clear();
375
+ yi = y;
376
+ }
377
+
378
+ FAISS_ALWAYS_INLINE void add_8_components(simd8float32 x) {
379
+ __m256 yiv = _mm256_loadu_ps(yi);
380
+ yi += 8;
381
+ __m256 tmp = _mm256_sub_ps(yiv, x.f);
382
+ accu8 = simd8float32(_mm256_fmadd_ps(tmp, tmp, accu8.f));
383
+ }
384
+
385
+ FAISS_ALWAYS_INLINE void add_8_components_2(
386
+ simd8float32 x,
387
+ simd8float32 y_2) {
388
+ __m256 tmp = _mm256_sub_ps(y_2.f, x.f);
389
+ accu8 = simd8float32(_mm256_fmadd_ps(tmp, tmp, accu8.f));
390
+ }
391
+
392
+ FAISS_ALWAYS_INLINE float result_8() {
393
+ const __m128 sum = _mm_add_ps(
394
+ _mm256_castps256_ps128(accu8.f),
395
+ _mm256_extractf128_ps(accu8.f, 1));
396
+ const __m128 v0 = _mm_shuffle_ps(sum, sum, _MM_SHUFFLE(0, 0, 3, 2));
397
+ const __m128 v1 = _mm_add_ps(sum, v0);
398
+ __m128 v2 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(0, 0, 0, 1));
399
+ const __m128 v3 = _mm_add_ps(v1, v2);
400
+ return _mm_cvtss_f32(v3);
401
+ }
402
+ };
403
+
404
+ template <>
405
+ struct SimilarityIP<SIMDLevel::AVX2> {
406
+ static constexpr int simdwidth = 8;
407
+ static constexpr SIMDLevel simd_level = SIMDLevel::AVX2;
408
+ static constexpr MetricType metric_type = METRIC_INNER_PRODUCT;
409
+
410
+ const float *y, *yi;
411
+
412
+ float accu;
413
+
414
+ explicit SimilarityIP(const float* y) : y(y), yi(nullptr), accu(0) {}
415
+
416
+ simd8float32 accu8 = {};
417
+
418
+ FAISS_ALWAYS_INLINE void begin_8() {
419
+ accu8.clear();
420
+ yi = y;
421
+ }
422
+
423
+ FAISS_ALWAYS_INLINE void add_8_components(simd8float32 x) {
424
+ __m256 yiv = _mm256_loadu_ps(yi);
425
+ yi += 8;
426
+ accu8.f = _mm256_fmadd_ps(yiv, x.f, accu8.f);
427
+ }
428
+
429
+ FAISS_ALWAYS_INLINE void add_8_components_2(
430
+ simd8float32 x1,
431
+ simd8float32 x2) {
432
+ accu8.f = _mm256_fmadd_ps(x1.f, x2.f, accu8.f);
433
+ }
434
+
435
+ FAISS_ALWAYS_INLINE float result_8() {
436
+ const __m128 sum = _mm_add_ps(
437
+ _mm256_castps256_ps128(accu8.f),
438
+ _mm256_extractf128_ps(accu8.f, 1));
439
+ const __m128 v0 = _mm_shuffle_ps(sum, sum, _MM_SHUFFLE(0, 0, 3, 2));
440
+ const __m128 v1 = _mm_add_ps(sum, v0);
441
+ __m128 v2 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(0, 0, 0, 1));
442
+ const __m128 v3 = _mm_add_ps(v1, v2);
443
+ return _mm_cvtss_f32(v3);
444
+ }
445
+ };
446
+
447
+ /**********************************************************
448
+ * Distance computers
449
+ **********************************************************/
450
+
451
+ template <class Quantizer, class Similarity>
452
+ struct DCTemplate<Quantizer, Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
453
+ using Sim = Similarity;
454
+
455
+ Quantizer quant;
456
+
457
+ DCTemplate(size_t d, const std::vector<float>& trained)
458
+ : quant(d, trained) {}
459
+
460
+ float compute_distance(const float* x, const uint8_t* code) const {
461
+ Similarity sim(x);
462
+ sim.begin_8();
463
+ for (size_t i = 0; i < quant.d; i += 8) {
464
+ simd8float32 xi =
465
+ quant.reconstruct_8_components(code, static_cast<int>(i));
466
+ sim.add_8_components(xi);
467
+ }
468
+ return sim.result_8();
469
+ }
470
+
471
+ float compute_code_distance(const uint8_t* code1, const uint8_t* code2)
472
+ const {
473
+ Similarity sim(nullptr);
474
+ sim.begin_8();
475
+ for (size_t i = 0; i < quant.d; i += 8) {
476
+ simd8float32 x1 =
477
+ quant.reconstruct_8_components(code1, static_cast<int>(i));
478
+ simd8float32 x2 =
479
+ quant.reconstruct_8_components(code2, static_cast<int>(i));
480
+ sim.add_8_components_2(x1, x2);
481
+ }
482
+ return sim.result_8();
483
+ }
484
+
485
+ void set_query(const float* x) final {
486
+ q = x;
487
+ }
488
+
489
+ float symmetric_dis(idx_t i, idx_t j) override {
490
+ return compute_code_distance(
491
+ codes + i * code_size, codes + j * code_size);
492
+ }
493
+
494
+ float query_to_code(const uint8_t* code) const final {
495
+ return compute_distance(q, code);
496
+ }
497
+
498
+ void query_to_codes_batch_4(
499
+ const uint8_t* code_0,
500
+ const uint8_t* code_1,
501
+ const uint8_t* code_2,
502
+ const uint8_t* code_3,
503
+ float& dis0,
504
+ float& dis1,
505
+ float& dis2,
506
+ float& dis3) const final {
507
+ Similarity sim0(q);
508
+ Similarity sim1(q);
509
+ Similarity sim2(q);
510
+ Similarity sim3(q);
511
+
512
+ sim0.begin_8();
513
+ sim1.begin_8();
514
+ sim2.begin_8();
515
+ sim3.begin_8();
516
+
517
+ for (size_t i = 0; i < quant.d; i += 8) {
518
+ const int ii = static_cast<int>(i);
519
+ simd8float32 xi0 = quant.reconstruct_8_components(code_0, ii);
520
+ simd8float32 xi1 = quant.reconstruct_8_components(code_1, ii);
521
+ simd8float32 xi2 = quant.reconstruct_8_components(code_2, ii);
522
+ simd8float32 xi3 = quant.reconstruct_8_components(code_3, ii);
523
+ sim0.add_8_components(xi0);
524
+ sim1.add_8_components(xi1);
525
+ sim2.add_8_components(xi2);
526
+ sim3.add_8_components(xi3);
527
+ }
528
+
529
+ dis0 = sim0.result_8();
530
+ dis1 = sim1.result_8();
531
+ dis2 = sim2.result_8();
532
+ dis3 = sim3.result_8();
533
+ }
534
+ };
535
+
536
+ template <class Similarity>
537
+ struct DistanceComputerByte<Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
538
+ using Sim = Similarity;
539
+
540
+ int d;
541
+ std::vector<uint8_t> tmp;
542
+
543
+ DistanceComputerByte(int d, const std::vector<float>&) : d(d), tmp(d) {}
544
+
545
+ int compute_code_distance(const uint8_t* code1, const uint8_t* code2)
546
+ const {
547
+ // __m256i accu = _mm256_setzero_ps ();
548
+ __m256i accu = _mm256_setzero_si256();
549
+ for (int i = 0; i < d; i += 16) {
550
+ // load 16 bytes, convert to 16 uint16_t
551
+ __m256i c1 = _mm256_cvtepu8_epi16(
552
+ _mm_loadu_si128((__m128i*)(code1 + i)));
553
+ __m256i c2 = _mm256_cvtepu8_epi16(
554
+ _mm_loadu_si128((__m128i*)(code2 + i)));
555
+ __m256i prod32;
556
+ if (Sim::metric_type == METRIC_INNER_PRODUCT) {
557
+ prod32 = _mm256_madd_epi16(c1, c2);
558
+ } else {
559
+ __m256i diff = _mm256_sub_epi16(c1, c2);
560
+ prod32 = _mm256_madd_epi16(diff, diff);
561
+ }
562
+ accu = _mm256_add_epi32(accu, prod32);
563
+ }
564
+ __m128i sum = _mm256_extractf128_si256(accu, 0);
565
+ sum = _mm_add_epi32(sum, _mm256_extractf128_si256(accu, 1));
566
+ sum = _mm_hadd_epi32(sum, sum);
567
+ sum = _mm_hadd_epi32(sum, sum);
568
+ return _mm_cvtsi128_si32(sum);
569
+ }
570
+
571
+ void set_query(const float* x) final {
572
+ /*
573
+ for (int i = 0; i < d; i += 8) {
574
+ __m256 xi = _mm256_loadu_ps (x + i);
575
+ __m256i ci = _mm256_cvtps_epi32(xi);
576
+ */
577
+ for (int i = 0; i < d; i++) {
578
+ tmp[i] = int(x[i]);
579
+ }
580
+ }
581
+
582
+ int compute_distance(const float* x, const uint8_t* code) {
583
+ set_query(x);
584
+ return compute_code_distance(tmp.data(), code);
585
+ }
586
+
587
+ float symmetric_dis(idx_t i, idx_t j) override {
588
+ return compute_code_distance(
589
+ codes + i * code_size, codes + j * code_size);
590
+ }
591
+
592
+ float query_to_code(const uint8_t* code) const final {
593
+ return compute_code_distance(tmp.data(), code);
594
+ }
595
+ };
596
+
597
+ } // namespace scalar_quantizer
598
+ } // namespace faiss
599
+
600
+ #define THE_LEVEL_TO_DISPATCH SIMDLevel::AVX2
601
+ #include <faiss/impl/scalar_quantizer/sq-dispatch.h>
602
+
603
+ #endif // COMPILE_SIMD_AVX2