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
@@ -11,7 +11,7 @@
11
11
  #include <vector>
12
12
 
13
13
  #include <faiss/Index.h>
14
- #include <faiss/utils/approx_topk/mode.h>
14
+ #include <faiss/impl/approx_topk/approx_topk.h>
15
15
 
16
16
  namespace faiss {
17
17
 
@@ -8,8 +8,8 @@
8
8
  #pragma once
9
9
 
10
10
  #include <faiss/impl/ScalarQuantizer.h>
11
+ #include <faiss/impl/simdlib/simdlib_dispatch.h>
11
12
  #include <faiss/utils/simd_levels.h>
12
- #include <faiss/utils/simdlib.h>
13
13
 
14
14
  namespace faiss {
15
15
 
@@ -8,8 +8,8 @@
8
8
  #pragma once
9
9
 
10
10
  #include <faiss/impl/ScalarQuantizer.h>
11
+ #include <faiss/impl/simdlib/simdlib_dispatch.h>
11
12
  #include <faiss/utils/simd_levels.h>
12
- #include <faiss/utils/simdlib.h>
13
13
 
14
14
  namespace faiss {
15
15
 
@@ -84,7 +84,8 @@ struct DistanceComputerByte<Similarity, SIMDLevel::NONE> : SQDistanceComputer {
84
84
  int d;
85
85
  std::vector<uint8_t> tmp;
86
86
 
87
- DistanceComputerByte(int d, const std::vector<float>&) : d(d), tmp(d) {}
87
+ DistanceComputerByte(int d_in, const std::vector<float>&)
88
+ : d(d_in), tmp(d_in) {}
88
89
 
89
90
  int compute_code_distance(const uint8_t* code1, const uint8_t* code2)
90
91
  const {
@@ -7,11 +7,14 @@
7
7
 
8
8
  #pragma once
9
9
 
10
+ #include <algorithm>
11
+
12
+ #include <faiss/impl/FaissAssert.h>
10
13
  #include <faiss/impl/ScalarQuantizer.h>
14
+ #include <faiss/impl/simdlib/simdlib_dispatch.h>
11
15
  #include <faiss/utils/bf16.h>
12
16
  #include <faiss/utils/fp16.h>
13
17
  #include <faiss/utils/simd_levels.h>
14
- #include <faiss/utils/simdlib.h>
15
18
 
16
19
  namespace faiss {
17
20
 
@@ -37,8 +40,8 @@ struct QuantizerTemplate<
37
40
  const size_t d;
38
41
  const float vmin, vdiff;
39
42
 
40
- QuantizerTemplate(size_t d, const std::vector<float>& trained)
41
- : d(d), vmin(trained[0]), vdiff(trained[1]) {}
43
+ QuantizerTemplate(size_t d_in, const std::vector<float>& trained)
44
+ : d(d_in), vmin(trained[0]), vdiff(trained[1]) {}
42
45
 
43
46
  void encode_vector(const float* x, uint8_t* code) const final {
44
47
  for (size_t i = 0; i < d; i++) {
@@ -79,8 +82,8 @@ struct QuantizerTemplate<
79
82
  const size_t d;
80
83
  const float *vmin, *vdiff;
81
84
 
82
- QuantizerTemplate(size_t d, const std::vector<float>& trained)
83
- : d(d), vmin(trained.data()), vdiff(trained.data() + d) {}
85
+ QuantizerTemplate(size_t d_in, const std::vector<float>& trained)
86
+ : d(d_in), vmin(trained.data()), vdiff(trained.data() + d_in) {}
84
87
 
85
88
  void encode_vector(const float* x, uint8_t* code) const final {
86
89
  for (size_t i = 0; i < d; i++) {
@@ -113,6 +116,90 @@ struct QuantizerTemplate<
113
116
  }
114
117
  };
115
118
 
119
+ /*******************************************************************
120
+ * TurboQuant MSE quantizer
121
+ *******************************************************************/
122
+ template <int NBits, SIMDLevel SL>
123
+ struct QuantizerTurboQuantMSE;
124
+
125
+ template <int NBits>
126
+ struct QuantizerTurboQuantMSE<NBits, SIMDLevel::NONE>
127
+ : ScalarQuantizer::SQuantizer {
128
+ static_assert(NBits >= 1 && NBits <= 8);
129
+
130
+ static constexpr size_t kCentroidsCount = size_t(1) << NBits;
131
+ static constexpr uint16_t kIndexMask =
132
+ static_cast<uint16_t>((1u << NBits) - 1);
133
+
134
+ const size_t d;
135
+ const float* centroids;
136
+ const float* boundaries;
137
+
138
+ QuantizerTurboQuantMSE(size_t d_in, const std::vector<float>& trained)
139
+ : d(d_in), centroids(nullptr), boundaries(nullptr) {
140
+ FAISS_THROW_IF_NOT(trained.size() == 2 * kCentroidsCount - 1);
141
+ centroids = trained.data();
142
+ boundaries = trained.data() + kCentroidsCount;
143
+ }
144
+
145
+ FAISS_ALWAYS_INLINE uint8_t select_index(float x) const {
146
+ return static_cast<uint8_t>(
147
+ std::upper_bound(
148
+ boundaries, boundaries + (kCentroidsCount - 1), x) -
149
+ boundaries);
150
+ }
151
+
152
+ FAISS_ALWAYS_INLINE void encode_index(uint8_t idx, uint8_t* code, size_t i)
153
+ const {
154
+ const size_t bit_offset = i * NBits;
155
+ const size_t byte_offset = bit_offset >> 3;
156
+ const size_t bit_shift = bit_offset & 7;
157
+ const uint16_t packed = static_cast<uint16_t>(idx & kIndexMask)
158
+ << bit_shift;
159
+ code[byte_offset] |= packed & 0xff;
160
+ if (bit_shift + NBits > 8) {
161
+ code[byte_offset + 1] |= packed >> 8;
162
+ }
163
+ }
164
+
165
+ FAISS_ALWAYS_INLINE uint8_t
166
+ decode_index(const uint8_t* code, size_t i) const {
167
+ const size_t bit_offset = i * NBits;
168
+ const size_t byte_offset = bit_offset >> 3;
169
+ const size_t bit_shift = bit_offset & 7;
170
+
171
+ uint16_t packed = code[byte_offset];
172
+ if (bit_shift + NBits > 8) {
173
+ packed |= static_cast<uint16_t>(code[byte_offset + 1]) << 8;
174
+ }
175
+ return static_cast<uint8_t>((packed >> bit_shift) & kIndexMask);
176
+ }
177
+
178
+ void encode_vector(const float* x, uint8_t* code) const final {
179
+ for (size_t i = 0; i < d; i++) {
180
+ encode_index(select_index(x[i]), code, i);
181
+ }
182
+ }
183
+
184
+ void decode_vector(const uint8_t* code, float* x) const final {
185
+ for (size_t i = 0; i < d; i++) {
186
+ x[i] = centroids[decode_index(code, i)];
187
+ }
188
+ }
189
+
190
+ FAISS_ALWAYS_INLINE float reconstruct_component(
191
+ const uint8_t* code,
192
+ size_t i) const {
193
+ return centroids[decode_index(code, i)];
194
+ }
195
+ };
196
+
197
+ template <int NBits, SIMDLevel SL>
198
+ struct QuantizerTurboQuantMSE : QuantizerTurboQuantMSE<NBits, SIMDLevel::NONE> {
199
+ using QuantizerTurboQuantMSE<NBits, SIMDLevel::NONE>::
200
+ QuantizerTurboQuantMSE;
201
+ };
202
+
116
203
  /*******************************************************************
117
204
  * FP16 quantizer
118
205
  *******************************************************************/
@@ -124,7 +211,8 @@ template <>
124
211
  struct QuantizerFP16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
125
212
  const size_t d;
126
213
 
127
- QuantizerFP16(size_t d, const std::vector<float>& /* unused */) : d(d) {}
214
+ QuantizerFP16(size_t d_in, const std::vector<float>& /* unused */)
215
+ : d(d_in) {}
128
216
 
129
217
  void encode_vector(const float* x, uint8_t* code) const final {
130
218
  for (size_t i = 0; i < d; i++) {
@@ -161,7 +249,8 @@ template <>
161
249
  struct QuantizerBF16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
162
250
  const size_t d;
163
251
 
164
- QuantizerBF16(size_t d, const std::vector<float>& /* unused */) : d(d) {}
252
+ QuantizerBF16(size_t d_in, const std::vector<float>& /* unused */)
253
+ : d(d_in) {}
165
254
 
166
255
  void encode_vector(const float* x, uint8_t* code) const final {
167
256
  for (size_t i = 0; i < d; i++) {
@@ -198,8 +287,8 @@ template <>
198
287
  struct Quantizer8bitDirect<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
199
288
  const size_t d;
200
289
 
201
- Quantizer8bitDirect(size_t d, const std::vector<float>& /* unused */)
202
- : d(d) {}
290
+ Quantizer8bitDirect(size_t d_in, const std::vector<float>& /* unused */)
291
+ : d(d_in) {}
203
292
 
204
293
  void encode_vector(const float* x, uint8_t* code) const final {
205
294
  for (size_t i = 0; i < d; i++) {
@@ -237,8 +326,10 @@ struct Quantizer8bitDirectSigned<SIMDLevel::NONE>
237
326
  : ScalarQuantizer::SQuantizer {
238
327
  const size_t d;
239
328
 
240
- Quantizer8bitDirectSigned(size_t d, const std::vector<float>& /* unused */)
241
- : d(d) {}
329
+ Quantizer8bitDirectSigned(
330
+ size_t d_in,
331
+ const std::vector<float>& /* unused */)
332
+ : d(d_in) {}
242
333
 
243
334
  void encode_vector(const float* x, uint8_t* code) const final {
244
335
  for (size_t i = 0; i < d; i++) {
@@ -11,8 +11,8 @@
11
11
  #pragma once
12
12
 
13
13
  #include <faiss/impl/ScalarQuantizer.h>
14
+ #include <faiss/impl/simdlib/simdlib_dispatch.h>
14
15
  #include <faiss/utils/simd_levels.h>
15
- #include <faiss/utils/simdlib.h>
16
16
 
17
17
  #include <faiss/impl/simd_dispatch.h>
18
18
 
@@ -159,6 +159,32 @@ InvertedListScanner* sq_select_InvertedListScanner(
159
159
  const IDSelector* sel,
160
160
  bool by_residual);
161
161
 
162
+ /// Scanner for QT_0bit / centroid-only distance: always returns the
163
+ /// coarse distance that was set via set_list().
164
+ struct IVFCoarseDistanceScanner : InvertedListScanner {
165
+ float coarse_dis = 0;
166
+
167
+ IVFCoarseDistanceScanner(
168
+ bool is_similarity,
169
+ bool store_pairs,
170
+ const IDSelector* sel)
171
+ : InvertedListScanner(store_pairs, sel) {
172
+ code_size = 0;
173
+ keep_max = is_similarity;
174
+ }
175
+
176
+ void set_query(const float* /*query_vector*/) override {}
177
+
178
+ void set_list(idx_t list_no_in, float coarse_dis_in) override {
179
+ this->list_no = list_no_in;
180
+ this->coarse_dis = coarse_dis_in;
181
+ }
182
+
183
+ float distance_to_code(const uint8_t* /*code*/) const override {
184
+ return coarse_dis;
185
+ }
186
+ };
187
+
162
188
  } // namespace scalar_quantizer
163
189
 
164
190
  } // namespace faiss
@@ -8,8 +8,8 @@
8
8
  #pragma once
9
9
 
10
10
  #include <faiss/impl/ScalarQuantizer.h>
11
+ #include <faiss/impl/simdlib/simdlib_dispatch.h>
11
12
  #include <faiss/utils/simd_levels.h>
12
- #include <faiss/utils/simdlib.h>
13
13
 
14
14
  namespace faiss {
15
15
 
@@ -32,7 +32,7 @@ struct SimilarityL2<SIMDLevel::NONE> {
32
32
 
33
33
  const float *y, *yi;
34
34
 
35
- explicit SimilarityL2(const float* y) : y(y), yi(nullptr), accu(0) {}
35
+ explicit SimilarityL2(const float* y_in) : y(y_in), yi(nullptr), accu(0) {}
36
36
 
37
37
  /******* scalar accumulator *******/
38
38
 
@@ -70,7 +70,7 @@ struct SimilarityIP<SIMDLevel::NONE> {
70
70
 
71
71
  float accu;
72
72
 
73
- explicit SimilarityIP(const float* y) : y(y), yi(nullptr), accu(0) {}
73
+ explicit SimilarityIP(const float* y_in) : y(y_in), yi(nullptr), accu(0) {}
74
74
 
75
75
  FAISS_ALWAYS_INLINE void begin() {
76
76
  accu = 0;
@@ -7,6 +7,10 @@
7
7
 
8
8
  #ifdef COMPILE_SIMD_AVX2
9
9
 
10
+ #include <faiss/impl/simdlib/simdlib_avx2.h>
11
+
12
+ #include <cstring>
13
+
10
14
  #include <faiss/impl/scalar_quantizer/codecs.h>
11
15
  #include <faiss/impl/scalar_quantizer/distance_computers.h>
12
16
  #include <faiss/impl/scalar_quantizer/quantizers.h>
@@ -17,6 +21,63 @@ namespace faiss {
17
21
 
18
22
  namespace scalar_quantizer {
19
23
 
24
+ using simd8float32 = faiss::simd8float32_tpl<SIMDLevel::AVX2>;
25
+
26
+ namespace {
27
+
28
+ FAISS_ALWAYS_INLINE uint16_t load_u16(const uint8_t* ptr) {
29
+ uint16_t value;
30
+ std::memcpy(&value, ptr, sizeof(value));
31
+ return value;
32
+ }
33
+
34
+ FAISS_ALWAYS_INLINE uint32_t load_u32(const uint8_t* ptr) {
35
+ uint32_t value;
36
+ std::memcpy(&value, ptr, sizeof(value));
37
+ return value;
38
+ }
39
+
40
+ FAISS_ALWAYS_INLINE uint32_t load_u24(const uint8_t* ptr) {
41
+ return static_cast<uint32_t>(ptr[0]) |
42
+ (static_cast<uint32_t>(ptr[1]) << 8) |
43
+ (static_cast<uint32_t>(ptr[2]) << 16);
44
+ }
45
+
46
+ FAISS_ALWAYS_INLINE __m256i unpack_8x1bit_to_u32(const uint8_t* code, int i) {
47
+ const uint32_t packed = code[static_cast<size_t>(i) >> 3];
48
+ const __m256i shifts = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
49
+ const __m256i indices =
50
+ _mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
51
+ return _mm256_and_si256(indices, _mm256_set1_epi32(0x1));
52
+ }
53
+
54
+ FAISS_ALWAYS_INLINE __m256i unpack_8x2bit_to_u32(const uint8_t* code, int i) {
55
+ const uint32_t packed = load_u16(code + (static_cast<size_t>(i) >> 2));
56
+ const __m256i shifts = _mm256_setr_epi32(0, 2, 4, 6, 8, 10, 12, 14);
57
+ const __m256i indices =
58
+ _mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
59
+ return _mm256_and_si256(indices, _mm256_set1_epi32(0x3));
60
+ }
61
+
62
+ FAISS_ALWAYS_INLINE __m256i unpack_8x3bit_to_u32(const uint8_t* code, int i) {
63
+ const uint32_t packed =
64
+ load_u24(code + ((static_cast<size_t>(i) >> 3) * 3));
65
+ const __m256i shifts = _mm256_setr_epi32(0, 3, 6, 9, 12, 15, 18, 21);
66
+ const __m256i indices =
67
+ _mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
68
+ return _mm256_and_si256(indices, _mm256_set1_epi32(0x7));
69
+ }
70
+
71
+ FAISS_ALWAYS_INLINE __m256i unpack_8x4bit_to_u32(const uint8_t* code, int i) {
72
+ const uint32_t packed = load_u32(code + (static_cast<size_t>(i) >> 1));
73
+ const __m256i shifts = _mm256_setr_epi32(0, 4, 8, 12, 16, 20, 24, 28);
74
+ const __m256i indices =
75
+ _mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
76
+ return _mm256_and_si256(indices, _mm256_set1_epi32(0xf));
77
+ }
78
+
79
+ } // namespace
80
+
20
81
  /**********************************************************
21
82
  * Codecs
22
83
  **********************************************************/
@@ -164,6 +225,56 @@ struct QuantizerTemplate<
164
225
  }
165
226
  };
166
227
 
228
+ /**********************************************************
229
+ * TurboQuant MSE quantizer
230
+ **********************************************************/
231
+
232
+ #define DEFINE_TQMSE_AVX2_SPECIALIZATION(NBITS, INDEX_EXPR) \
233
+ template <> \
234
+ struct QuantizerTurboQuantMSE<NBITS, SIMDLevel::AVX2> \
235
+ : QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE> { \
236
+ using Base = QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE>; \
237
+ \
238
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained) \
239
+ : Base(d, trained) { \
240
+ assert(d % 8 == 0); \
241
+ } \
242
+ \
243
+ FAISS_ALWAYS_INLINE simd8float32 \
244
+ reconstruct_8_components(const uint8_t* code, int i) const { \
245
+ const __m256i indices = (INDEX_EXPR); \
246
+ return simd8float32(_mm256_i32gather_ps( \
247
+ this->centroids, indices, sizeof(float))); \
248
+ } \
249
+ }
250
+
251
+ DEFINE_TQMSE_AVX2_SPECIALIZATION(1, unpack_8x1bit_to_u32(code, i));
252
+ DEFINE_TQMSE_AVX2_SPECIALIZATION(2, unpack_8x2bit_to_u32(code, i));
253
+ DEFINE_TQMSE_AVX2_SPECIALIZATION(3, unpack_8x3bit_to_u32(code, i));
254
+ DEFINE_TQMSE_AVX2_SPECIALIZATION(4, unpack_8x4bit_to_u32(code, i));
255
+
256
+ #undef DEFINE_TQMSE_AVX2_SPECIALIZATION
257
+
258
+ template <>
259
+ struct QuantizerTurboQuantMSE<8, SIMDLevel::AVX2>
260
+ : QuantizerTurboQuantMSE<8, SIMDLevel::NONE> {
261
+ using Base = QuantizerTurboQuantMSE<8, SIMDLevel::NONE>;
262
+
263
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained)
264
+ : Base(d, trained) {
265
+ assert(d % 8 == 0);
266
+ }
267
+
268
+ FAISS_ALWAYS_INLINE simd8float32
269
+ reconstruct_8_components(const uint8_t* code, int i) const {
270
+ const __m128i packed = _mm_loadl_epi64(
271
+ (const __m128i*)(code + static_cast<size_t>(i)));
272
+ const __m256i indices = _mm256_cvtepu8_epi32(packed);
273
+ return simd8float32(
274
+ _mm256_i32gather_ps(this->centroids, indices, sizeof(float)));
275
+ }
276
+ };
277
+
167
278
  /**********************************************************
168
279
  * FP16 Quantizer
169
280
  **********************************************************/
@@ -383,6 +494,43 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
383
494
  float query_to_code(const uint8_t* code) const final {
384
495
  return compute_distance(q, code);
385
496
  }
497
+
498
+ void query_to_codes_batch_4(
499
+ const uint8_t* code_0,
500
+ const uint8_t* code_1,
501
+ const uint8_t* code_2,
502
+ const uint8_t* code_3,
503
+ float& dis0,
504
+ float& dis1,
505
+ float& dis2,
506
+ float& dis3) const final {
507
+ Similarity sim0(q);
508
+ Similarity sim1(q);
509
+ Similarity sim2(q);
510
+ Similarity sim3(q);
511
+
512
+ sim0.begin_8();
513
+ sim1.begin_8();
514
+ sim2.begin_8();
515
+ sim3.begin_8();
516
+
517
+ for (size_t i = 0; i < quant.d; i += 8) {
518
+ const int ii = static_cast<int>(i);
519
+ simd8float32 xi0 = quant.reconstruct_8_components(code_0, ii);
520
+ simd8float32 xi1 = quant.reconstruct_8_components(code_1, ii);
521
+ simd8float32 xi2 = quant.reconstruct_8_components(code_2, ii);
522
+ simd8float32 xi3 = quant.reconstruct_8_components(code_3, ii);
523
+ sim0.add_8_components(xi0);
524
+ sim1.add_8_components(xi1);
525
+ sim2.add_8_components(xi2);
526
+ sim3.add_8_components(xi3);
527
+ }
528
+
529
+ dis0 = sim0.result_8();
530
+ dis1 = sim1.result_8();
531
+ dis2 = sim2.result_8();
532
+ dis3 = sim3.result_8();
533
+ }
386
534
  };
387
535
 
388
536
  template <class Similarity>
@@ -7,6 +7,10 @@
7
7
 
8
8
  #ifdef COMPILE_SIMD_AVX512
9
9
 
10
+ #include <faiss/impl/simdlib/simdlib_avx512.h>
11
+
12
+ #include <cstring>
13
+
10
14
  #include <faiss/impl/scalar_quantizer/codecs.h>
11
15
  #include <faiss/impl/scalar_quantizer/distance_computers.h>
12
16
  #include <faiss/impl/scalar_quantizer/quantizers.h>
@@ -17,6 +21,83 @@ namespace faiss {
17
21
 
18
22
  namespace scalar_quantizer {
19
23
 
24
+ using simd16float32 = faiss::simd16float32_tpl<SIMDLevel::AVX512>;
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 uint64_t load_u64(const uint8_t* ptr) {
41
+ uint64_t value;
42
+ std::memcpy(&value, ptr, sizeof(value));
43
+ return value;
44
+ }
45
+
46
+ FAISS_ALWAYS_INLINE uint32_t load_u24(const uint8_t* ptr) {
47
+ return static_cast<uint32_t>(ptr[0]) |
48
+ (static_cast<uint32_t>(ptr[1]) << 8) |
49
+ (static_cast<uint32_t>(ptr[2]) << 16);
50
+ }
51
+
52
+ FAISS_ALWAYS_INLINE __m256i unpack_8x3bit_to_u32(uint32_t packed) {
53
+ const __m256i shifts = _mm256_setr_epi32(0, 3, 6, 9, 12, 15, 18, 21);
54
+ const __m256i indices =
55
+ _mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
56
+ return _mm256_and_si256(indices, _mm256_set1_epi32(0x7));
57
+ }
58
+
59
+ FAISS_ALWAYS_INLINE __m512i unpack_16x1bit_to_u32(const uint8_t* code, int i) {
60
+ const uint32_t packed = load_u16(code + (static_cast<size_t>(i) >> 3));
61
+ const __m512i shifts = _mm512_setr_epi32(
62
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
63
+ const __m512i indices =
64
+ _mm512_srlv_epi32(_mm512_set1_epi32(packed), shifts);
65
+ return _mm512_and_si512(indices, _mm512_set1_epi32(0x1));
66
+ }
67
+
68
+ FAISS_ALWAYS_INLINE __m512i unpack_16x2bit_to_u32(const uint8_t* code, int i) {
69
+ const uint32_t packed = load_u32(code + (static_cast<size_t>(i) >> 2));
70
+ const __m512i shifts = _mm512_setr_epi32(
71
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30);
72
+ const __m512i indices =
73
+ _mm512_srlv_epi32(_mm512_set1_epi32(packed), shifts);
74
+ return _mm512_and_si512(indices, _mm512_set1_epi32(0x3));
75
+ }
76
+
77
+ FAISS_ALWAYS_INLINE __m512i unpack_16x3bit_to_u32(const uint8_t* code, int i) {
78
+ const size_t byte_offset = (static_cast<size_t>(i) >> 4) * 6;
79
+ const __m256i low = unpack_8x3bit_to_u32(load_u24(code + byte_offset));
80
+ const __m256i high = unpack_8x3bit_to_u32(load_u24(code + byte_offset + 3));
81
+ __m512i indices = _mm512_castsi256_si512(low);
82
+ return _mm512_inserti32x8(indices, high, 1);
83
+ }
84
+
85
+ FAISS_ALWAYS_INLINE __m512i unpack_16x4bit_to_u32(const uint8_t* code, int i) {
86
+ const uint64_t packed = load_u64(code + (static_cast<size_t>(i) >> 1));
87
+ const __m256i shifts = _mm256_setr_epi32(0, 4, 8, 12, 16, 20, 24, 28);
88
+ const __m256i low = _mm256_and_si256(
89
+ _mm256_srlv_epi32(_mm256_set1_epi32((uint32_t)packed), shifts),
90
+ _mm256_set1_epi32(0xf));
91
+ const __m256i high = _mm256_and_si256(
92
+ _mm256_srlv_epi32(
93
+ _mm256_set1_epi32((uint32_t)(packed >> 32)), shifts),
94
+ _mm256_set1_epi32(0xf));
95
+ __m512i indices = _mm512_castsi256_si512(low);
96
+ return _mm512_inserti32x8(indices, high, 1);
97
+ }
98
+
99
+ } // namespace
100
+
20
101
  /**********************************************************
21
102
  * Codecs
22
103
  **********************************************************/
@@ -162,6 +243,56 @@ struct QuantizerTemplate<
162
243
  }
163
244
  };
164
245
 
246
+ /**********************************************************
247
+ * TurboQuant MSE quantizer
248
+ **********************************************************/
249
+
250
+ #define DEFINE_TQMSE_AVX512_SPECIALIZATION(NBITS, INDEX_EXPR) \
251
+ template <> \
252
+ struct QuantizerTurboQuantMSE<NBITS, SIMDLevel::AVX512> \
253
+ : QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE> { \
254
+ using Base = QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE>; \
255
+ \
256
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained) \
257
+ : Base(d, trained) { \
258
+ assert(d % 16 == 0); \
259
+ } \
260
+ \
261
+ FAISS_ALWAYS_INLINE simd16float32 \
262
+ reconstruct_16_components(const uint8_t* code, int i) const { \
263
+ const __m512i indices = (INDEX_EXPR); \
264
+ return simd16float32(_mm512_i32gather_ps( \
265
+ indices, this->centroids, sizeof(float))); \
266
+ } \
267
+ }
268
+
269
+ DEFINE_TQMSE_AVX512_SPECIALIZATION(1, unpack_16x1bit_to_u32(code, i));
270
+ DEFINE_TQMSE_AVX512_SPECIALIZATION(2, unpack_16x2bit_to_u32(code, i));
271
+ DEFINE_TQMSE_AVX512_SPECIALIZATION(3, unpack_16x3bit_to_u32(code, i));
272
+ DEFINE_TQMSE_AVX512_SPECIALIZATION(4, unpack_16x4bit_to_u32(code, i));
273
+
274
+ #undef DEFINE_TQMSE_AVX512_SPECIALIZATION
275
+
276
+ template <>
277
+ struct QuantizerTurboQuantMSE<8, SIMDLevel::AVX512>
278
+ : QuantizerTurboQuantMSE<8, SIMDLevel::NONE> {
279
+ using Base = QuantizerTurboQuantMSE<8, SIMDLevel::NONE>;
280
+
281
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained)
282
+ : Base(d, trained) {
283
+ assert(d % 16 == 0);
284
+ }
285
+
286
+ FAISS_ALWAYS_INLINE simd16float32
287
+ reconstruct_16_components(const uint8_t* code, int i) const {
288
+ const __m128i packed = _mm_loadu_si128(
289
+ (const __m128i*)(code + static_cast<size_t>(i)));
290
+ const __m512i indices = _mm512_cvtepu8_epi32(packed);
291
+ return simd16float32(
292
+ _mm512_i32gather_ps(indices, this->centroids, sizeof(float)));
293
+ }
294
+ };
295
+
165
296
  /**********************************************************
166
297
  * FP16 Quantizer
167
298
  **********************************************************/
@@ -364,6 +495,42 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::AVX512>
364
495
  float query_to_code(const uint8_t* code) const final {
365
496
  return compute_distance(q, code);
366
497
  }
498
+
499
+ void query_to_codes_batch_4(
500
+ const uint8_t* code_0,
501
+ const uint8_t* code_1,
502
+ const uint8_t* code_2,
503
+ const uint8_t* code_3,
504
+ float& dis0,
505
+ float& dis1,
506
+ float& dis2,
507
+ float& dis3) const final {
508
+ Similarity sim0(q);
509
+ Similarity sim1(q);
510
+ Similarity sim2(q);
511
+ Similarity sim3(q);
512
+
513
+ sim0.begin_16();
514
+ sim1.begin_16();
515
+ sim2.begin_16();
516
+ sim3.begin_16();
517
+
518
+ for (size_t i = 0; i < quant.d; i += 16) {
519
+ simd16float32 xi0 = quant.reconstruct_16_components(code_0, i);
520
+ simd16float32 xi1 = quant.reconstruct_16_components(code_1, i);
521
+ simd16float32 xi2 = quant.reconstruct_16_components(code_2, i);
522
+ simd16float32 xi3 = quant.reconstruct_16_components(code_3, i);
523
+ sim0.add_16_components(xi0);
524
+ sim1.add_16_components(xi1);
525
+ sim2.add_16_components(xi2);
526
+ sim3.add_16_components(xi3);
527
+ }
528
+
529
+ dis0 = sim0.result_16();
530
+ dis1 = sim1.result_16();
531
+ dis2 = sim2.result_16();
532
+ dis3 = sim3.result_16();
533
+ }
367
534
  };
368
535
 
369
536
  template <class Similarity>