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,630 @@
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_ARM_NEON
9
+
10
+ #include <faiss/impl/simdlib/simdlib_neon.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::ARM_NEON>;
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 void unpack_8x1bit_to_u8(
47
+ const uint8_t* code,
48
+ int i,
49
+ uint8_t out[8]) {
50
+ const uint8_t packed = code[static_cast<size_t>(i) >> 3];
51
+ for (size_t j = 0; j < 8; ++j) {
52
+ out[j] = (packed >> j) & 0x1;
53
+ }
54
+ }
55
+
56
+ FAISS_ALWAYS_INLINE void unpack_8x2bit_to_u8(
57
+ const uint8_t* code,
58
+ int i,
59
+ uint8_t out[8]) {
60
+ const uint16_t packed = load_u16(code + (static_cast<size_t>(i) >> 2));
61
+ for (size_t j = 0; j < 8; ++j) {
62
+ out[j] = (packed >> (2 * j)) & 0x3;
63
+ }
64
+ }
65
+
66
+ FAISS_ALWAYS_INLINE void unpack_8x3bit_to_u8(
67
+ const uint8_t* code,
68
+ int i,
69
+ uint8_t out[8]) {
70
+ const uint32_t packed =
71
+ load_u24(code + ((static_cast<size_t>(i) >> 3) * 3));
72
+ for (size_t j = 0; j < 8; ++j) {
73
+ out[j] = (packed >> (3 * j)) & 0x7;
74
+ }
75
+ }
76
+
77
+ FAISS_ALWAYS_INLINE void unpack_8x4bit_to_u8(
78
+ const uint8_t* code,
79
+ int i,
80
+ uint8_t out[8]) {
81
+ const uint32_t packed = load_u32(code + (static_cast<size_t>(i) >> 1));
82
+ for (size_t j = 0; j < 8; ++j) {
83
+ out[j] = (packed >> (4 * j)) & 0xf;
84
+ }
85
+ }
86
+
87
+ FAISS_ALWAYS_INLINE simd8float32
88
+ gather_8_components(const float* codebook, const uint8_t indices[8]) {
89
+ float result[8];
90
+ for (size_t j = 0; j < 8; ++j) {
91
+ result[j] = codebook[indices[j]];
92
+ }
93
+ return simd8float32(
94
+ float32x4x2_t{vld1q_f32(result), vld1q_f32(result + 4)});
95
+ }
96
+
97
+ } // namespace
98
+
99
+ /**********************************************************
100
+ * Codecs
101
+ **********************************************************/
102
+
103
+ template <>
104
+ struct Codec8bit<SIMDLevel::ARM_NEON> : Codec8bit<SIMDLevel::NONE> {
105
+ static FAISS_ALWAYS_INLINE simd8float32
106
+ decode_8_components(const uint8_t* code, size_t i) {
107
+ float32_t result[8] = {};
108
+ for (size_t j = 0; j < 8; j++) {
109
+ result[j] =
110
+ Codec8bit<SIMDLevel::NONE>::decode_component(code, i + j);
111
+ }
112
+ float32x4_t res1 = vld1q_f32(result);
113
+ float32x4_t res2 = vld1q_f32(result + 4);
114
+ return simd8float32(float32x4x2_t{res1, res2});
115
+ }
116
+ };
117
+
118
+ template <>
119
+ struct Codec4bit<SIMDLevel::ARM_NEON> : Codec4bit<SIMDLevel::NONE> {
120
+ static FAISS_ALWAYS_INLINE simd8float32
121
+ decode_8_components(const uint8_t* code, size_t i) {
122
+ float32_t result[8] = {};
123
+ for (size_t j = 0; j < 8; j++) {
124
+ result[j] =
125
+ Codec4bit<SIMDLevel::NONE>::decode_component(code, i + j);
126
+ }
127
+ float32x4_t res1 = vld1q_f32(result);
128
+ float32x4_t res2 = vld1q_f32(result + 4);
129
+ return simd8float32(float32x4x2_t{res1, res2});
130
+ }
131
+ };
132
+
133
+ template <>
134
+ struct Codec6bit<SIMDLevel::ARM_NEON> : Codec6bit<SIMDLevel::NONE> {
135
+ static FAISS_ALWAYS_INLINE simd8float32
136
+ decode_8_components(const uint8_t* code, size_t i) {
137
+ float32_t result[8] = {};
138
+ for (size_t j = 0; j < 8; j++) {
139
+ result[j] =
140
+ Codec6bit<SIMDLevel::NONE>::decode_component(code, i + j);
141
+ }
142
+ float32x4_t res1 = vld1q_f32(result);
143
+ float32x4_t res2 = vld1q_f32(result + 4);
144
+ return simd8float32(float32x4x2_t{res1, res2});
145
+ }
146
+ };
147
+
148
+ /**********************************************************
149
+ * Quantizers (uniform and non-uniform)
150
+ **********************************************************/
151
+
152
+ template <class Codec>
153
+ struct QuantizerTemplate<
154
+ Codec,
155
+ scalar_quantizer::QuantizerTemplateScaling::UNIFORM,
156
+ SIMDLevel::ARM_NEON>
157
+ : QuantizerTemplate<
158
+ Codec,
159
+ scalar_quantizer::QuantizerTemplateScaling::UNIFORM,
160
+ SIMDLevel::NONE> {
161
+ QuantizerTemplate(size_t d, const std::vector<float>& trained)
162
+ : QuantizerTemplate<
163
+ Codec,
164
+ scalar_quantizer::QuantizerTemplateScaling::UNIFORM,
165
+ SIMDLevel::NONE>(d, trained) {
166
+ assert(d % 8 == 0);
167
+ }
168
+
169
+ FAISS_ALWAYS_INLINE simd8float32
170
+ reconstruct_8_components(const uint8_t* code, int i) const {
171
+ simd8float32 xi = Codec::decode_8_components(code, i);
172
+ return simd8float32(
173
+ float32x4x2_t{
174
+ vfmaq_n_f32(
175
+ vdupq_n_f32(this->vmin),
176
+ xi.data.val[0],
177
+ this->vdiff),
178
+ vfmaq_n_f32(
179
+ vdupq_n_f32(this->vmin),
180
+ xi.data.val[1],
181
+ this->vdiff)});
182
+ }
183
+ };
184
+
185
+ template <class Codec>
186
+ struct QuantizerTemplate<
187
+ Codec,
188
+ scalar_quantizer::QuantizerTemplateScaling::NON_UNIFORM,
189
+ SIMDLevel::ARM_NEON>
190
+ : QuantizerTemplate<
191
+ Codec,
192
+ scalar_quantizer::QuantizerTemplateScaling::NON_UNIFORM,
193
+ SIMDLevel::NONE> {
194
+ QuantizerTemplate(size_t d, const std::vector<float>& trained)
195
+ : QuantizerTemplate<
196
+ Codec,
197
+ scalar_quantizer::QuantizerTemplateScaling::NON_UNIFORM,
198
+ SIMDLevel::NONE>(d, trained) {
199
+ assert(d % 8 == 0);
200
+ }
201
+
202
+ FAISS_ALWAYS_INLINE simd8float32
203
+ reconstruct_8_components(const uint8_t* code, int i) const {
204
+ simd8float32 xi = Codec::decode_8_components(code, i);
205
+ return simd8float32(
206
+ float32x4x2_t{
207
+ vfmaq_f32(
208
+ vld1q_f32(this->vmin + i),
209
+ xi.data.val[0],
210
+ vld1q_f32(this->vdiff + i)),
211
+ vfmaq_f32(
212
+ vld1q_f32(this->vmin + i + 4),
213
+ xi.data.val[1],
214
+ vld1q_f32(this->vdiff + i + 4))});
215
+ }
216
+ };
217
+
218
+ /**********************************************************
219
+ * TurboQuant MSE quantizer
220
+ **********************************************************/
221
+
222
+ #define DEFINE_TQMSE_NEON_SPECIALIZATION(NBITS, UNPACK_FN) \
223
+ template <> \
224
+ struct QuantizerTurboQuantMSE<NBITS, SIMDLevel::ARM_NEON> \
225
+ : QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE> { \
226
+ using Base = QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE>; \
227
+ \
228
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained) \
229
+ : Base(d, trained) { \
230
+ assert(d % 8 == 0); \
231
+ } \
232
+ \
233
+ FAISS_ALWAYS_INLINE simd8float32 \
234
+ reconstruct_8_components(const uint8_t* code, int i) const { \
235
+ uint8_t indices[8]; \
236
+ UNPACK_FN(code, i, indices); \
237
+ return gather_8_components(this->centroids, indices); \
238
+ } \
239
+ }
240
+
241
+ DEFINE_TQMSE_NEON_SPECIALIZATION(1, unpack_8x1bit_to_u8);
242
+ DEFINE_TQMSE_NEON_SPECIALIZATION(2, unpack_8x2bit_to_u8);
243
+ DEFINE_TQMSE_NEON_SPECIALIZATION(3, unpack_8x3bit_to_u8);
244
+ DEFINE_TQMSE_NEON_SPECIALIZATION(4, unpack_8x4bit_to_u8);
245
+
246
+ #undef DEFINE_TQMSE_NEON_SPECIALIZATION
247
+
248
+ template <>
249
+ struct QuantizerTurboQuantMSE<8, SIMDLevel::ARM_NEON>
250
+ : QuantizerTurboQuantMSE<8, SIMDLevel::NONE> {
251
+ using Base = QuantizerTurboQuantMSE<8, SIMDLevel::NONE>;
252
+
253
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained)
254
+ : Base(d, trained) {
255
+ assert(d % 8 == 0);
256
+ }
257
+
258
+ FAISS_ALWAYS_INLINE simd8float32
259
+ reconstruct_8_components(const uint8_t* code, int i) const {
260
+ uint8_t indices[8];
261
+ std::memcpy(indices, code + static_cast<size_t>(i), sizeof(indices));
262
+ return gather_8_components(this->centroids, indices);
263
+ }
264
+ };
265
+
266
+ /**********************************************************
267
+ * FP16 Quantizer
268
+ **********************************************************/
269
+
270
+ template <>
271
+ struct QuantizerFP16<SIMDLevel::ARM_NEON> : QuantizerFP16<SIMDLevel::NONE> {
272
+ QuantizerFP16(size_t d, const std::vector<float>& trained)
273
+ : QuantizerFP16<SIMDLevel::NONE>(d, trained) {
274
+ assert(d % 8 == 0);
275
+ }
276
+
277
+ FAISS_ALWAYS_INLINE simd8float32
278
+ reconstruct_8_components(const uint8_t* code, int i) const {
279
+ uint16x4x2_t codei = vld1_u16_x2((const uint16_t*)(code + 2 * i));
280
+ return simd8float32(
281
+ float32x4x2_t{
282
+ vcvt_f32_f16(vreinterpret_f16_u16(codei.val[0])),
283
+ vcvt_f32_f16(vreinterpret_f16_u16(codei.val[1]))});
284
+ }
285
+ };
286
+
287
+ /**********************************************************
288
+ * BF16 Quantizer
289
+ **********************************************************/
290
+
291
+ template <>
292
+ struct QuantizerBF16<SIMDLevel::ARM_NEON> : QuantizerBF16<SIMDLevel::NONE> {
293
+ QuantizerBF16(size_t d, const std::vector<float>& trained)
294
+ : QuantizerBF16<SIMDLevel::NONE>(d, trained) {
295
+ assert(d % 8 == 0);
296
+ }
297
+
298
+ FAISS_ALWAYS_INLINE simd8float32
299
+ reconstruct_8_components(const uint8_t* code, int i) const {
300
+ uint16x4x2_t codei = vld1_u16_x2((const uint16_t*)(code + 2 * i));
301
+ return simd8float32(
302
+ float32x4x2_t{
303
+ vreinterpretq_f32_u32(
304
+ vshlq_n_u32(vmovl_u16(codei.val[0]), 16)),
305
+ vreinterpretq_f32_u32(
306
+ vshlq_n_u32(vmovl_u16(codei.val[1]), 16))});
307
+ }
308
+ };
309
+
310
+ /**********************************************************
311
+ * 8bit Direct Quantizer
312
+ **********************************************************/
313
+
314
+ template <>
315
+ struct Quantizer8bitDirect<SIMDLevel::ARM_NEON>
316
+ : Quantizer8bitDirect<SIMDLevel::NONE> {
317
+ Quantizer8bitDirect(size_t d, const std::vector<float>& trained)
318
+ : Quantizer8bitDirect<SIMDLevel::NONE>(d, trained) {
319
+ assert(d % 8 == 0);
320
+ }
321
+
322
+ FAISS_ALWAYS_INLINE simd8float32
323
+ reconstruct_8_components(const uint8_t* code, int i) const {
324
+ uint8x8_t x8 = vld1_u8((const uint8_t*)(code + i));
325
+ uint16x8_t y8 = vmovl_u8(x8);
326
+ uint16x4_t y8_0 = vget_low_u16(y8);
327
+ uint16x4_t y8_1 = vget_high_u16(y8);
328
+ return simd8float32(
329
+ float32x4x2_t{
330
+ vcvtq_f32_u32(vmovl_u16(y8_0)),
331
+ vcvtq_f32_u32(vmovl_u16(y8_1))});
332
+ }
333
+ };
334
+
335
+ /**********************************************************
336
+ * 8bit Direct Signed Quantizer
337
+ **********************************************************/
338
+
339
+ template <>
340
+ struct Quantizer8bitDirectSigned<SIMDLevel::ARM_NEON>
341
+ : Quantizer8bitDirectSigned<SIMDLevel::NONE> {
342
+ Quantizer8bitDirectSigned(size_t d, const std::vector<float>& trained)
343
+ : Quantizer8bitDirectSigned<SIMDLevel::NONE>(d, trained) {
344
+ assert(d % 8 == 0);
345
+ }
346
+
347
+ FAISS_ALWAYS_INLINE simd8float32
348
+ reconstruct_8_components(const uint8_t* code, int i) const {
349
+ uint8x8_t x8 = vld1_u8((const uint8_t*)(code + i));
350
+ uint16x8_t y8 = vmovl_u8(x8);
351
+ int16x8_t z8 = vreinterpretq_s16_u16(
352
+ vsubq_u16(y8, vdupq_n_u16(128))); // subtract 128 from all lanes
353
+ int16x4_t z8_0 = vget_low_s16(z8);
354
+ int16x4_t z8_1 = vget_high_s16(z8);
355
+ return simd8float32(
356
+ float32x4x2_t{
357
+ vcvtq_f32_s32(vmovl_s16(z8_0)),
358
+ vcvtq_f32_s32(vmovl_s16(z8_1))});
359
+ }
360
+ };
361
+
362
+ /**********************************************************
363
+ * Similarities (L2 and IP)
364
+ **********************************************************/
365
+
366
+ template <>
367
+ struct SimilarityL2<SIMDLevel::ARM_NEON> {
368
+ static constexpr int simdwidth = 8;
369
+ static constexpr SIMDLevel simd_level = SIMDLevel::ARM_NEON;
370
+ static constexpr MetricType metric_type = METRIC_L2;
371
+
372
+ const float *y, *yi;
373
+
374
+ explicit SimilarityL2(const float* y) : y(y), yi(nullptr) {}
375
+
376
+ simd8float32 accu8;
377
+
378
+ FAISS_ALWAYS_INLINE void begin_8() {
379
+ accu8.clear();
380
+ yi = y;
381
+ }
382
+
383
+ FAISS_ALWAYS_INLINE void add_8_components(simd8float32 x) {
384
+ simd8float32 yiv(yi);
385
+ yi += 8;
386
+ simd8float32 tmp = yiv - x;
387
+ accu8 = accu8 + tmp * tmp;
388
+ }
389
+
390
+ FAISS_ALWAYS_INLINE void add_8_components_2(
391
+ simd8float32 x,
392
+ simd8float32 y_2) {
393
+ simd8float32 tmp = y_2 - x;
394
+ accu8 = accu8 + tmp * tmp;
395
+ }
396
+
397
+ FAISS_ALWAYS_INLINE float result_8() {
398
+ return horizontal_add(accu8);
399
+ }
400
+ };
401
+
402
+ template <>
403
+ struct SimilarityIP<SIMDLevel::ARM_NEON> {
404
+ static constexpr int simdwidth = 8;
405
+ static constexpr SIMDLevel simd_level = SIMDLevel::ARM_NEON;
406
+ static constexpr MetricType metric_type = METRIC_INNER_PRODUCT;
407
+
408
+ const float *y, *yi;
409
+
410
+ explicit SimilarityIP(const float* y) : y(y), yi(nullptr) {}
411
+
412
+ simd8float32 accu8;
413
+
414
+ FAISS_ALWAYS_INLINE void begin_8() {
415
+ accu8.clear();
416
+ yi = y;
417
+ }
418
+
419
+ FAISS_ALWAYS_INLINE void add_8_components(simd8float32 x) {
420
+ simd8float32 yiv(yi);
421
+ yi += 8;
422
+ accu8 = accu8 + yiv * x;
423
+ }
424
+
425
+ FAISS_ALWAYS_INLINE void add_8_components_2(
426
+ simd8float32 x1,
427
+ simd8float32 x2) {
428
+ accu8 = accu8 + x1 * x2;
429
+ }
430
+
431
+ FAISS_ALWAYS_INLINE float result_8() {
432
+ return horizontal_add(accu8);
433
+ }
434
+ };
435
+
436
+ /**********************************************************
437
+ * Distance Computers
438
+ **********************************************************/
439
+
440
+ template <class Quantizer, class Similarity>
441
+ struct DCTemplate<Quantizer, Similarity, SIMDLevel::ARM_NEON>
442
+ : SQDistanceComputer {
443
+ using Sim = Similarity;
444
+
445
+ Quantizer quant;
446
+
447
+ DCTemplate(size_t d, const std::vector<float>& trained)
448
+ : quant(d, trained) {}
449
+
450
+ float compute_distance(const float* x, const uint8_t* code) const {
451
+ Similarity sim(x);
452
+ sim.begin_8();
453
+ for (size_t i = 0; i < quant.d; i += 8) {
454
+ simd8float32 xi = quant.reconstruct_8_components(code, i);
455
+ sim.add_8_components(xi);
456
+ }
457
+ return sim.result_8();
458
+ }
459
+
460
+ float compute_code_distance(const uint8_t* code1, const uint8_t* code2)
461
+ const {
462
+ Similarity sim(nullptr);
463
+ sim.begin_8();
464
+ for (size_t i = 0; i < quant.d; i += 8) {
465
+ simd8float32 x1 = quant.reconstruct_8_components(code1, i);
466
+ simd8float32 x2 = quant.reconstruct_8_components(code2, i);
467
+ sim.add_8_components_2(x1, x2);
468
+ }
469
+ return sim.result_8();
470
+ }
471
+
472
+ void set_query(const float* x) final {
473
+ q = x;
474
+ }
475
+
476
+ float symmetric_dis(idx_t i, idx_t j) override {
477
+ return compute_code_distance(
478
+ codes + i * code_size, codes + j * code_size);
479
+ }
480
+
481
+ float query_to_code(const uint8_t* code) const final {
482
+ return compute_distance(q, code);
483
+ }
484
+
485
+ void query_to_codes_batch_4(
486
+ const uint8_t* code_0,
487
+ const uint8_t* code_1,
488
+ const uint8_t* code_2,
489
+ const uint8_t* code_3,
490
+ float& dis0,
491
+ float& dis1,
492
+ float& dis2,
493
+ float& dis3) const final {
494
+ Similarity sim0(q);
495
+ Similarity sim1(q);
496
+ Similarity sim2(q);
497
+ Similarity sim3(q);
498
+
499
+ sim0.begin_8();
500
+ sim1.begin_8();
501
+ sim2.begin_8();
502
+ sim3.begin_8();
503
+
504
+ for (size_t i = 0; i < quant.d; i += 8) {
505
+ simd8float32 xi0 = quant.reconstruct_8_components(code_0, i);
506
+ simd8float32 xi1 = quant.reconstruct_8_components(code_1, i);
507
+ simd8float32 xi2 = quant.reconstruct_8_components(code_2, i);
508
+ simd8float32 xi3 = quant.reconstruct_8_components(code_3, i);
509
+ sim0.add_8_components(xi0);
510
+ sim1.add_8_components(xi1);
511
+ sim2.add_8_components(xi2);
512
+ sim3.add_8_components(xi3);
513
+ }
514
+
515
+ dis0 = sim0.result_8();
516
+ dis1 = sim1.result_8();
517
+ dis2 = sim2.result_8();
518
+ dis3 = sim3.result_8();
519
+ }
520
+ };
521
+
522
+ template <class Similarity>
523
+ struct DistanceComputerByte<Similarity, SIMDLevel::ARM_NEON>
524
+ : SQDistanceComputer {
525
+ using Sim = Similarity;
526
+
527
+ int d;
528
+ std::vector<uint8_t> tmp;
529
+
530
+ DistanceComputerByte(int d, const std::vector<float>&) : d(d), tmp(d) {}
531
+
532
+ int compute_code_distance(const uint8_t* code1, const uint8_t* code2)
533
+ const {
534
+ int accu = 0;
535
+ for (int i = 0; i < d; i++) {
536
+ if (Sim::metric_type == METRIC_INNER_PRODUCT) {
537
+ accu += int(code1[i]) * code2[i];
538
+ } else {
539
+ int diff = int(code1[i]) - code2[i];
540
+ accu += diff * diff;
541
+ }
542
+ }
543
+ return accu;
544
+ }
545
+
546
+ void set_query(const float* x) final {
547
+ for (int i = 0; i < d; i++) {
548
+ tmp[i] = int(x[i]);
549
+ }
550
+ }
551
+
552
+ int compute_distance(const float* x, const uint8_t* code) {
553
+ set_query(x);
554
+ return compute_code_distance(tmp.data(), code);
555
+ }
556
+
557
+ float symmetric_dis(idx_t i, idx_t j) override {
558
+ return compute_code_distance(
559
+ codes + i * code_size, codes + j * code_size);
560
+ }
561
+
562
+ float query_to_code(const uint8_t* code) const final {
563
+ return compute_code_distance(tmp.data(), code);
564
+ }
565
+ };
566
+
567
+ } // namespace scalar_quantizer
568
+ } // namespace faiss
569
+
570
+ #define THE_LEVEL_TO_DISPATCH SIMDLevel::ARM_NEON
571
+ #include <faiss/impl/scalar_quantizer/sq-dispatch.h>
572
+
573
+ #ifdef COMPILE_SIMD_ARM_SVE
574
+
575
+ // ARM_SVE: SVE is a superset of NEON. Forward to the NEON implementation
576
+ // until a dedicated SVE specialization is written.
577
+
578
+ namespace faiss {
579
+ namespace scalar_quantizer {
580
+
581
+ // NOLINTNEXTLINE(facebook-hte-MisplacedTemplateSpecialization)
582
+ template <>
583
+ ScalarQuantizer::SQuantizer* sq_select_quantizer<SIMDLevel::ARM_SVE>(
584
+ QuantizerType qtype,
585
+ size_t d,
586
+ const std::vector<float>& trained) {
587
+ return sq_select_quantizer<SIMDLevel::ARM_NEON>(qtype, d, trained);
588
+ }
589
+
590
+ // NOLINTNEXTLINE(facebook-hte-MisplacedTemplateSpecialization)
591
+ template <>
592
+ SQDistanceComputer* sq_select_distance_computer<SIMDLevel::ARM_SVE>(
593
+ MetricType metric,
594
+ ScalarQuantizer::QuantizerType qtype,
595
+ size_t d,
596
+ const std::vector<float>& trained) {
597
+ return sq_select_distance_computer<SIMDLevel::ARM_NEON>(
598
+ metric, qtype, d, trained);
599
+ }
600
+
601
+ // NOLINTNEXTLINE(facebook-hte-MisplacedTemplateSpecialization)
602
+ template <>
603
+ InvertedListScanner* sq_select_InvertedListScanner<SIMDLevel::ARM_SVE>(
604
+ QuantizerType qtype,
605
+ MetricType mt,
606
+ size_t d,
607
+ size_t code_size,
608
+ const std::vector<float>& trained,
609
+ const Index* quantizer,
610
+ bool store_pairs,
611
+ const IDSelector* sel,
612
+ bool by_residual) {
613
+ return sq_select_InvertedListScanner<SIMDLevel::ARM_NEON>(
614
+ qtype,
615
+ mt,
616
+ d,
617
+ code_size,
618
+ trained,
619
+ quantizer,
620
+ store_pairs,
621
+ sel,
622
+ by_residual);
623
+ }
624
+
625
+ } // namespace scalar_quantizer
626
+ } // namespace faiss
627
+
628
+ #endif // COMPILE_SIMD_ARM_SVE
629
+
630
+ #endif // COMPILE_SIMD_ARM_NEON