faiss 0.6.0 → 0.6.2

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 (378) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -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 +88 -97
  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 +89 -417
  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 +374 -206
  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 +467 -364
  41. data/vendor/faiss/faiss/IndexIVF.h +33 -12
  42. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +79 -76
  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 +39 -69
  48. data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
  49. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +56 -33
  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 +73 -846
  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 +23 -20
  56. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +30 -52
  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 +38 -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 +150 -20
  84. data/vendor/faiss/faiss/IndexScalarQuantizer.h +10 -0
  85. data/vendor/faiss/faiss/IndexShards.cpp +10 -9
  86. data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
  87. data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
  88. data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
  89. data/vendor/faiss/faiss/MetaIndexes.h +1 -1
  90. data/vendor/faiss/faiss/MetricType.h +14 -7
  91. data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
  92. data/vendor/faiss/faiss/SuperKMeans.h +97 -0
  93. data/vendor/faiss/faiss/VectorTransform.cpp +237 -149
  94. data/vendor/faiss/faiss/VectorTransform.h +16 -16
  95. data/vendor/faiss/faiss/build.cpp +23 -0
  96. data/vendor/faiss/faiss/build.h +15 -0
  97. data/vendor/faiss/faiss/clone_index.cpp +48 -47
  98. data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +1 -1
  99. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
  100. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
  101. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +902 -12
  102. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
  103. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
  104. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +702 -10
  105. data/vendor/faiss/faiss/factory_tools.cpp +9 -0
  106. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
  107. data/vendor/faiss/faiss/gpu/GpuResources.h +3 -2
  108. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +15 -16
  109. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +5 -4
  110. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
  111. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
  112. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
  113. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
  114. data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
  115. data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
  116. data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
  117. data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
  118. data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
  119. data/vendor/faiss/faiss/gpu_metal/MetalDistance.h +87 -0
  120. data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
  121. data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +58 -0
  122. data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
  123. data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +181 -0
  124. data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +111 -0
  125. data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +45 -0
  126. data/vendor/faiss/faiss/gpu_metal/MetalResources.h +79 -0
  127. data/vendor/faiss/faiss/gpu_metal/StandardMetalResources.h +35 -0
  128. data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFFlat.h +193 -0
  129. data/vendor/faiss/faiss/impl/AdSampling.cpp +103 -0
  130. data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
  131. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +29 -25
  132. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
  133. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
  134. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -0
  135. data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
  136. data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
  137. data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +16 -16
  138. data/vendor/faiss/faiss/impl/CodePacker.cpp +3 -3
  139. data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +1 -1
  140. data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
  141. data/vendor/faiss/faiss/impl/FaissAssert.h +6 -3
  142. data/vendor/faiss/faiss/impl/FaissException.h +50 -3
  143. data/vendor/faiss/faiss/impl/HNSW.cpp +639 -507
  144. data/vendor/faiss/faiss/impl/HNSW.h +61 -44
  145. data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
  146. data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
  147. data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
  148. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +82 -77
  149. data/vendor/faiss/faiss/impl/NNDescent.cpp +62 -25
  150. data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
  151. data/vendor/faiss/faiss/impl/NSG.cpp +53 -32
  152. data/vendor/faiss/faiss/impl/NSG.h +4 -4
  153. data/vendor/faiss/faiss/impl/Panorama.cpp +23 -6
  154. data/vendor/faiss/faiss/impl/Panorama.h +269 -87
  155. data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
  156. data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
  157. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +46 -32
  158. data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
  159. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
  160. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
  161. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +55 -25
  162. data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
  163. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +55 -49
  164. data/vendor/faiss/faiss/impl/RaBitQUtils.h +65 -0
  165. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +302 -283
  166. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +26 -23
  167. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
  168. data/vendor/faiss/faiss/impl/ResultHandler.h +100 -75
  169. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +318 -7
  170. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +77 -1
  171. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
  172. data/vendor/faiss/faiss/impl/VisitedTable.cpp +10 -10
  173. data/vendor/faiss/faiss/impl/VisitedTable.h +70 -28
  174. data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
  175. data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
  176. data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
  177. data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
  178. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
  179. data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
  180. data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
  181. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
  182. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
  183. data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
  184. data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
  185. data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
  186. data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
  187. data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
  188. data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
  189. data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
  190. data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
  191. data/vendor/faiss/faiss/impl/expanded_scanners.h +8 -3
  192. data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
  193. data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
  194. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
  195. data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
  196. data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
  197. data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +270 -0
  198. data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +169 -2
  199. data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
  200. data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
  201. data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
  202. data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
  203. data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
  204. data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
  205. data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -356
  206. data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
  207. data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
  208. data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +282 -134
  209. data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
  210. data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
  211. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +83 -0
  212. data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +113 -0
  213. data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +150 -0
  214. data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +142 -0
  215. data/vendor/faiss/faiss/impl/index_read.cpp +1227 -79
  216. data/vendor/faiss/faiss/impl/index_read_utils.h +1 -1
  217. data/vendor/faiss/faiss/impl/index_write.cpp +96 -13
  218. data/vendor/faiss/faiss/impl/io.cpp +6 -6
  219. data/vendor/faiss/faiss/impl/io_macros.h +58 -16
  220. data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
  221. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +37 -23
  222. data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
  223. data/vendor/faiss/faiss/impl/mapped_io.cpp +6 -6
  224. data/vendor/faiss/faiss/impl/platform_macros.h +15 -4
  225. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
  226. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
  227. data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
  228. data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
  229. data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +23 -0
  230. data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +23 -0
  231. data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +23 -0
  232. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx2.cpp → pq_code_distance-avx2.h} +9 -13
  233. data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx512.cpp → pq_code_distance-avx512.h} +9 -57
  234. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +45 -107
  235. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
  236. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +274 -5
  237. data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +10 -7
  238. data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +105 -0
  239. data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +70 -0
  240. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +311 -477
  241. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
  242. data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +1 -1
  243. data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +9 -2
  244. data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +419 -19
  245. data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +27 -1
  246. data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +3 -3
  247. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +387 -2
  248. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +553 -0
  249. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +559 -0
  250. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +341 -2
  251. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +425 -3
  252. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +290 -2
  253. data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +337 -0
  254. data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +192 -8
  255. data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +12 -0
  256. data/vendor/faiss/faiss/impl/simd_dispatch.h +157 -66
  257. data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
  258. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +264 -172
  259. data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
  260. data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
  261. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
  262. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +270 -218
  263. data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
  264. data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
  265. data/vendor/faiss/faiss/impl/svs_io.h +8 -2
  266. data/vendor/faiss/faiss/index_factory.cpp +90 -18
  267. data/vendor/faiss/faiss/index_io.h +40 -0
  268. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +66 -16
  269. data/vendor/faiss/faiss/invlists/DirectMap.cpp +28 -15
  270. data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
  271. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +170 -86
  272. data/vendor/faiss/faiss/invlists/InvertedLists.h +88 -25
  273. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
  274. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +13 -13
  275. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  276. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +1 -1
  277. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
  278. data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
  279. data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
  280. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
  281. data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
  282. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
  283. data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
  284. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +142 -21
  285. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +33 -7
  286. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +3 -2
  287. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
  288. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +77 -27
  289. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +10 -4
  290. data/vendor/faiss/faiss/utils/Heap.cpp +10 -10
  291. data/vendor/faiss/faiss/utils/NeuralNet.cpp +47 -36
  292. data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
  293. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
  294. data/vendor/faiss/faiss/utils/bf16.h +34 -0
  295. data/vendor/faiss/faiss/utils/distances.cpp +390 -560
  296. data/vendor/faiss/faiss/utils/distances.h +20 -1
  297. data/vendor/faiss/faiss/utils/distances_dispatch.h +117 -37
  298. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
  299. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
  300. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
  301. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
  302. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
  303. data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
  304. data/vendor/faiss/faiss/utils/distances_simd.cpp +5 -178
  305. data/vendor/faiss/faiss/utils/extra_distances.cpp +9 -8
  306. data/vendor/faiss/faiss/utils/extra_distances.h +32 -6
  307. data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
  308. data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
  309. data/vendor/faiss/faiss/utils/hamming.h +92 -2
  310. data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
  311. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +16 -0
  312. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
  313. data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +15 -0
  314. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
  315. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +210 -0
  316. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_spr.h +171 -0
  317. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-generic.h +368 -0
  318. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +322 -0
  319. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-rvv.h +39 -0
  320. data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer.h +146 -0
  321. data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +481 -0
  322. data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +15 -0
  323. data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +15 -0
  324. data/vendor/faiss/faiss/utils/partitioning.cpp +66 -989
  325. data/vendor/faiss/faiss/utils/partitioning.h +31 -0
  326. data/vendor/faiss/faiss/utils/popcount.h +29 -0
  327. data/vendor/faiss/faiss/utils/pq_code_distance.h +2 -2
  328. data/vendor/faiss/faiss/utils/prefetch.h +2 -2
  329. data/vendor/faiss/faiss/utils/quantize_lut.cpp +30 -30
  330. data/vendor/faiss/faiss/utils/quantize_lut.h +1 -1
  331. data/vendor/faiss/faiss/utils/rabitq_simd.h +57 -536
  332. data/vendor/faiss/faiss/utils/random.cpp +6 -6
  333. data/vendor/faiss/faiss/utils/simd_impl/IVFFlatScanner-inl.h +51 -0
  334. data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +5 -1
  335. data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +213 -4
  336. data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +163 -10
  337. data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +250 -4
  338. data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +7 -4
  339. data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +189 -0
  340. data/vendor/faiss/faiss/utils/simd_impl/distances_simdlib256.h +195 -0
  341. data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +2 -1
  342. data/vendor/faiss/faiss/utils/{distances_fused/simdlib_based.h → simd_impl/exhaustive_L2sqr_blas_cmax.h} +5 -10
  343. data/vendor/faiss/faiss/utils/simd_impl/hamming_impl.h +481 -0
  344. data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +14 -0
  345. data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +14 -0
  346. data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +1031 -0
  347. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +355 -0
  348. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +477 -0
  349. data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512_spr.cpp +343 -0
  350. data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +55 -0
  351. data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
  352. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
  353. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
  354. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
  355. data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
  356. data/vendor/faiss/faiss/utils/simd_levels.cpp +29 -7
  357. data/vendor/faiss/faiss/utils/simd_levels.h +93 -1
  358. data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
  359. data/vendor/faiss/faiss/utils/utils.cpp +5 -5
  360. data/vendor/faiss/faiss/utils/utils.h +3 -3
  361. metadata +129 -34
  362. data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
  363. data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
  364. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -224
  365. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -230
  366. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
  367. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
  368. data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
  369. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
  370. data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -235
  371. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
  372. data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
  373. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -449
  374. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
  375. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
  376. data/vendor/faiss/faiss/utils/simdlib.h +0 -42
  377. data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -365
  378. /data/ext/faiss/{utils_rb.h → utils.h} +0 -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
  **********************************************************/
