faiss 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/ext/faiss/extconf.rb +2 -1
  4. data/ext/faiss/{index_rb.cpp → index.cpp} +1 -1
  5. data/ext/faiss/index_binary.cpp +1 -1
  6. data/ext/faiss/kmeans.cpp +1 -1
  7. data/ext/faiss/pca_matrix.cpp +1 -1
  8. data/ext/faiss/product_quantizer.cpp +1 -1
  9. data/ext/faiss/{utils_rb.cpp → utils.cpp} +1 -1
  10. data/lib/faiss/version.rb +1 -1
  11. data/vendor/faiss/faiss/AutoTune.cpp +93 -80
  12. data/vendor/faiss/faiss/Clustering.cpp +39 -240
  13. data/vendor/faiss/faiss/Clustering.h +6 -0
  14. data/vendor/faiss/faiss/IVFlib.cpp +41 -21
  15. data/vendor/faiss/faiss/Index.cpp +6 -5
  16. data/vendor/faiss/faiss/Index.h +5 -5
  17. data/vendor/faiss/faiss/Index2Layer.cpp +37 -53
  18. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +49 -37
  19. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +36 -34
  20. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +4 -1
  21. data/vendor/faiss/faiss/IndexBinary.cpp +5 -3
  22. data/vendor/faiss/faiss/IndexBinary.h +4 -4
  23. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +1 -1
  24. data/vendor/faiss/faiss/IndexBinaryFlat.h +1 -1
  25. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -4
  26. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +84 -92
  27. data/vendor/faiss/faiss/IndexBinaryHNSW.h +9 -3
  28. data/vendor/faiss/faiss/IndexBinaryHash.cpp +45 -236
  29. data/vendor/faiss/faiss/IndexBinaryHash.h +6 -6
  30. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +87 -415
  31. data/vendor/faiss/faiss/IndexFastScan.cpp +72 -109
  32. data/vendor/faiss/faiss/IndexFastScan.h +25 -23
  33. data/vendor/faiss/faiss/IndexFlat.cpp +27 -20
  34. data/vendor/faiss/faiss/IndexFlat.h +21 -18
  35. data/vendor/faiss/faiss/IndexFlatCodes.cpp +42 -19
  36. data/vendor/faiss/faiss/IndexHNSW.cpp +283 -145
  37. data/vendor/faiss/faiss/IndexHNSW.h +16 -2
  38. data/vendor/faiss/faiss/IndexIDMap.cpp +25 -21
  39. data/vendor/faiss/faiss/IndexIDMap.h +9 -7
  40. data/vendor/faiss/faiss/IndexIVF.cpp +465 -362
  41. data/vendor/faiss/faiss/IndexIVF.h +33 -12
  42. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +77 -74
  43. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +96 -93
  44. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +4 -1
  45. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +357 -238
  46. data/vendor/faiss/faiss/IndexIVFFastScan.h +42 -41
  47. data/vendor/faiss/faiss/IndexIVFFlat.cpp +36 -68
  48. data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
  49. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +53 -30
  50. data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
  51. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
  52. data/vendor/faiss/faiss/IndexIVFPQ.cpp +71 -843
  53. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +151 -121
  54. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
  55. data/vendor/faiss/faiss/IndexIVFPQR.cpp +21 -17
  56. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +26 -39
  57. data/vendor/faiss/faiss/IndexIVFRaBitQ.h +2 -1
  58. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +475 -476
  59. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +248 -93
  60. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +41 -127
  61. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
  62. data/vendor/faiss/faiss/IndexLSH.cpp +36 -19
  63. data/vendor/faiss/faiss/IndexLattice.cpp +13 -13
  64. data/vendor/faiss/faiss/IndexNNDescent.cpp +36 -21
  65. data/vendor/faiss/faiss/IndexNNDescent.h +2 -2
  66. data/vendor/faiss/faiss/IndexNSG.cpp +39 -23
  67. data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +31 -11
  68. data/vendor/faiss/faiss/IndexPQ.cpp +128 -221
  69. data/vendor/faiss/faiss/IndexPQ.h +3 -2
  70. data/vendor/faiss/faiss/IndexPQFastScan.cpp +20 -14
  71. data/vendor/faiss/faiss/IndexPQFastScan.h +3 -0
  72. data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -18
  73. data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
  74. data/vendor/faiss/faiss/IndexRaBitQ.cpp +11 -36
  75. data/vendor/faiss/faiss/IndexRaBitQ.h +2 -1
  76. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +41 -277
  77. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +183 -27
  78. data/vendor/faiss/faiss/IndexRefine.cpp +30 -25
  79. data/vendor/faiss/faiss/IndexRefine.h +4 -4
  80. data/vendor/faiss/faiss/IndexReplicas.cpp +6 -6
  81. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +15 -14
  82. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +1 -1
  83. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +82 -14
  84. data/vendor/faiss/faiss/IndexShards.cpp +10 -9
  85. data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
  86. data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
  87. data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
  88. data/vendor/faiss/faiss/MetaIndexes.h +1 -1
  89. data/vendor/faiss/faiss/MetricType.h +14 -7
  90. data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
  91. data/vendor/faiss/faiss/SuperKMeans.h +97 -0
  92. data/vendor/faiss/faiss/VectorTransform.cpp +237 -149
  93. data/vendor/faiss/faiss/VectorTransform.h +16 -16
  94. data/vendor/faiss/faiss/build.cpp +23 -0
  95. data/vendor/faiss/faiss/build.h +15 -0
  96. data/vendor/faiss/faiss/clone_index.cpp +48 -47
  97. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
  98. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
  99. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
  100. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
  101. data/vendor/faiss/faiss/factory_tools.cpp +5 -0
  102. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
  103. data/vendor/faiss/faiss/gpu/GpuResources.h +1 -1
  104. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +9 -9
  105. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +4 -3
  106. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
  107. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
  108. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
  109. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
  110. data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
  111. data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
  112. data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
  113. data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
  114. data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
  115. data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
  116. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +51 -0
  117. data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
  118. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +66 -0
  119. data/vendor/faiss/faiss/gpu_metal/MetalResources.h +79 -0
  120. data/vendor/faiss/faiss/gpu_metal/StandardMetalResources.h +35 -0
  121. data/vendor/faiss/faiss/impl/AdSampling.cpp +103 -0
  122. data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
  123. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +29 -25
  124. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
  125. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
  126. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -0
  127. data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
  128. data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
  129. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +16 -16
  130. data/vendor/faiss/faiss/impl/CodePacker.cpp +3 -3
  131. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +1 -1
  132. data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
  133. data/vendor/faiss/faiss/impl/FaissAssert.h +6 -3
  134. data/vendor/faiss/faiss/impl/FaissException.h +50 -3
  135. data/vendor/faiss/faiss/impl/HNSW.cpp +92 -317
  136. data/vendor/faiss/faiss/impl/HNSW.h +13 -34
  137. data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
  138. data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
  139. data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
  140. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +82 -77
  141. data/vendor/faiss/faiss/impl/NNDescent.cpp +62 -25
  142. data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
  143. data/vendor/faiss/faiss/impl/NSG.cpp +38 -21
  144. data/vendor/faiss/faiss/impl/NSG.h +4 -4
  145. data/vendor/faiss/faiss/impl/Panorama.cpp +23 -6
  146. data/vendor/faiss/faiss/impl/Panorama.h +258 -87
  147. data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
  148. data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
  149. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +46 -32
  150. data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
  151. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
  152. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
  153. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +30 -23
  154. data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
  155. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +55 -49
  156. data/vendor/faiss/faiss/impl/RaBitQUtils.h +65 -0
  157. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +296 -283
  158. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +26 -23
  159. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
  160. data/vendor/faiss/faiss/impl/ResultHandler.h +99 -75
  161. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +52 -4
  162. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +27 -1
  163. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
  164. data/vendor/faiss/faiss/impl/VisitedTable.h +7 -0
  165. data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
  166. data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
  167. data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
  168. data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
  169. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
  170. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
  171. data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
  172. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
  173. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
  174. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
  175. data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
  176. data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
  177. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
  178. data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
  179. data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
  180. data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
  181. data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
  182. data/vendor/faiss/faiss/impl/expanded_scanners.h +8 -3
  183. data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
  184. data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
  185. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
  186. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
  187. data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
  188. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +268 -0
  189. data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +169 -2
  190. data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
  191. data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
  192. data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
  193. data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
  194. data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
  195. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
  196. data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -356
  197. data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
  198. data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
  199. data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +282 -134
  200. data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
  201. data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
  202. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +91 -0
  203. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -0
  204. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +104 -0
  205. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +111 -0
  206. data/vendor/faiss/faiss/impl/index_read.cpp +1132 -45
  207. data/vendor/faiss/faiss/impl/index_read_utils.h +1 -1
  208. data/vendor/faiss/faiss/impl/index_write.cpp +95 -13
  209. data/vendor/faiss/faiss/impl/io.cpp +6 -6
  210. data/vendor/faiss/faiss/impl/io_macros.h +33 -16
  211. data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
  212. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +37 -23
  213. data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
  214. data/vendor/faiss/faiss/impl/mapped_io.cpp +6 -6
  215. data/vendor/faiss/faiss/impl/platform_macros.h +11 -4
  216. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
  217. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
  218. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
  219. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
  220. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +21 -0
  221. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +21 -0
  222. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +21 -0
  223. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx2.cpp → pq_code_distance-avx2.h} +9 -13
  224. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx512.cpp → pq_code_distance-avx512.h} +9 -57
  225. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +29 -111
  226. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
  227. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +238 -5
  228. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +5 -7
  229. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +68 -0
  230. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +311 -477
  231. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
  232. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +1 -1
  233. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +3 -2
  234. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +102 -11
  235. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +27 -1
  236. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +3 -3
  237. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +148 -0
  238. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +167 -0
  239. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +59 -0
  240. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +163 -0
  241. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +311 -0
  242. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +192 -8
  243. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +12 -0
  244. data/vendor/faiss/faiss/impl/simd_dispatch.h +100 -66
  245. data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
  246. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +264 -172
  247. data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
  248. data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
  249. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
  250. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +270 -218
  251. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
  252. data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
  253. data/vendor/faiss/faiss/impl/svs_io.h +8 -2
  254. data/vendor/faiss/faiss/index_factory.cpp +86 -18
  255. data/vendor/faiss/faiss/index_io.h +24 -0
  256. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +66 -16
  257. data/vendor/faiss/faiss/invlists/DirectMap.cpp +24 -14
  258. data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
  259. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +157 -73
  260. data/vendor/faiss/faiss/invlists/InvertedLists.h +86 -23
  261. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
  262. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +13 -13
  263. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  264. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +1 -1
  265. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
  266. data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
  267. data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
  268. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
  269. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
  270. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
  271. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
  272. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +25 -1
  273. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +18 -2
  274. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +1 -1
  275. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +12 -3
  276. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +7 -2
  277. data/vendor/faiss/faiss/utils/Heap.cpp +10 -10
  278. data/vendor/faiss/faiss/utils/NeuralNet.cpp +47 -36
  279. data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
  280. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
  281. data/vendor/faiss/faiss/utils/distances.cpp +390 -560
  282. data/vendor/faiss/faiss/utils/distances.h +20 -1
  283. data/vendor/faiss/faiss/utils/distances_dispatch.h +117 -37
  284. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
  285. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
  286. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
  287. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
  288. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
  289. data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
  290. data/vendor/faiss/faiss/utils/distances_simd.cpp +5 -177
  291. data/vendor/faiss/faiss/utils/extra_distances.cpp +9 -8
  292. data/vendor/faiss/faiss/utils/extra_distances.h +32 -6
  293. data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
  294. data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
  295. data/vendor/faiss/faiss/utils/hamming.h +92 -2
  296. data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
  297. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +15 -0
  298. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
  299. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
  300. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +234 -0
  301. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-generic.h +368 -0
  302. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +322 -0
  303. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-rvv.h +39 -0
  304. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer.h +146 -0
  305. data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +481 -0
  306. data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +15 -0
  307. data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +15 -0
  308. data/vendor/faiss/faiss/utils/partitioning.cpp +66 -987
  309. data/vendor/faiss/faiss/utils/partitioning.h +31 -0
  310. data/vendor/faiss/faiss/utils/popcount.h +29 -0
  311. data/vendor/faiss/faiss/utils/pq_code_distance.h +2 -2
  312. data/vendor/faiss/faiss/utils/prefetch.h +2 -2
  313. data/vendor/faiss/faiss/utils/quantize_lut.cpp +30 -30
  314. data/vendor/faiss/faiss/utils/quantize_lut.h +1 -1
  315. data/vendor/faiss/faiss/utils/rabitq_simd.h +57 -536
  316. data/vendor/faiss/faiss/utils/random.cpp +6 -6
  317. data/vendor/faiss/faiss/utils/simd_impl/IVFFlatScanner-inl.h +51 -0
  318. data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +5 -1
  319. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +213 -4
  320. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +163 -10
  321. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +250 -4
  322. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +7 -4
  323. data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +189 -0
  324. data/vendor/faiss/faiss/utils/simd_impl/distances_simdlib256.h +195 -0
  325. data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +2 -1
  326. data/vendor/faiss/faiss/utils/{distances_fused/simdlib_based.h → simd_impl/exhaustive_L2sqr_blas_cmax.h} +5 -10
  327. data/vendor/faiss/faiss/utils/simd_impl/hamming_impl.h +481 -0
  328. data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +14 -0
  329. data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +14 -0
  330. data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +1085 -0
  331. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +355 -0
  332. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +477 -0
  333. data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +55 -0
  334. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
  335. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
  336. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
  337. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
  338. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
  339. data/vendor/faiss/faiss/utils/simd_levels.cpp +17 -5
  340. data/vendor/faiss/faiss/utils/simd_levels.h +93 -1
  341. data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
  342. data/vendor/faiss/faiss/utils/utils.cpp +5 -5
  343. data/vendor/faiss/faiss/utils/utils.h +3 -3
  344. metadata +119 -34
  345. data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
  346. data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
  347. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -224
  348. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -230
  349. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
  350. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
  351. data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
  352. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
  353. data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -235
  354. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
  355. data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
  356. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -449
  357. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
  358. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
  359. data/vendor/faiss/faiss/utils/simdlib.h +0 -42
  360. data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -365
  361. /data/ext/faiss/{utils_rb.h → utils.h} +0 -0
