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
@@ -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
 
@@ -77,6 +77,12 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::NONE> : SQDistanceComputer {
77
77
  template <class Similarity, SIMDLevel SL>
78
78
  struct DistanceComputerByte : SQDistanceComputer {};
79
79
 
80
+ // Byte-domain distance computer for QT_8bit_direct_signed (storage is
81
+ // value+128). Only specialized for AVX512_SPR; other levels fall back to
82
+ // the float-domain DCTemplate path via the dispatch logic.
83
+ template <class Similarity, SIMDLevel SL>
84
+ struct DistanceComputerByteSigned : SQDistanceComputer {};
85
+
80
86
  template <class Similarity>
81
87
  struct DistanceComputerByte<Similarity, SIMDLevel::NONE> : SQDistanceComputer {
82
88
  using Sim = Similarity;
@@ -84,7 +90,8 @@ struct DistanceComputerByte<Similarity, SIMDLevel::NONE> : SQDistanceComputer {
84
90
  int d;
85
91
  std::vector<uint8_t> tmp;
86
92
 
87
- DistanceComputerByte(int d, const std::vector<float>&) : d(d), tmp(d) {}
93
+ DistanceComputerByte(int d_in, const std::vector<float>&)
94
+ : d(d_in), tmp(d_in) {}
88
95
 
89
96
  int compute_code_distance(const uint8_t* code1, const uint8_t* code2)
90
97
  const {
@@ -7,11 +7,44 @@
7
7
 
8
8
  #pragma once
9
9
 
10
+ #include <cmath>
11
+
12
+ // Hack for MSVC
13
+ #ifndef M_PI
14
+ #define M_PI 3.14159265358979323846
15
+ #endif
16
+
17
+ #include <algorithm>
18
+ #include <cstring>
19
+
20
+ #include <faiss/impl/FaissAssert.h>
21
+ #include <faiss/impl/RaBitQUtils.h>
10
22
  #include <faiss/impl/ScalarQuantizer.h>
23
+ #include <faiss/impl/platform_macros.h>
24
+ #include <faiss/impl/simdlib/simdlib_dispatch.h>
11
25
  #include <faiss/utils/bf16.h>
26
+ #include <faiss/utils/distances.h>
12
27
  #include <faiss/utils/fp16.h>
28
+ #include <faiss/utils/random.h>
13
29
  #include <faiss/utils/simd_levels.h>
14
- #include <faiss/utils/simdlib.h>
30
+ #include <faiss/utils/utils.h>
31
+
32
+ extern "C" {
33
+ int sgemm_(
34
+ const char* transa,
35
+ const char* transb,
36
+ int* m,
37
+ int* n,
38
+ int* k,
39
+ const float* alpha,
40
+ const float* a,
41
+ int* lda,
42
+ const float* b,
43
+ int* ldb,
44
+ float* beta,
45
+ float* c,
46
+ int* ldc);
47
+ }
15
48
 
16
49
  namespace faiss {
17
50
 
@@ -37,8 +70,8 @@ struct QuantizerTemplate<
37
70
  const size_t d;
38
71
  const float vmin, vdiff;
39
72
 
40
- QuantizerTemplate(size_t d, const std::vector<float>& trained)
41
- : d(d), vmin(trained[0]), vdiff(trained[1]) {}
73
+ QuantizerTemplate(size_t d_in, const std::vector<float>& trained)
74
+ : d(d_in), vmin(trained[0]), vdiff(trained[1]) {}
42
75
 
43
76
  void encode_vector(const float* x, uint8_t* code) const final {
44
77
  for (size_t i = 0; i < d; i++) {
@@ -79,8 +112,8 @@ struct QuantizerTemplate<
79
112
  const size_t d;
80
113
  const float *vmin, *vdiff;
81
114
 
82
- QuantizerTemplate(size_t d, const std::vector<float>& trained)
83
- : d(d), vmin(trained.data()), vdiff(trained.data() + d) {}
115
+ QuantizerTemplate(size_t d_in, const std::vector<float>& trained)
116
+ : d(d_in), vmin(trained.data()), vdiff(trained.data() + d_in) {}
84
117
 
85
118
  void encode_vector(const float* x, uint8_t* code) const final {
86
119
  for (size_t i = 0; i < d; i++) {
@@ -113,6 +146,86 @@ struct QuantizerTemplate<
113
146
  }
114
147
  };
115
148
 
149
+ /*******************************************************************
150
+ * TurboQuant MSE quantizer
151
+ *******************************************************************/
152
+ template <int NBits, SIMDLevel SL>
153
+ struct QuantizerTurboQuantMSE;
154
+
155
+ template <int NBits>
156
+ struct QuantizerTurboQuantMSE<NBits, SIMDLevel::NONE>
157
+ : ScalarQuantizer::SQuantizer {
158
+ static_assert(NBits >= 1 && NBits <= 8);
159
+
160
+ static constexpr size_t kCentroidsCount = size_t(1) << NBits;
161
+ static constexpr uint16_t kIndexMask =
162
+ static_cast<uint16_t>((1u << NBits) - 1);
163
+
164
+ const size_t d;
165
+ const float* centroids;
166
+ const float* boundaries;
167
+
168
+ QuantizerTurboQuantMSE(size_t d_in, const std::vector<float>& trained)
169
+ : d(d_in), centroids(nullptr), boundaries(nullptr) {
170
+ FAISS_THROW_IF_NOT(trained.size() == 2 * kCentroidsCount - 1);
171
+ centroids = trained.data();
172
+ boundaries = trained.data() + kCentroidsCount;
173
+ }
174
+
175
+ uint8_t select_index(float x) const {
176
+ return static_cast<uint8_t>(
177
+ std::upper_bound(
178
+ boundaries, boundaries + (kCentroidsCount - 1), x) -
179
+ boundaries);
180
+ }
181
+
182
+ void encode_index(uint8_t idx, uint8_t* code, size_t i) const {
183
+ const size_t bit_offset = i * NBits;
184
+ const size_t byte_offset = bit_offset >> 3;
185
+ const size_t bit_shift = bit_offset & 7;
186
+ const uint16_t packed = static_cast<uint16_t>(idx & kIndexMask)
187
+ << bit_shift;
188
+ code[byte_offset] |= packed & 0xff;
189
+ if (bit_shift + NBits > 8) {
190
+ code[byte_offset + 1] |= packed >> 8;
191
+ }
192
+ }
193
+
194
+ uint8_t decode_index(const uint8_t* code, size_t i) const {
195
+ const size_t bit_offset = i * NBits;
196
+ const size_t byte_offset = bit_offset >> 3;
197
+ const size_t bit_shift = bit_offset & 7;
198
+
199
+ uint16_t packed = code[byte_offset];
200
+ if (bit_shift + NBits > 8) {
201
+ packed |= static_cast<uint16_t>(code[byte_offset + 1]) << 8;
202
+ }
203
+ return static_cast<uint8_t>((packed >> bit_shift) & kIndexMask);
204
+ }
205
+
206
+ void encode_vector(const float* x, uint8_t* code) const override {
207
+ for (size_t i = 0; i < d; i++) {
208
+ encode_index(select_index(x[i]), code, i);
209
+ }
210
+ }
211
+
212
+ void decode_vector(const uint8_t* code, float* x) const override {
213
+ for (size_t i = 0; i < d; i++) {
214
+ x[i] = centroids[decode_index(code, i)];
215
+ }
216
+ }
217
+
218
+ float reconstruct_component(const uint8_t* code, size_t i) const {
219
+ return centroids[decode_index(code, i)];
220
+ }
221
+ };
222
+
223
+ template <int NBits, SIMDLevel SL>
224
+ struct QuantizerTurboQuantMSE : QuantizerTurboQuantMSE<NBits, SIMDLevel::NONE> {
225
+ using QuantizerTurboQuantMSE<NBits, SIMDLevel::NONE>::
226
+ QuantizerTurboQuantMSE;
227
+ };
228
+
116
229
  /*******************************************************************
117
230
  * FP16 quantizer
118
231
  *******************************************************************/
@@ -124,7 +237,8 @@ template <>
124
237
  struct QuantizerFP16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
125
238
  const size_t d;
126
239
 
127
- QuantizerFP16(size_t d, const std::vector<float>& /* unused */) : d(d) {}
240
+ QuantizerFP16(size_t d_in, const std::vector<float>& /* unused */)
241
+ : d(d_in) {}
128
242
 
129
243
  void encode_vector(const float* x, uint8_t* code) const final {
130
244
  for (size_t i = 0; i < d; i++) {
@@ -161,18 +275,15 @@ template <>
161
275
  struct QuantizerBF16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
162
276
  const size_t d;
163
277
 
164
- QuantizerBF16(size_t d, const std::vector<float>& /* unused */) : d(d) {}
278
+ QuantizerBF16(size_t d_in, const std::vector<float>& /* unused */)
279
+ : d(d_in) {}
165
280
 
166
- void encode_vector(const float* x, uint8_t* code) const final {
167
- for (size_t i = 0; i < d; i++) {
168
- ((uint16_t*)code)[i] = encode_bf16(x[i]);
169
- }
281
+ void encode_vector(const float* x, uint8_t* code) const override {
282
+ encode_bf16_simd(x, (uint16_t*)code, d);
170
283
  }
171
284
 
172
- void decode_vector(const uint8_t* code, float* x) const final {
173
- for (size_t i = 0; i < d; i++) {
174
- x[i] = decode_bf16(((uint16_t*)code)[i]);
175
- }
285
+ void decode_vector(const uint8_t* code, float* x) const override {
286
+ decode_bf16_simd((const uint16_t*)code, x, d);
176
287
  }
177
288
 
178
289
  FAISS_ALWAYS_INLINE float reconstruct_component(
@@ -187,6 +298,11 @@ struct QuantizerBF16 : QuantizerBF16<SIMDLevel::NONE> {
187
298
  using QuantizerBF16<SIMDLevel::NONE>::QuantizerBF16;
188
299
  };
189
300
 
301
+ template <>
302
+ struct QuantizerBF16<SIMDLevel::AVX512>;
303
+ template <>
304
+ struct QuantizerBF16<SIMDLevel::AVX512_SPR>;
305
+
190
306
  /*******************************************************************
191
307
  * 8bit_direct quantizer
192
308
  *******************************************************************/
@@ -198,8 +314,8 @@ template <>
198
314
  struct Quantizer8bitDirect<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
199
315
  const size_t d;
200
316
 
201
- Quantizer8bitDirect(size_t d, const std::vector<float>& /* unused */)
202
- : d(d) {}
317
+ Quantizer8bitDirect(size_t d_in, const std::vector<float>& /* unused */)
318
+ : d(d_in) {}
203
319
 
204
320
  void encode_vector(const float* x, uint8_t* code) const final {
205
321
  for (size_t i = 0; i < d; i++) {
@@ -237,8 +353,10 @@ struct Quantizer8bitDirectSigned<SIMDLevel::NONE>
237
353
  : ScalarQuantizer::SQuantizer {
238
354
  const size_t d;
239
355
 
240
- Quantizer8bitDirectSigned(size_t d, const std::vector<float>& /* unused */)
241
- : d(d) {}
356
+ Quantizer8bitDirectSigned(
357
+ size_t d_in,
358
+ const std::vector<float>& /* unused */)
359
+ : d(d_in) {}
242
360
 
243
361
  void encode_vector(const float* x, uint8_t* code) const final {
244
362
  for (size_t i = 0; i < d; i++) {
@@ -264,6 +382,288 @@ struct Quantizer8bitDirectSigned : Quantizer8bitDirectSigned<SIMDLevel::NONE> {
264
382
  using Quantizer8bitDirectSigned<SIMDLevel::NONE>::Quantizer8bitDirectSigned;
265
383
  };
266
384
 
385
+ /*******************************************************************
386
+ * Full TurboQuant (MSE + QJL) quantizer
387
+ *
388
+ * NBits = total bits per dimension (2-5).
389
+ * MSE bits = NBits - 1, QJL bits = 1.
390
+ *
391
+ * Trained vector layout:
392
+ * [centroids (k floats), boundaries (k-1 floats),
393
+ * seed_lo (float), seed_hi (float), qjl_type (float)]
394
+ * where k = 2^(NBits-1).
395
+ *******************************************************************/
396
+
397
+ FAISS_PACK_STRUCTS_BEGIN
398
+ struct SQTurboQFactors {
399
+ float norm = 0;
400
+ float gamma = 0;
401
+ };
402
+ FAISS_PACK_STRUCTS_END
403
+
404
+ template <int NBits, SIMDLevel SL>
405
+ struct QuantizerTurboQuantFull;
406
+
407
+ template <int NBits>
408
+ struct QuantizerTurboQuantFull<NBits, SIMDLevel::NONE>
409
+ : ScalarQuantizer::SQuantizer {
410
+ static_assert(NBits >= 2 && NBits <= 5);
411
+
412
+ static constexpr int kMSEBits = NBits - 1;
413
+ static constexpr size_t kCentroidsCount = size_t(1) << kMSEBits;
414
+
415
+ const size_t d;
416
+ const float* centroids;
417
+ const float* boundaries;
418
+
419
+ // QJL projection type: 0 = FWHT, 2 = Random Rotation
420
+ uint8_t qjl_type;
421
+
422
+ // FWHT state (qjl_type == 0)
423
+ size_t padded_d;
424
+ std::vector<float> fwht_signs;
425
+
426
+ // Random Rotation state (qjl_type == 2)
427
+ std::vector<float> rr_matrix; // d x d orthogonal matrix (row-major)
428
+
429
+ size_t mse_plane_bytes; // bytes for one bit-plane of d bits
430
+ size_t mse_total_bytes; // kMSEBits * mse_plane_bytes
431
+ size_t qjl_plane_bytes;
432
+
433
+ QuantizerTurboQuantFull(size_t d_in, const std::vector<float>& trained)
434
+ : d(d_in),
435
+ centroids(trained.data()),
436
+ boundaries(trained.data() + kCentroidsCount) {
437
+ // trained = [centroids(k), boundaries(k-1), seed_lo, seed_hi, qjl_type]
438
+ size_t k = kCentroidsCount;
439
+ FAISS_THROW_IF_NOT(trained.size() == 2 * k - 1 + 3);
440
+
441
+ mse_plane_bytes = (d + 7) / 8;
442
+ mse_total_bytes = kMSEBits * mse_plane_bytes;
443
+ qjl_plane_bytes = (d + 7) / 8;
444
+
445
+ // Extract seed from trained
446
+ uint64_t seed = ScalarQuantizer::TurboQuantRefine::unpack_seed(
447
+ trained[2 * k - 1], trained[2 * k]);
448
+ qjl_type = static_cast<uint8_t>(trained[2 * k + 1]);
449
+
450
+ if (qjl_type == 0) {
451
+ // FWHT mode
452
+ padded_d = 1;
453
+ while (padded_d < d) {
454
+ padded_d <<= 1;
455
+ }
456
+ fwht_signs.resize(padded_d);
457
+ RandomGenerator rng(seed);
458
+ for (size_t i = 0; i < padded_d; i++) {
459
+ fwht_signs[i] = (rng.rand_int(2) == 0) ? 1.0f : -1.0f;
460
+ }
461
+ } else {
462
+ // Random Rotation mode
463
+ padded_d = d; // no padding needed for dense multiply
464
+ rr_matrix.resize(d * d);
465
+ float_randn(rr_matrix.data(), d * d, static_cast<int64_t>(seed));
466
+ matrix_qr(
467
+ static_cast<int>(d), static_cast<int>(d), rr_matrix.data());
468
+ }
469
+ }
470
+
471
+ void fwht_inplace(float* x, size_t n) const {
472
+ for (size_t h = 1; h < n; h <<= 1) {
473
+ for (size_t i = 0; i < n; i += h << 1) {
474
+ for (size_t j = i; j < i + h; j++) {
475
+ float a = x[j];
476
+ float b = x[j + h];
477
+ x[j] = a + b;
478
+ x[j + h] = a - b;
479
+ }
480
+ }
481
+ }
482
+ }
483
+
484
+ /// Forward QJL projection: residual -> projected (d outputs)
485
+ void project_forward(const float* residual, float* out) const {
486
+ if (qjl_type == 0) {
487
+ std::vector<float> fwht_buf(padded_d);
488
+ for (size_t j = 0; j < d; j++) {
489
+ fwht_buf[j] = residual[j] * fwht_signs[j];
490
+ }
491
+ for (size_t j = d; j < padded_d; j++) {
492
+ fwht_buf[j] = 0.0f;
493
+ }
494
+ fwht_inplace(fwht_buf.data(), padded_d);
495
+ for (size_t j = 0; j < d; j++) {
496
+ out[j] = fwht_buf[j];
497
+ }
498
+ } else {
499
+ rr_forward(residual, out);
500
+ }
501
+ }
502
+
503
+ /// Inverse QJL projection: signs_buf -> reconstructed (d outputs)
504
+ void project_inverse(float* signs_buf, float* out) const {
505
+ if (qjl_type == 0) {
506
+ fwht_inplace(signs_buf, padded_d);
507
+ for (size_t j = 0; j < d; j++) {
508
+ out[j] = signs_buf[j] * fwht_signs[j];
509
+ }
510
+ } else {
511
+ rr_inverse(signs_buf, out);
512
+ }
513
+ }
514
+
515
+ void rr_forward(const float* x, float* out) const {
516
+ float alpha = 1.0f;
517
+ float beta = 0.0f;
518
+ int di = static_cast<int>(d);
519
+ int one = 1;
520
+ sgemm_("T",
521
+ "N",
522
+ &di,
523
+ &one,
524
+ &di,
525
+ &alpha,
526
+ rr_matrix.data(),
527
+ &di,
528
+ x,
529
+ &di,
530
+ &beta,
531
+ out,
532
+ &di);
533
+ }
534
+
535
+ void rr_inverse(const float* x, float* out) const {
536
+ float alpha = 1.0f;
537
+ float beta = 0.0f;
538
+ int di = static_cast<int>(d);
539
+ int one = 1;
540
+ sgemm_("N",
541
+ "N",
542
+ &di,
543
+ &one,
544
+ &di,
545
+ &alpha,
546
+ rr_matrix.data(),
547
+ &di,
548
+ x,
549
+ &di,
550
+ &beta,
551
+ out,
552
+ &di);
553
+ }
554
+
555
+ /// Store MSE index for dimension j using BIT-PLANE layout.
556
+ /// Plane p stores bit p of every dimension's index.
557
+ void store_mse_index(uint8_t idx, uint8_t* code, size_t j) const {
558
+ for (int p = 0; p < kMSEBits; p++) {
559
+ if (idx & (1 << p)) {
560
+ code[p * mse_plane_bytes + j / 8] |= (1 << (j % 8));
561
+ }
562
+ }
563
+ }
564
+
565
+ /// Load MSE index for dimension j from BIT-PLANE layout.
566
+ uint8_t load_mse_index(const uint8_t* code, size_t j) const {
567
+ uint8_t idx = 0;
568
+ for (int p = 0; p < kMSEBits; p++) {
569
+ if (code[p * mse_plane_bytes + j / 8] & (1 << (j % 8))) {
570
+ idx |= (1 << p);
571
+ }
572
+ }
573
+ return idx;
574
+ }
575
+
576
+ void encode_vector(const float* x, uint8_t* code) const final {
577
+ float sqrt_d = std::sqrt(static_cast<float>(d));
578
+ float inv_sqrt_d = 1.0f / sqrt_d;
579
+
580
+ float x_norm = std::sqrt(fvec_norm_L2sqr(x, d));
581
+ if (x_norm < 1e-30f) {
582
+ x_norm = 1e-30f;
583
+ }
584
+
585
+ // MSE quantize in scaled space + compute residual
586
+ std::vector<float> residual(padded_d);
587
+ for (size_t j = 0; j < d; j++) {
588
+ float v = x[j] / x_norm; // unit-normalized
589
+ float val = v * sqrt_d; // scaled for MSE lookup
590
+ uint8_t idx = static_cast<uint8_t>(
591
+ std::upper_bound(
592
+ boundaries,
593
+ boundaries + (kCentroidsCount - 1),
594
+ val) -
595
+ boundaries);
596
+ store_mse_index(idx, code, j);
597
+ residual[j] = v - centroids[idx] * inv_sqrt_d;
598
+ }
599
+
600
+ // QJL: project residual, take signs
601
+ std::vector<float> proj(d);
602
+ project_forward(residual.data(), proj.data());
603
+
604
+ uint8_t* qjl_code = code + mse_total_bytes;
605
+ for (size_t j = 0; j < d; j++) {
606
+ if (proj[j] > 0.0f) {
607
+ rabitq_utils::set_bit_standard(qjl_code, j);
608
+ }
609
+ }
610
+
611
+ // Store per-vector factors
612
+ float gamma = std::sqrt(fvec_norm_L2sqr(residual.data(), d));
613
+ auto* factors = reinterpret_cast<SQTurboQFactors*>(
614
+ code + mse_total_bytes + qjl_plane_bytes);
615
+ factors->norm = x_norm;
616
+ factors->gamma = gamma;
617
+ }
618
+
619
+ void decode_vector(const uint8_t* code, float* x) const final {
620
+ float inv_sqrt_d = 1.0f / std::sqrt(static_cast<float>(d));
621
+ float inv_sqrt_pd = 1.0f / std::sqrt(static_cast<float>(padded_d));
622
+
623
+ const auto* factors = reinterpret_cast<const SQTurboQFactors*>(
624
+ code + mse_total_bytes + qjl_plane_bytes);
625
+
626
+ // MSE reconstruction
627
+ for (size_t j = 0; j < d; j++) {
628
+ uint8_t idx = load_mse_index(code, j);
629
+ x[j] = centroids[idx] * inv_sqrt_d;
630
+ }
631
+
632
+ // QJL reconstruction: coeff * gamma * S^T * signs
633
+ const uint8_t* qjl_code = code + mse_total_bytes;
634
+ float coeff =
635
+ std::sqrt(M_PI / 2.0f) / static_cast<float>(d) * factors->gamma;
636
+
637
+ std::vector<float> signs_buf(padded_d);
638
+ for (size_t j = 0; j < d; j++) {
639
+ signs_buf[j] = rabitq_utils::extract_bit_standard(qjl_code, j)
640
+ ? inv_sqrt_pd
641
+ : -inv_sqrt_pd;
642
+ }
643
+ for (size_t j = d; j < padded_d; j++) {
644
+ signs_buf[j] = 0.0f;
645
+ }
646
+
647
+ std::vector<float> reconstructed(d);
648
+ project_inverse(signs_buf.data(), reconstructed.data());
649
+ for (size_t j = 0; j < d; j++) {
650
+ x[j] += coeff * reconstructed[j];
651
+ }
652
+
653
+ // Scale by norm
654
+ for (size_t j = 0; j < d; j++) {
655
+ x[j] *= factors->norm;
656
+ }
657
+ }
658
+ };
659
+
660
+ template <int NBits, SIMDLevel SL>
661
+ struct QuantizerTurboQuantFull
662
+ : QuantizerTurboQuantFull<NBits, SIMDLevel::NONE> {
663
+ using QuantizerTurboQuantFull<NBits, SIMDLevel::NONE>::
664
+ QuantizerTurboQuantFull;
665
+ };
666
+
267
667
  /*******************************************************************
268
668
  * Selection function
269
669
  *******************************************************************/
@@ -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;