@@ -135,6 +196,12 @@ struct QuantizerTemplate<
135
196
  return simd8float32(_mm256_fmadd_ps(
136
197
  xi, _mm256_set1_ps(this->vdiff), _mm256_set1_ps(this->vmin)));
137
198
  }
199
+
200
+ /// Raw codec decode without denormalization
201
+ FAISS_ALWAYS_INLINE simd8float32
202
+ decode_8_raw(const uint8_t* code, int i) const {
203
+ return Codec::decode_8_components(code, i);
204
+ }
138
205
  };
139
206
 
140
207
  template <class Codec>
@@ -164,6 +231,171 @@ struct QuantizerTemplate<
164
231
  }
165
232
  };
166
233
 
234
+ /**********************************************************
235
+ * TurboQuant MSE quantizer
236
+ **********************************************************/
237
+
238
+ // 1-bit MSE: boundary is always at centroids midpoint.
239
+ // Encode: 8 comparisons → 1 byte via movemask.
240
+ // Decode: gather 8 centroids via index unpack.
241
+ // NOLINTNEXTLINE(facebook-hte-MisplacedTemplateSpecialization,facebook-hte-ShadowingClass)
242
+ template <>
243
+ struct QuantizerTurboQuantMSE<1, SIMDLevel::AVX2>
244
+ : QuantizerTurboQuantMSE<1, SIMDLevel::NONE> {
245
+ using Base = QuantizerTurboQuantMSE<1, SIMDLevel::NONE>;
246
+
247
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained)
248
+ : Base(d, trained) {
249
+ assert(d % 8 == 0);
250
+ }
251
+
252
+ FAISS_ALWAYS_INLINE simd8float32
253
+ reconstruct_8_components(const uint8_t* code, int i) const {
254
+ return simd8float32(_mm256_i32gather_ps(
255
+ this->centroids, unpack_8x1bit_to_u32(code, i), sizeof(float)));
256
+ }
257
+
258
+ void encode_vector(const float* x, uint8_t* code) const final {
259
+ __m256 boundary = _mm256_set1_ps(this->boundaries[0]);
260
+ for (size_t i = 0; i < this->d; i += 8) {
261
+ __m256 vals = _mm256_loadu_ps(x + i);
262
+ int mask = _mm256_movemask_ps(
263
+ _mm256_cmp_ps(vals, boundary, _CMP_GT_OQ));
264
+ code[i / 8] = static_cast<uint8_t>(mask);
265
+ }
266
+ }
267
+
268
+ void decode_vector(const uint8_t* code, float* x) const final {
269
+ for (size_t i = 0; i < this->d; i += 8) {
270
+ simd8float32 xi =
271
+ reconstruct_8_components(code, static_cast<int>(i));
272
+ _mm256_storeu_ps(x + i, xi.f);
273
+ }
274
+ }
275
+ };
276
+
277
+ // 2-bit MSE: 4 centroids, 3 boundaries.
278
+ // Encode: branchless index = sum of 3 comparisons per component.
279
+ // Decode: gather via index unpack.
280
+ // NOLINTNEXTLINE(facebook-hte-MisplacedTemplateSpecialization,facebook-hte-ShadowingClass)
281
+ template <>
282
+ struct QuantizerTurboQuantMSE<2, SIMDLevel::AVX2>
283
+ : QuantizerTurboQuantMSE<2, SIMDLevel::NONE> {
284
+ using Base = QuantizerTurboQuantMSE<2, SIMDLevel::NONE>;
285
+
286
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained)
287
+ : Base(d, trained) {
288
+ assert(d % 8 == 0);
289
+ }
290
+
291
+ FAISS_ALWAYS_INLINE simd8float32
292
+ reconstruct_8_components(const uint8_t* code, int i) const {
293
+ return simd8float32(_mm256_i32gather_ps(
294
+ this->centroids, unpack_8x2bit_to_u32(code, i), sizeof(float)));
295
+ }
296
+
297
+ void encode_vector(const float* x, uint8_t* code) const final {
298
+ // 3 boundaries → branchless: idx = (x>b0) + (x>b1) + (x>b2)
299
+ // _mm256_cmp_ps returns all-ones (-1 as int32) for true,
300
+ // so we negate the sum to get positive indices.
301
+ __m256 b0 = _mm256_set1_ps(this->boundaries[0]);
302
+ __m256 b1 = _mm256_set1_ps(this->boundaries[1]);
303
+ __m256 b2 = _mm256_set1_ps(this->boundaries[2]);
304
+ for (size_t i = 0; i < this->d; i += 8) {
305
+ __m256 vals = _mm256_loadu_ps(x + i);
306
+ __m256i gt0 =
307
+ _mm256_castps_si256(_mm256_cmp_ps(vals, b0, _CMP_GT_OQ));
308
+ __m256i gt1 =
309
+ _mm256_castps_si256(_mm256_cmp_ps(vals, b1, _CMP_GT_OQ));
310
+ __m256i gt2 =
311
+ _mm256_castps_si256(_mm256_cmp_ps(vals, b2, _CMP_GT_OQ));
312
+ // Each gt is 0 or -1 (0xFFFFFFFF). Sum = -(index).
313
+ __m256i idx = _mm256_sub_epi32(
314
+ _mm256_setzero_si256(),
315
+ _mm256_add_epi32(_mm256_add_epi32(gt0, gt1), gt2));
316
+ // Pack 8 x 2-bit indices into 2 bytes.
317
+ // Store to temp array and pack scalarly - faster than
318
+ // extract+permute.
319
+ alignas(32) int32_t idx_array[8];
320
+ _mm256_store_si256((__m256i*)idx_array, idx);
321
+ for (int j = 0; j < 8; j++) {
322
+ this->encode_index(
323
+ static_cast<uint8_t>(idx_array[j] & 0x3), code, i + j);
324
+ }
325
+ }
326
+ }
327
+
328
+ void decode_vector(const uint8_t* code, float* x) const final {
329
+ for (size_t i = 0; i < this->d; i += 8) {
330
+ simd8float32 xi =
331
+ reconstruct_8_components(code, static_cast<int>(i));
332
+ _mm256_storeu_ps(x + i, xi.f);
333
+ }
334
+ }
335
+ };
336
+
337
+ // 3-bit and 4-bit MSE: use branchless comparison chain for encode.
338
+ // k boundaries → idx = sum of k-1 comparisons.
339
+ #define DEFINE_TQMSE_AVX2_MULTIBIT(NBITS, UNPACK_EXPR) \
340
+ template <> \
341
+ struct QuantizerTurboQuantMSE<NBITS, SIMDLevel::AVX2> \
342
+ : QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE> { \
343
+ using Base = QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE>; \
344
+ \
345
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained) \
346
+ : Base(d, trained) { \
347
+ assert(d % 8 == 0); \
348
+ } \
349
+ \
350
+ FAISS_ALWAYS_INLINE simd8float32 \
351
+ reconstruct_8_components(const uint8_t* code, int i) const { \
352
+ return simd8float32(_mm256_i32gather_ps( \
353
+ this->centroids, (UNPACK_EXPR), sizeof(float))); \
354
+ } \
355
+ \
356
+ void decode_vector(const uint8_t* code, float* x) const final { \
357
+ for (size_t i = 0; i < this->d; i += 8) { \
358
+ simd8float32 xi = \
359
+ reconstruct_8_components(code, static_cast<int>(i)); \
360
+ _mm256_storeu_ps(x + i, xi.f); \
361
+ } \
362
+ } \
363
+ }
364
+
365
+ DEFINE_TQMSE_AVX2_MULTIBIT(3, unpack_8x3bit_to_u32(code, i));
366
+ DEFINE_TQMSE_AVX2_MULTIBIT(4, unpack_8x4bit_to_u32(code, i));
367
+
368
+ #undef DEFINE_TQMSE_AVX2_MULTIBIT
369
+
370
+ // 8-bit MSE: indices are raw bytes, no bit packing.
371
+ template <>
372
+ struct QuantizerTurboQuantMSE<8, SIMDLevel::AVX2>
373
+ : QuantizerTurboQuantMSE<8, SIMDLevel::NONE> {
374
+ using Base = QuantizerTurboQuantMSE<8, SIMDLevel::NONE>;
375
+
376
+ QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained)
377
+ : Base(d, trained) {
378
+ assert(d % 8 == 0);
379
+ }
380
+
381
+ FAISS_ALWAYS_INLINE simd8float32
382
+ reconstruct_8_components(const uint8_t* code, int i) const {
383
+ const __m128i packed = _mm_loadl_epi64(
384
+ (const __m128i*)(code + static_cast<size_t>(i)));
385
+ const __m256i indices = _mm256_cvtepu8_epi32(packed);
386
+ return simd8float32(
387
+ _mm256_i32gather_ps(this->centroids, indices, sizeof(float)));
388
+ }
389
+
390
+ void decode_vector(const uint8_t* code, float* x) const final {
391
+ for (size_t i = 0; i < this->d; i += 8) {
392
+ simd8float32 xi =
393
+ reconstruct_8_components(code, static_cast<int>(i));
394
+ _mm256_storeu_ps(x + i, xi.f);
395
+ }
396
+ }
397
+ };
398
+
167
399
  /**********************************************************
168
400
  * FP16 Quantizer
169
401
  **********************************************************/