@@ -12,9 +12,12 @@
12
12
  #include <cstring>
13
13
  #include <string>
14
14
 
15
+ #include <faiss/impl/simdlib/simdlib.h>
16
+
15
17
  namespace faiss {
16
18
 
17
- struct simd256bit {
19
+ template <>
20
+ struct simd256bit_tpl<SIMDLevel::NONE> {
18
21
  union {
19
22
  uint8_t u8[32];
20
23
  uint16_t u16[16];
@@ -22,9 +25,9 @@ struct simd256bit {
22
25
  float f32[8];
23
26
  };
24
27
 
25
- simd256bit() {}
28
+ simd256bit_tpl() {}
26
29
 
27
- explicit simd256bit(const void* x) {
30
+ explicit simd256bit_tpl(const void* x) {
28
31
  memcpy(u8, x, 32);
29
32
  }
30
33
 
@@ -59,7 +62,7 @@ struct simd256bit {
59
62
  }
60
63
 
61
64
  // Checks whether the other holds exactly the same bytes.
62
- bool is_same_as(simd256bit other) const {
65
+ bool is_same_as(simd256bit_tpl other) const {
63
66
  for (size_t i = 0; i < 8; i++) {
64
67
  if (u32[i] != other.u32[i]) {
65
68
  return false;
@@ -71,22 +74,25 @@ struct simd256bit {
71
74
  };
72
75
 
73
76
  /// vector of 16 elements in uint16
74
- struct simd16uint16 : simd256bit {
75
- simd16uint16() {}
77
+ template <>
78
+ struct simd16uint16_tpl<SIMDLevel::NONE> : simd256bit_tpl<SIMDLevel::NONE> {
79
+ simd16uint16_tpl() {}
76
80
 
77
- explicit simd16uint16(int x) {
81
+ explicit simd16uint16_tpl(int x) {
78
82
  set1(x);
79
83
  }
80
84
 
81
- explicit simd16uint16(uint16_t x) {
85
+ explicit simd16uint16_tpl(uint16_t x) {
82
86
  set1(x);
83
87
  }
84
88
 
85
- explicit simd16uint16(const simd256bit& x) : simd256bit(x) {}
89
+ explicit simd16uint16_tpl(const simd256bit_tpl<SIMDLevel::NONE>& x)
90
+ : simd256bit_tpl<SIMDLevel::NONE>(x) {}
86
91
 
87
- explicit simd16uint16(const uint16_t* x) : simd256bit((const void*)x) {}
92
+ explicit simd16uint16_tpl(const uint16_t* x)
93
+ : simd256bit_tpl<SIMDLevel::NONE>((const void*)x) {}
88
94
 
89
- explicit simd16uint16(
95
+ explicit simd16uint16_tpl(
90
96
  uint16_t u0,
91
97
  uint16_t u1,
92
98
  uint16_t u2,
@@ -140,8 +146,8 @@ struct simd16uint16 : simd256bit {
140
146
  }
141
147
 
142
148
  template <typename F>
143
- static simd16uint16 unary_func(const simd16uint16& a, F&& f) {
144
- simd16uint16 c;
149
+ static simd16uint16_tpl unary_func(const simd16uint16_tpl& a, F&& f) {
150
+ simd16uint16_tpl c;
145
151
  for (int j = 0; j < 16; j++) {
146
152
  c.u16[j] = f(a.u16[j]);
147
153
  }
@@ -149,11 +155,11 @@ struct simd16uint16 : simd256bit {
149
155
  }
150
156
 
151
157
  template <typename F>
152
- static simd16uint16 binary_func(
153
- const simd16uint16& a,
154
- const simd16uint16& b,
158
+ static simd16uint16_tpl binary_func(
159
+ const simd16uint16_tpl& a,
160
+ const simd16uint16_tpl& b,
155
161
  F&& f) {
156
- simd16uint16 c;
162
+ simd16uint16_tpl c;
157
163
  for (int j = 0; j < 16; j++) {
158
164
  c.u16[j] = f(a.u16[j], b.u16[j]);
159
165
  }
@@ -166,70 +172,73 @@ struct simd16uint16 : simd256bit {
166
172
  }
167
173
  }
168
174
 
169
- simd16uint16 operator*(const simd16uint16& other) const {
175
+ simd16uint16_tpl operator*(const simd16uint16_tpl& other) const {
170
176
  return binary_func(
171
177
  *this, other, [](uint16_t a, uint16_t b) { return a * b; });
172
178
  }
173
179
 
174
180
  // shift must be known at compile time
175
- simd16uint16 operator>>(const int shift) const {
181
+ simd16uint16_tpl operator>>(const int shift) const {
176
182
  return unary_func(*this, [shift](uint16_t a) { return a >> shift; });
177
183
  }
178
184
 
179
185
  // shift must be known at compile time
180
- simd16uint16 operator<<(const int shift) const {
186
+ simd16uint16_tpl operator<<(const int shift) const {
181
187
  return unary_func(*this, [shift](uint16_t a) { return a << shift; });
182
188
  }
183
189
 
184
- simd16uint16 operator+=(const simd16uint16& other) {
190
+ simd16uint16_tpl& operator+=(const simd16uint16_tpl& other) {
185
191
  *this = *this + other;
186
192
  return *this;
187
193
  }
188
194
 
189
- simd16uint16 operator-=(const simd16uint16& other) {
195
+ simd16uint16_tpl& operator-=(const simd16uint16_tpl& other) {
190
196
  *this = *this - other;
191
197
  return *this;
192
198
  }
193
199
 
194
- simd16uint16 operator+(const simd16uint16& other) const {
200
+ simd16uint16_tpl operator+(const simd16uint16_tpl& other) const {
195
201
  return binary_func(
196
202
  *this, other, [](uint16_t a, uint16_t b) { return a + b; });
197
203
  }
198
204
 
199
- simd16uint16 operator-(const simd16uint16& other) const {
205
+ simd16uint16_tpl operator-(const simd16uint16_tpl& other) const {
200
206
  return binary_func(
201
207
  *this, other, [](uint16_t a, uint16_t b) { return a - b; });
202
208
  }
203
209
 
204
- simd16uint16 operator&(const simd256bit& other) const {
210
+ simd16uint16_tpl operator&(
211
+ const simd256bit_tpl<SIMDLevel::NONE>& other) const {
205
212
  return binary_func(
206
- *this, simd16uint16(other), [](uint16_t a, uint16_t b) {
213
+ *this, simd16uint16_tpl(other), [](uint16_t a, uint16_t b) {
207
214
  return a & b;
208
215
  });
209
216
  }
210
217
 
211
- simd16uint16 operator|(const simd256bit& other) const {
218
+ simd16uint16_tpl operator|(
219
+ const simd256bit_tpl<SIMDLevel::NONE>& other) const {
212
220
  return binary_func(
213
- *this, simd16uint16(other), [](uint16_t a, uint16_t b) {
221
+ *this, simd16uint16_tpl(other), [](uint16_t a, uint16_t b) {
214
222
  return a | b;
215
223
  });
216
224
  }
217
225
 
218
- simd16uint16 operator^(const simd256bit& other) const {
226
+ simd16uint16_tpl operator^(
227
+ const simd256bit_tpl<SIMDLevel::NONE>& other) const {
219
228
  return binary_func(
220
- *this, simd16uint16(other), [](uint16_t a, uint16_t b) {
229
+ *this, simd16uint16_tpl(other), [](uint16_t a, uint16_t b) {
221
230
  return a ^ b;
222
231
  });
223
232
  }
224
233
 
225
234
  // returns binary masks
226
- simd16uint16 operator==(const simd16uint16& other) const {
235
+ simd16uint16_tpl operator==(const simd16uint16_tpl& other) const {
227
236
  return binary_func(*this, other, [](uint16_t a, uint16_t b) {
228
237
  return a == b ? 0xffff : 0;
229
238
  });
230
239
  }
231
240
 
232
- simd16uint16 operator~() const {
241
+ simd16uint16_tpl operator~() const {
233
242
  return unary_func(*this, [](uint16_t a) { return ~a; });
234
243
  }
235
244
 
@@ -240,7 +249,7 @@ struct simd16uint16 : simd256bit {
240
249
 
241
250
  // mask of elements where this >= thresh
242
251
  // 2 bit per component: 16 * 2 = 32 bit
243
- uint32_t ge_mask(const simd16uint16& thresh) const {
252
+ uint32_t ge_mask(const simd16uint16_tpl& thresh) const {
244
253
  uint32_t gem = 0;
245
254
  for (int j = 0; j < 16; j++) {
246
255
  if (u16[j] >= thresh.u16[j]) {
@@ -250,15 +259,15 @@ struct simd16uint16 : simd256bit {
250
259
  return gem;
251
260
  }
252
261
 
253
- uint32_t le_mask(const simd16uint16& thresh) const {
262
+ uint32_t le_mask(const simd16uint16_tpl& thresh) const {
254
263
  return thresh.ge_mask(*this);
255
264
  }
256
265
 
257
- uint32_t gt_mask(const simd16uint16& thresh) const {
266
+ uint32_t gt_mask(const simd16uint16_tpl& thresh) const {
258
267
  return ~le_mask(thresh);
259
268
  }
260
269
 
261
- bool all_gt(const simd16uint16& thresh) const {
270
+ bool all_gt(const simd16uint16_tpl& thresh) const {
262
271
  return le_mask(thresh) == 0;
263
272
  }
264
273
 
@@ -267,7 +276,7 @@ struct simd16uint16 : simd256bit {
267
276
  return u16[i];
268
277
  }
269
278
 
270
- void accu_min(const simd16uint16& incoming) {
279
+ void accu_min(const simd16uint16_tpl& incoming) {
271
280
  for (int j = 0; j < 16; j++) {
272
281
  if (incoming.u16[j] < u16[j]) {
273
282
  u16[j] = incoming.u16[j];
@@ -275,7 +284,7 @@ struct simd16uint16 : simd256bit {
275
284
  }
276
285
  }
277
286
 
278
- void accu_max(const simd16uint16& incoming) {
287
+ void accu_max(const simd16uint16_tpl& incoming) {
279
288
  for (int j = 0; j < 16; j++) {
280
289
  if (incoming.u16[j] > u16[j]) {
281
290
  u16[j] = incoming.u16[j];
@@ -285,21 +294,27 @@ struct simd16uint16 : simd256bit {
285
294
  };
286
295
 
287
296
  // not really a std::min because it returns an elementwise min
288
- inline simd16uint16 min(const simd16uint16& av, const simd16uint16& bv) {
289
- return simd16uint16::binary_func(
297
+ inline simd16uint16_tpl<SIMDLevel::NONE> min(
298
+ const simd16uint16_tpl<SIMDLevel::NONE>& av,
299
+ const simd16uint16_tpl<SIMDLevel::NONE>& bv) {
300
+ return simd16uint16_tpl<SIMDLevel::NONE>::binary_func(
290
301
  av, bv, [](uint16_t a, uint16_t b) { return std::min(a, b); });
291
302
  }
292
303
 
293
- inline simd16uint16 max(const simd16uint16& av, const simd16uint16& bv) {
294
- return simd16uint16::binary_func(
304
+ inline simd16uint16_tpl<SIMDLevel::NONE> max(
305
+ const simd16uint16_tpl<SIMDLevel::NONE>& av,
306
+ const simd16uint16_tpl<SIMDLevel::NONE>& bv) {
307
+ return simd16uint16_tpl<SIMDLevel::NONE>::binary_func(
295
308
  av, bv, [](uint16_t a, uint16_t b) { return std::max(a, b); });
296
309
  }
297
310
 
298
311
  // decompose in 128-lanes: a = (a0, a1), b = (b0, b1)
299
312
  // return (a0 + a1, b0 + b1)
300
313
  // TODO find a better name
301
- inline simd16uint16 combine2x2(const simd16uint16& a, const simd16uint16& b) {
302
- simd16uint16 c;
314
+ inline simd16uint16_tpl<SIMDLevel::NONE> combine2x2(
315
+ const simd16uint16_tpl<SIMDLevel::NONE>& a,
316
+ const simd16uint16_tpl<SIMDLevel::NONE>& b) {
317
+ simd16uint16_tpl<SIMDLevel::NONE> c;
303
318
  for (int j = 0; j < 8; j++) {
304
319
  c.u16[j] = a.u16[j] + a.u16[j + 8];
305
320
  c.u16[j + 8] = b.u16[j] + b.u16[j + 8];
@@ -310,9 +325,9 @@ inline simd16uint16 combine2x2(const simd16uint16& a, const simd16uint16& b) {
310
325
  // compare d0 and d1 to thr, return 32 bits corresponding to the concatenation
311
326
  // of d0 and d1 with thr
312
327
  inline uint32_t cmp_ge32(
313
- const simd16uint16& d0,
314
- const simd16uint16& d1,
315
- const simd16uint16& thr) {
328
+ const simd16uint16_tpl<SIMDLevel::NONE>& d0,
329
+ const simd16uint16_tpl<SIMDLevel::NONE>& d1,
330
+ const simd16uint16_tpl<SIMDLevel::NONE>& thr) {
316
331
  uint32_t gem = 0;
317
332
  for (int j = 0; j < 16; j++) {
318
333
  if (d0.u16[j] >= thr.u16[j]) {
@@ -326,9 +341,9 @@ inline uint32_t cmp_ge32(
326
341
  }
327
342
 
328
343
  inline uint32_t cmp_le32(
329
- const simd16uint16& d0,
330
- const simd16uint16& d1,
331
- const simd16uint16& thr) {
344
+ const simd16uint16_tpl<SIMDLevel::NONE>& d0,
345
+ const simd16uint16_tpl<SIMDLevel::NONE>& d1,
346
+ const simd16uint16_tpl<SIMDLevel::NONE>& thr) {
332
347
  uint32_t gem = 0;
333
348
  for (int j = 0; j < 16; j++) {
334
349
  if (d0.u16[j] <= thr.u16[j]) {
@@ -342,8 +357,10 @@ inline uint32_t cmp_le32(
342
357
  }
343
358
 
344
359
  // hadd does not cross lanes
345
- inline simd16uint16 hadd(const simd16uint16& a, const simd16uint16& b) {
346
- simd16uint16 c;
360
+ inline simd16uint16_tpl<SIMDLevel::NONE> hadd(
361
+ const simd16uint16_tpl<SIMDLevel::NONE>& a,
362
+ const simd16uint16_tpl<SIMDLevel::NONE>& b) {
363
+ simd16uint16_tpl<SIMDLevel::NONE> c;
347
364
  c.u16[0] = a.u16[0] + a.u16[1];
348
365
  c.u16[1] = a.u16[2] + a.u16[3];
349
366
  c.u16[2] = a.u16[4] + a.u16[5];
@@ -377,14 +394,14 @@ inline simd16uint16 hadd(const simd16uint16& a, const simd16uint16& b) {
377
394
  // the last equal value is saved instead of the first one), but this behavior
378
395
  // saves instructions.
379
396
  inline void cmplt_min_max_fast(
380
- const simd16uint16 candidateValues,
381
- const simd16uint16 candidateIndices,
382
- const simd16uint16 currentValues,
383
- const simd16uint16 currentIndices,
384
- simd16uint16& minValues,
385
- simd16uint16& minIndices,
386
- simd16uint16& maxValues,
387
- simd16uint16& maxIndices) {
397
+ const simd16uint16_tpl<SIMDLevel::NONE> candidateValues,
398
+ const simd16uint16_tpl<SIMDLevel::NONE> candidateIndices,
399
+ const simd16uint16_tpl<SIMDLevel::NONE> currentValues,
400
+ const simd16uint16_tpl<SIMDLevel::NONE> currentIndices,
401
+ simd16uint16_tpl<SIMDLevel::NONE>& minValues,
402
+ simd16uint16_tpl<SIMDLevel::NONE>& minIndices,
403
+ simd16uint16_tpl<SIMDLevel::NONE>& maxValues,
404
+ simd16uint16_tpl<SIMDLevel::NONE>& maxIndices) {
388
405
  for (size_t i = 0; i < 16; i++) {
389
406
  bool flag = (candidateValues.u16[i] < currentValues.u16[i]);
390
407
  minValues.u16[i] = flag ? candidateValues.u16[i] : currentValues.u16[i];
@@ -398,14 +415,15 @@ inline void cmplt_min_max_fast(
398
415
  }
399
416
 
400
417
  // vector of 32 unsigned 8-bit integers
401
- struct simd32uint8 : simd256bit {
402
- simd32uint8() {}
418
+ template <>
419
+ struct simd32uint8_tpl<SIMDLevel::NONE> : simd256bit_tpl<SIMDLevel::NONE> {
420
+ simd32uint8_tpl() {}
403
421
 
404
- explicit simd32uint8(int x) {
422
+ explicit simd32uint8_tpl(int x) {
405
423
  set1(x);
406
424
  }
407
425
 
408
- explicit simd32uint8(uint8_t x) {
426
+ explicit simd32uint8_tpl(uint8_t x) {
409
427
  set1(x);
410
428
  }
411
429
  template <
@@ -441,8 +459,8 @@ struct simd32uint8 : simd256bit {
441
459
  uint8_t _29,
442
460
  uint8_t _30,
443
461
  uint8_t _31>
444
- static simd32uint8 create() {
445
- simd32uint8 ret;
462
+ static simd32uint8_tpl create() {
463
+ simd32uint8_tpl ret;
446
464
  ret.u8[0] = _0;
447
465
  ret.u8[1] = _1;
448
466
  ret.u8[2] = _2;
@@ -478,9 +496,11 @@ struct simd32uint8 : simd256bit {
478
496
  return ret;
479
497
  }
480
498
 
481
- explicit simd32uint8(const simd256bit& x) : simd256bit(x) {}
499
+ explicit simd32uint8_tpl(const simd256bit_tpl<SIMDLevel::NONE>& x)
500
+ : simd256bit_tpl<SIMDLevel::NONE>(x) {}
482
501
 
483
- explicit simd32uint8(const uint8_t* x) : simd256bit((const void*)x) {}
502
+ explicit simd32uint8_tpl(const uint8_t* x)
503
+ : simd256bit_tpl<SIMDLevel::NONE>((const void*)x) {}
484
504
 
485
505
  std::string elements_to_string(const char* fmt) const {
486
506
  char res[1000], *ptr = res;
@@ -507,31 +527,33 @@ struct simd32uint8 : simd256bit {
507
527
  }
508
528
 
509
529
  template <typename F>
510
- static simd32uint8 binary_func(
511
- const simd32uint8& a,
512
- const simd32uint8& b,
530
+ static simd32uint8_tpl binary_func(
531
+ const simd32uint8_tpl& a,
532
+ const simd32uint8_tpl& b,
513
533
  F&& f) {
514
- simd32uint8 c;
534
+ simd32uint8_tpl c;
515
535
  for (int j = 0; j < 32; j++) {
516
536
  c.u8[j] = f(a.u8[j], b.u8[j]);
517
537
  }
518
538
  return c;
519
539
  }
520
540
 
521
- simd32uint8 operator&(const simd256bit& other) const {
522
- return binary_func(*this, simd32uint8(other), [](uint8_t a, uint8_t b) {
523
- return a & b;
524
- });
541
+ simd32uint8_tpl operator&(
542
+ const simd256bit_tpl<SIMDLevel::NONE>& other) const {
543
+ return binary_func(
544
+ *this, simd32uint8_tpl(other), [](uint8_t a, uint8_t b) {
545
+ return a & b;
546
+ });
525
547
  }
526
548
 
527
- simd32uint8 operator+(const simd32uint8& other) const {
549
+ simd32uint8_tpl operator+(const simd32uint8_tpl& other) const {
528
550
  return binary_func(
529
551
  *this, other, [](uint8_t a, uint8_t b) { return a + b; });
530
552
  }
531
553
 
532
554
  // The very important operation that everything relies on
533
- simd32uint8 lookup_2_lanes(const simd32uint8& idx) const {
534
- simd32uint8 c;
555
+ simd32uint8_tpl lookup_2_lanes(const simd32uint8_tpl& idx) const {
556
+ simd32uint8_tpl c;
535
557
  // The original for loop:
536
558
  // for (int j = 0; j < 32; j++) {
537
559
  // if (idx.u8[j] & 0x80) {
@@ -589,7 +611,7 @@ struct simd32uint8 : simd256bit {
589
611
  // extract + 0-extend lane
590
612
  // this operation is slow (3 cycles)
591
613
 
592
- simd32uint8 operator+=(const simd32uint8& other) {
614
+ simd32uint8_tpl& operator+=(const simd32uint8_tpl& other) {
593
615
  *this = *this + other;
594
616
  return *this;
595
617
  }
@@ -602,10 +624,10 @@ struct simd32uint8 : simd256bit {
602
624
 
603
625
  // convert with saturation
604
626
  // careful: this does not cross lanes, so the order is weird
605
- inline simd32uint8 uint16_to_uint8_saturate(
606
- const simd16uint16& a,
607
- const simd16uint16& b) {
608
- simd32uint8 c;
627
+ inline simd32uint8_tpl<SIMDLevel::NONE> uint16_to_uint8_saturate(
628
+ const simd16uint16_tpl<SIMDLevel::NONE>& a,
629
+ const simd16uint16_tpl<SIMDLevel::NONE>& b) {
630
+ simd32uint8_tpl<SIMDLevel::NONE> c;
609
631
 
610
632
  auto saturate_16_to_8 = [](uint16_t x) { return x >= 256 ? 0xff : x; };
611
633
 
@@ -619,7 +641,7 @@ inline simd32uint8 uint16_to_uint8_saturate(
619
641
  }
620
642
 
621
643
  /// get most significant bit of each byte
622
- inline uint32_t get_MSBs(const simd32uint8& a) {
644
+ inline uint32_t get_MSBs(const simd32uint8_tpl<SIMDLevel::NONE>& a) {
623
645
  uint32_t res = 0;
624
646
  for (int i = 0; i < 32; i++) {
625
647
  if (a.u8[i] & 0x80) {
@@ -630,11 +652,11 @@ inline uint32_t get_MSBs(const simd32uint8& a) {
630
652
  }
631
653
 
632
654
  /// use MSB of each byte of mask to select a byte between a and b
633
- inline simd32uint8 blendv(
634
- const simd32uint8& a,
635
- const simd32uint8& b,
636
- const simd32uint8& mask) {
637
- simd32uint8 c;
655
+ inline simd32uint8_tpl<SIMDLevel::NONE> blendv(
656
+ const simd32uint8_tpl<SIMDLevel::NONE>& a,
657
+ const simd32uint8_tpl<SIMDLevel::NONE>& b,
658
+ const simd32uint8_tpl<SIMDLevel::NONE>& mask) {
659
+ simd32uint8_tpl<SIMDLevel::NONE> c;
638
660
  for (int i = 0; i < 32; i++) {
639
661
  if (mask.u8[i] & 0x80) {
640
662
  c.u8[i] = b.u8[i];
@@ -646,18 +668,21 @@ inline simd32uint8 blendv(
646
668
  }
647
669
 
648
670
  /// vector of 8 unsigned 32-bit integers
649
- struct simd8uint32 : simd256bit {
650
- simd8uint32() {}
671
+ template <>
672
+ struct simd8uint32_tpl<SIMDLevel::NONE> : simd256bit_tpl<SIMDLevel::NONE> {
673
+ simd8uint32_tpl() {}
651
674
 
652
- explicit simd8uint32(uint32_t x) {
675
+ explicit simd8uint32_tpl(uint32_t x) {
653
676
  set1(x);
654
677
  }
655
678
 
656
- explicit simd8uint32(const simd256bit& x) : simd256bit(x) {}
679
+ explicit simd8uint32_tpl(const simd256bit_tpl<SIMDLevel::NONE>& x)
680
+ : simd256bit_tpl<SIMDLevel::NONE>(x) {}
657
681
 
658
- explicit simd8uint32(const uint32_t* x) : simd256bit((const void*)x) {}
682
+ explicit simd8uint32_tpl(const uint32_t* x)
683
+ : simd256bit_tpl<SIMDLevel::NONE>((const void*)x) {}
659
684
 
660
- explicit simd8uint32(
685
+ explicit simd8uint32_tpl(
661
686
  uint32_t u0,
662
687
  uint32_t u1,
663
688
  uint32_t u2,
@@ -676,30 +701,30 @@ struct simd8uint32 : simd256bit {
676
701
  u32[7] = u7;
677
702
  }
678
703
 
679
- simd8uint32 operator+(simd8uint32 other) const {
680
- simd8uint32 result;
704
+ simd8uint32_tpl operator+(simd8uint32_tpl other) const {
705
+ simd8uint32_tpl result;
681
706
  for (int i = 0; i < 8; i++) {
682
707
  result.u32[i] = u32[i] + other.u32[i];
683
708
  }
684
709
  return result;
685
710
  }
686
711
 
687
- simd8uint32 operator-(simd8uint32 other) const {
688
- simd8uint32 result;
712
+ simd8uint32_tpl operator-(simd8uint32_tpl other) const {
713
+ simd8uint32_tpl result;
689
714
  for (int i = 0; i < 8; i++) {
690
715
  result.u32[i] = u32[i] - other.u32[i];
691
716
  }
692
717
  return result;
693
718
  }
694
719
 
695
- simd8uint32& operator+=(const simd8uint32& other) {
720
+ simd8uint32_tpl& operator+=(const simd8uint32_tpl& other) {
696
721
  for (int i = 0; i < 8; i++) {
697
722
  u32[i] += other.u32[i];
698
723
  }
699
724
  return *this;
700
725
  }
701
726
 
702
- bool operator==(simd8uint32 other) const {
727
+ bool operator==(simd8uint32_tpl other) const {
703
728
  for (size_t i = 0; i < 8; i++) {
704
729
  if (u32[i] != other.u32[i]) {
705
730
  return false;
@@ -709,7 +734,7 @@ struct simd8uint32 : simd256bit {
709
734
  return true;
710
735
  }
711
736
 
712
- bool operator!=(simd8uint32 other) const {
737
+ bool operator!=(simd8uint32_tpl other) const {
713
738
  return !(*this == other);
714
739
  }
715
740
 
@@ -737,10 +762,10 @@ struct simd8uint32 : simd256bit {
737
762
  }
738
763
  }
739
764
 
740
- simd8uint32 unzip() const {
765
+ simd8uint32_tpl unzip() const {
741
766
  const uint32_t ret[] = {
742
767
  u32[0], u32[2], u32[4], u32[6], u32[1], u32[3], u32[5], u32[7]};
743
- return simd8uint32{ret};
768
+ return simd8uint32_tpl{ret};
744
769
  }
745
770
  };
746
771
 
@@ -756,14 +781,14 @@ struct simd8uint32 : simd256bit {
756
781
  // the last equal value is saved instead of the first one), but this behavior
757
782
  // saves instructions.
758
783
  inline void cmplt_min_max_fast(
759
- const simd8uint32 candidateValues,
760
- const simd8uint32 candidateIndices,
761
- const simd8uint32 currentValues,
762
- const simd8uint32 currentIndices,
763
- simd8uint32& minValues,
764
- simd8uint32& minIndices,
765
- simd8uint32& maxValues,
766
- simd8uint32& maxIndices) {
784
+ const simd8uint32_tpl<SIMDLevel::NONE> candidateValues,
785
+ const simd8uint32_tpl<SIMDLevel::NONE> candidateIndices,
786
+ const simd8uint32_tpl<SIMDLevel::NONE> currentValues,
787
+ const simd8uint32_tpl<SIMDLevel::NONE> currentIndices,
788
+ simd8uint32_tpl<SIMDLevel::NONE>& minValues,
789
+ simd8uint32_tpl<SIMDLevel::NONE>& minIndices,
790
+ simd8uint32_tpl<SIMDLevel::NONE>& maxValues,
791
+ simd8uint32_tpl<SIMDLevel::NONE>& maxIndices) {
767
792
  for (size_t i = 0; i < 8; i++) {
768
793
  bool flag = (candidateValues.u32[i] < currentValues.u32[i]);
769
794
  minValues.u32[i] = flag ? candidateValues.u32[i] : currentValues.u32[i];
@@ -776,16 +801,18 @@ inline void cmplt_min_max_fast(
776
801
  }
777
802
  }
778
803
 
779
- struct simd8float32 : simd256bit {
780
- simd8float32() {}
804
+ template <>
805
+ struct simd8float32_tpl<SIMDLevel::NONE> : simd256bit_tpl<SIMDLevel::NONE> {
806
+ simd8float32_tpl() {}
781
807
 
782
- explicit simd8float32(const simd256bit& x) : simd256bit(x) {}
808
+ explicit simd8float32_tpl(const simd256bit_tpl<SIMDLevel::NONE>& x)
809
+ : simd256bit_tpl<SIMDLevel::NONE>(x) {}
783
810
 
784
- explicit simd8float32(float x) {
811
+ explicit simd8float32_tpl(float x) {
785
812
  set1(x);
786
813
  }
787
814
 
788
- explicit simd8float32(const float* x) {
815
+ explicit simd8float32_tpl(const float* x) {
789
816
  loadu((void*)x);
790
817
  }
791
818
 
@@ -795,7 +822,7 @@ struct simd8float32 : simd256bit {
795
822
  }
796
823
  }
797
824
 
798
- explicit simd8float32(
825
+ explicit simd8float32_tpl(
799
826
  float f0,
800
827
  float f1,
801
828
  float f2,
@@ -815,33 +842,33 @@ struct simd8float32 : simd256bit {
815
842
  }
816
843
 
817
844
  template <typename F>
818
- static simd8float32 binary_func(
819
- const simd8float32& a,
820
- const simd8float32& b,
845
+ static simd8float32_tpl binary_func(
846
+ const simd8float32_tpl& a,
847
+ const simd8float32_tpl& b,
821
848
  F&& f) {
822
- simd8float32 c;
849
+ simd8float32_tpl c;
823
850
  for (int j = 0; j < 8; j++) {
824
851
  c.f32[j] = f(a.f32[j], b.f32[j]);
825
852
  }
826
853
  return c;
827
854
  }
828
855
 
829
- simd8float32 operator*(const simd8float32& other) const {
856
+ simd8float32_tpl operator*(const simd8float32_tpl& other) const {
830
857
  return binary_func(
831
858
  *this, other, [](float a, float b) { return a * b; });
832
859
  }
833
860
 
834
- simd8float32 operator+(const simd8float32& other) const {
861
+ simd8float32_tpl operator+(const simd8float32_tpl& other) const {
835
862
  return binary_func(
836
863
  *this, other, [](float a, float b) { return a + b; });
837
864
  }
838
865
 
839
- simd8float32 operator-(const simd8float32& other) const {
866
+ simd8float32_tpl operator-(const simd8float32_tpl& other) const {
840
867
  return binary_func(
841
868
  *this, other, [](float a, float b) { return a - b; });
842
869
  }
843
870
 
844
- simd8float32& operator+=(const simd8float32& other) {
871
+ simd8float32_tpl& operator+=(const simd8float32_tpl& other) {
845
872
  for (size_t i = 0; i < 8; i++) {
846
873
  f32[i] += other.f32[i];
847
874
  }
@@ -849,7 +876,7 @@ struct simd8float32 : simd256bit {
849
876
  return *this;
850
877
  }
851
878
 
852
- bool operator==(simd8float32 other) const {
879
+ bool operator==(simd8float32_tpl other) const {
853
880
  for (size_t i = 0; i < 8; i++) {
854
881
  if (f32[i] != other.f32[i]) {
855
882
  return false;
@@ -859,7 +886,7 @@ struct simd8float32 : simd256bit {
859
886
  return true;
860
887
  }
861
888
 
862
- bool operator!=(simd8float32 other) const {
889
+ bool operator!=(simd8float32_tpl other) const {
863
890
  return !(*this == other);
864
891
  }
865
892
 
@@ -875,8 +902,10 @@ struct simd8float32 : simd256bit {
875
902
  };
876
903
 
877
904
  // hadd does not cross lanes
878
- inline simd8float32 hadd(const simd8float32& a, const simd8float32& b) {
879
- simd8float32 c;
905
+ inline simd8float32_tpl<SIMDLevel::NONE> hadd(
906
+ const simd8float32_tpl<SIMDLevel::NONE>& a,
907
+ const simd8float32_tpl<SIMDLevel::NONE>& b) {
908
+ simd8float32_tpl<SIMDLevel::NONE> c;
880
909
  c.f32[0] = a.f32[0] + a.f32[1];
881
910
  c.f32[1] = a.f32[2] + a.f32[3];
882
911
  c.f32[2] = b.f32[0] + b.f32[1];
@@ -890,8 +919,10 @@ inline simd8float32 hadd(const simd8float32& a, const simd8float32& b) {
890
919
  return c;
891
920
  }
892
921
 
893
- inline simd8float32 unpacklo(const simd8float32& a, const simd8float32& b) {
894
- simd8float32 c;
922
+ inline simd8float32_tpl<SIMDLevel::NONE> unpacklo(
923
+ const simd8float32_tpl<SIMDLevel::NONE>& a,
924
+ const simd8float32_tpl<SIMDLevel::NONE>& b) {
925
+ simd8float32_tpl<SIMDLevel::NONE> c;
895
926
  c.f32[0] = a.f32[0];
896
927
  c.f32[1] = b.f32[0];
897
928
  c.f32[2] = a.f32[1];
@@ -905,8 +936,10 @@ inline simd8float32 unpacklo(const simd8float32& a, const simd8float32& b) {
905
936
  return c;
906
937
  }
907
938
 
908
- inline simd8float32 unpackhi(const simd8float32& a, const simd8float32& b) {
909
- simd8float32 c;
939
+ inline simd8float32_tpl<SIMDLevel::NONE> unpackhi(
940
+ const simd8float32_tpl<SIMDLevel::NONE>& a,
941
+ const simd8float32_tpl<SIMDLevel::NONE>& b) {
942
+ simd8float32_tpl<SIMDLevel::NONE> c;
910
943
  c.f32[0] = a.f32[2];
911
944
  c.f32[1] = b.f32[2];
912
945
  c.f32[2] = a.f32[3];
@@ -921,11 +954,11 @@ inline simd8float32 unpackhi(const simd8float32& a, const simd8float32& b) {
921
954
  }
922
955
 
923
956
  // compute a * b + c
924
- inline simd8float32 fmadd(
925
- const simd8float32& a,
926
- const simd8float32& b,
927
- const simd8float32& c) {
928
- simd8float32 res;
957
+ inline simd8float32_tpl<SIMDLevel::NONE> fmadd(
958
+ const simd8float32_tpl<SIMDLevel::NONE>& a,
959
+ const simd8float32_tpl<SIMDLevel::NONE>& b,
960
+ const simd8float32_tpl<SIMDLevel::NONE>& c) {
961
+ simd8float32_tpl<SIMDLevel::NONE> res;
929
962
  for (int i = 0; i < 8; i++) {
930
963
  res.f32[i] = a.f32[i] * b.f32[i] + c.f32[i];
931
964
  }
@@ -935,8 +968,10 @@ inline simd8float32 fmadd(
935
968
  namespace {
936
969
 
937
970
  // get even float32's of a and b, interleaved
938
- simd8float32 geteven(const simd8float32& a, const simd8float32& b) {
939
- simd8float32 c;
971
+ simd8float32_tpl<SIMDLevel::NONE> geteven(
972
+ const simd8float32_tpl<SIMDLevel::NONE>& a,
973
+ const simd8float32_tpl<SIMDLevel::NONE>& b) {
974
+ simd8float32_tpl<SIMDLevel::NONE> c;
940
975
 
941
976
  c.f32[0] = a.f32[0];
942
977
  c.f32[1] = a.f32[2];
@@ -952,8 +987,10 @@ simd8float32 geteven(const simd8float32& a, const simd8float32& b) {
952
987
  }
953
988
 
954
989
  // get odd float32's of a and b, interleaved
955
- simd8float32 getodd(const simd8float32& a, const simd8float32& b) {
956
- simd8float32 c;
990
+ simd8float32_tpl<SIMDLevel::NONE> getodd(
991
+ const simd8float32_tpl<SIMDLevel::NONE>& a,
992
+ const simd8float32_tpl<SIMDLevel::NONE>& b) {
993
+ simd8float32_tpl<SIMDLevel::NONE> c;
957
994
 
958
995
  c.f32[0] = a.f32[1];
959
996
  c.f32[1] = a.f32[3];
@@ -970,8 +1007,10 @@ simd8float32 getodd(const simd8float32& a, const simd8float32& b) {
970
1007
 
971
1008
  // 3 cycles
972
1009
  // if the lanes are a = [a0 a1] and b = [b0 b1], return [a0 b0]
973
- simd8float32 getlow128(const simd8float32& a, const simd8float32& b) {
974
- simd8float32 c;
1010
+ simd8float32_tpl<SIMDLevel::NONE> getlow128(
1011
+ const simd8float32_tpl<SIMDLevel::NONE>& a,
1012
+ const simd8float32_tpl<SIMDLevel::NONE>& b) {
1013
+ simd8float32_tpl<SIMDLevel::NONE> c;
975
1014
 
976
1015
  c.f32[0] = a.f32[0];
977
1016
  c.f32[1] = a.f32[1];
@@ -986,8 +1025,10 @@ simd8float32 getlow128(const simd8float32& a, const simd8float32& b) {
986
1025
  return c;
987
1026
  }
988
1027
 
989
- simd8float32 gethigh128(const simd8float32& a, const simd8float32& b) {
990
- simd8float32 c;
1028
+ simd8float32_tpl<SIMDLevel::NONE> gethigh128(
1029
+ const simd8float32_tpl<SIMDLevel::NONE>& a,
1030
+ const simd8float32_tpl<SIMDLevel::NONE>& b) {
1031
+ simd8float32_tpl<SIMDLevel::NONE> c;
991
1032
 
992
1033
  c.f32[0] = a.f32[4];
993
1034
  c.f32[1] = a.f32[5];
@@ -1034,10 +1075,10 @@ simd8float32 gethigh128(const simd8float32& a, const simd8float32& b) {
1034
1075
  // confusion for ppl who write in low-level SIMD instructions. Additionally,
1035
1076
  // these two ops (cmp and blend) are very often used together.
1036
1077
  inline void cmplt_and_blend_inplace(
1037
- const simd8float32 candidateValues,
1038
- const simd8uint32 candidateIndices,
1039
- simd8float32& lowestValues,
1040
- simd8uint32& lowestIndices) {
1078
+ const simd8float32_tpl<SIMDLevel::NONE> candidateValues,
1079
+ const simd8uint32_tpl<SIMDLevel::NONE> candidateIndices,
1080
+ simd8float32_tpl<SIMDLevel::NONE>& lowestValues,
1081
+ simd8uint32_tpl<SIMDLevel::NONE>& lowestIndices) {
1041
1082
  for (size_t j = 0; j < 8; j++) {
1042
1083
  bool comparison = (candidateValues.f32[j] < lowestValues.f32[j]);
1043
1084
  if (comparison) {
@@ -1059,14 +1100,14 @@ inline void cmplt_and_blend_inplace(
1059
1100
  // the last equal value is saved instead of the first one), but this behavior
1060
1101
  // saves instructions.
1061
1102
  inline void cmplt_min_max_fast(
1062
- const simd8float32 candidateValues,
1063
- const simd8uint32 candidateIndices,
1064
- const simd8float32 currentValues,
1065
- const simd8uint32 currentIndices,
1066
- simd8float32& minValues,
1067
- simd8uint32& minIndices,
1068
- simd8float32& maxValues,
1069
- simd8uint32& maxIndices) {
1103
+ const simd8float32_tpl<SIMDLevel::NONE> candidateValues,
1104
+ const simd8uint32_tpl<SIMDLevel::NONE> candidateIndices,
1105
+ const simd8float32_tpl<SIMDLevel::NONE> currentValues,
1106
+ const simd8uint32_tpl<SIMDLevel::NONE> currentIndices,
1107
+ simd8float32_tpl<SIMDLevel::NONE>& minValues,
1108
+ simd8uint32_tpl<SIMDLevel::NONE>& minIndices,
1109
+ simd8float32_tpl<SIMDLevel::NONE>& maxValues,
1110
+ simd8uint32_tpl<SIMDLevel::NONE>& maxIndices) {
1070
1111
  for (size_t i = 0; i < 8; i++) {
1071
1112
  bool flag = (candidateValues.f32[i] < currentValues.f32[i]);
1072
1113
  minValues.f32[i] = flag ? candidateValues.f32[i] : currentValues.f32[i];