@@ -288,6 +520,22 @@ struct SimilarityL2<SIMDLevel::AVX2> {
288
520
  const __m128 v3 = _mm_add_ps(v1, v2);
289
521
  return _mm_cvtss_f32(v3);
290
522
  }
523
+
524
+ static void adjust_query_for_raw_decode(
525
+ const float* x,
526
+ float* q_adj,
527
+ size_t d,
528
+ float vmin,
529
+ float vdiff,
530
+ float& scale_factor,
531
+ float& bias) {
532
+ float inv_vdiff = (vdiff != 0) ? 1.0f / vdiff : 0.0f;
533
+ for (size_t i = 0; i < d; i++) {
534
+ q_adj[i] = (x[i] - vmin) * inv_vdiff;
535
+ }
536
+ scale_factor = vdiff * vdiff;
537
+ bias = 0;
538
+ }
291
539
  };
292
540
 
293
541
  template <>
@@ -331,6 +579,23 @@ struct SimilarityIP<SIMDLevel::AVX2> {
331
579
  const __m128 v3 = _mm_add_ps(v1, v2);
332
580
  return _mm_cvtss_f32(v3);
333
581
  }
582
+
583
+ static void adjust_query_for_raw_decode(
584
+ const float* x,
585
+ float* q_adj,
586
+ size_t d,
587
+ float vmin,
588
+ float vdiff,
589
+ float& scale_factor,
590
+ float& bias) {
591
+ float sum_q = 0;
592
+ for (size_t i = 0; i < d; i++) {
593
+ q_adj[i] = x[i];
594
+ sum_q += x[i];
595
+ }
596
+ scale_factor = vdiff;
597
+ bias = vmin * sum_q;
598
+ }
334
599
  };
335
600
 
336
601
  /**********************************************************
@@ -343,8 +608,23 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
343
608
 
344
609
  Quantizer quant;
345
610
 
611
+ // Pre-adjusted query buffer for uniform quantizers
612
+ std::vector<float> q_adj;
613
+ float scale_factor = 0;
614
+ float bias = 0;
615
+
616
+ static constexpr bool has_decode_raw() {
617
+ return requires(const Quantizer& q, const uint8_t* c, int i) {
618
+ { q.decode_8_raw(c, i) };
619
+ };
620
+ }
621
+
346
622
  DCTemplate(size_t d, const std::vector<float>& trained)
347
- : quant(d, trained) {}
623
+ : quant(d, trained) {
624
+ if constexpr (has_decode_raw()) {
625
+ q_adj.resize(d);
626
+ }
627
+ }
348
628
 
349
629
  float compute_distance(const float* x, const uint8_t* code) const {
350
630
  Similarity sim(x);
@@ -373,6 +653,26 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
373
653
 
374
654
  void set_query(const float* x) final {
375
655
  q = x;
656
+ if constexpr (has_decode_raw()) {
657
+ Sim::adjust_query_for_raw_decode(
658
+ x,
659
+ q_adj.data(),
660
+ quant.d,
661
+ quant.vmin,
662
+ quant.vdiff,
663
+ scale_factor,
664
+ bias);
665
+ }
666
+ }
667
+
668
+ float query_to_code_predecoded(const uint8_t* code) const {
669
+ Similarity sim(q_adj.data());
670
+ sim.begin_8();
671
+ for (size_t i = 0; i < quant.d; i += 8) {
672
+ simd8float32 xi = quant.decode_8_raw(code, static_cast<int>(i));
673
+ sim.add_8_components(xi);
674
+ }
675
+ return bias + scale_factor * sim.result_8();
376
676
  }
377
677
 
378
678
  float symmetric_dis(idx_t i, idx_t j) override {
@@ -381,7 +681,48 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
381
681
  }
382
682
 
383
683
  float query_to_code(const uint8_t* code) const final {
384
- return compute_distance(q, code);
684
+ if constexpr (has_decode_raw()) {
685
+ return query_to_code_predecoded(code);
686
+ } else {
687
+ return compute_distance(q, code);
688
+ }
689
+ }
690
+
691
+ void query_to_codes_batch_4(
692
+ const uint8_t* code_0,
693
+ const uint8_t* code_1,
694
+ const uint8_t* code_2,
695
+ const uint8_t* code_3,
696
+ float& dis0,
697
+ float& dis1,
698
+ float& dis2,
699
+ float& dis3) const final {
700
+ Similarity sim0(q);
701
+ Similarity sim1(q);
702
+ Similarity sim2(q);
703
+ Similarity sim3(q);
704
+
705
+ sim0.begin_8();
706
+ sim1.begin_8();
707
+ sim2.begin_8();
708
+ sim3.begin_8();
709
+
710
+ for (size_t i = 0; i < quant.d; i += 8) {
711
+ const int ii = static_cast<int>(i);
712
+ simd8float32 xi0 = quant.reconstruct_8_components(code_0, ii);
713
+ simd8float32 xi1 = quant.reconstruct_8_components(code_1, ii);
714
+ simd8float32 xi2 = quant.reconstruct_8_components(code_2, ii);
715
+ simd8float32 xi3 = quant.reconstruct_8_components(code_3, ii);
716
+ sim0.add_8_components(xi0);
717
+ sim1.add_8_components(xi1);
718
+ sim2.add_8_components(xi2);
719
+ sim3.add_8_components(xi3);
720
+ }
721
+
722
+ dis0 = sim0.result_8();
723
+ dis1 = sim1.result_8();
724
+ dis2 = sim2.result_8();
725
+ dis3 = sim3.result_8();
385
726
  }
386
727
  };
387
728
 
@@ -446,6 +787,50 @@ struct DistanceComputerByte<Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
446
787
  }
447
788
  };
448
789
 
790
+ /**********************************************************
791
+ * TurboQuant masked_sum AVX2 specialization
792
+ **********************************************************/
793
+
794
+ template <SIMDLevel SL0>
795
+ float turboq_masked_sum(const float* arr, const uint8_t* bits, size_t d);
796
+
797
+ template <>
798
+ float turboq_masked_sum<SIMDLevel::AVX2>(
799
+ const float* arr,
800
+ const uint8_t* bits,
801
+ size_t d) {
802
+ const __m256i bit_masks = _mm256_set_epi32(128, 64, 32, 16, 8, 4, 2, 1);
803
+ __m256 acc = _mm256_setzero_ps();
804
+ size_t full_bytes = d / 8;
805
+ for (size_t byte_idx = 0; byte_idx < full_bytes; byte_idx++) {
806
+ __m256i byte_broadcast =
807
+ _mm256_set1_epi32(static_cast<int>(bits[byte_idx]));
808
+ __m256i masked = _mm256_and_si256(byte_broadcast, bit_masks);
809
+ __m256i cmp = _mm256_cmpeq_epi32(masked, bit_masks);
810
+ __m256 mask = _mm256_castsi256_ps(cmp);
811
+ __m256 vals = _mm256_loadu_ps(arr + byte_idx * 8);
812
+ acc = _mm256_add_ps(acc, _mm256_and_ps(mask, vals));
813
+ }
814
+ __m128 hi = _mm256_extractf128_ps(acc, 1);
815
+ __m128 lo = _mm256_castps256_ps128(acc);
816
+ __m128 sum128 = _mm_add_ps(lo, hi);
817
+ __m128 shuf = _mm_movehdup_ps(sum128);
818
+ __m128 sums = _mm_add_ps(sum128, shuf);
819
+ shuf = _mm_movehl_ps(shuf, sums);
820
+ sums = _mm_add_ss(sums, shuf);
821
+ float result = _mm_cvtss_f32(sums);
822
+ size_t tail_start = full_bytes * 8;
823
+ if (tail_start < d) {
824
+ uint8_t last_byte = bits[full_bytes];
825
+ for (size_t j = tail_start; j < d; j++) {
826
+ if (last_byte & (1 << (j - tail_start))) {
827
+ result += arr[j];
828
+ }
829
+ }
830
+ }
831
+ return result;
832
+ }
833
+
449
834
  } // namespace scalar_quantizer
450
835
  } // namespace faiss
451
836