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
@@ -0,0 +1,549 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #ifndef THE_SIMD_LEVEL
11
+ #error "THE_SIMD_LEVEL must be defined before including IVFPQScanner_impl.h"
12
+ #endif
13
+
14
+ #include <faiss/IndexIVFPQ.h>
15
+ #include <faiss/impl/IDSelector.h>
16
+ #include <faiss/impl/ResultHandler.h>
17
+ #include <faiss/impl/pq_code_distance/IVFPQ_QueryTables.h>
18
+ #include <faiss/impl/pq_code_distance/pq_code_distance-inl.h>
19
+ #include <faiss/impl/simd_dispatch.h>
20
+ #include <faiss/invlists/DirectMap.h>
21
+ #include <faiss/utils/distances_dispatch.h>
22
+ #include <faiss/utils/hamming.h>
23
+
24
+ namespace faiss {
25
+ namespace pq_code_distance {
26
+
27
+ template <class C, bool use_sel>
28
+ struct WrappedSearchResult {
29
+ ResultHandler& res;
30
+ size_t nup = 0;
31
+ idx_t list_no;
32
+
33
+ const idx_t* ids;
34
+ const IDSelector* sel;
35
+
36
+ WrappedSearchResult(
37
+ idx_t list_no_in,
38
+ const idx_t* ids_in,
39
+ const IDSelector* sel_in,
40
+ ResultHandler& res_in)
41
+ : res(res_in), list_no(list_no_in), ids(ids_in), sel(sel_in) {}
42
+
43
+ inline bool skip_entry(idx_t j) {
44
+ return use_sel && !sel->is_member(ids[j]);
45
+ }
46
+
47
+ inline void add(idx_t j, float dis) {
48
+ // Reached only for codes that passed skip_entry — i.e. distance
49
+ // was actually computed for this code (post-filter).
50
+ res.stats.scan_cnt++;
51
+ if (C::cmp(res.threshold, dis)) {
52
+ idx_t id = ids ? ids[j] : lo_build(this->list_no, j);
53
+ if (res.add_result(dis, id)) {
54
+ res.stats.nheap_updates++;
55
+ nup++;
56
+ }
57
+ }
58
+ }
59
+ };
60
+
61
+ /*****************************************************
62
+ * Scaning the codes.
63
+ * The scanning functions call their favorite precompute_*
64
+ * function to precompute the tables they need.
65
+ *****************************************************/
66
+ template <typename IDType, MetricType METRIC_TYPE, class PQCodeDist>
67
+ struct IVFPQScannerT : QueryTables {
68
+ using PQDecoder = typename PQCodeDist::PQDecoder;
69
+ const uint8_t* list_codes = nullptr;
70
+ const IDType* list_ids;
71
+ size_t list_size = 0;
72
+
73
+ IVFPQScannerT(
74
+ const IndexIVFPQ& ivfpq_in,
75
+ const IVFSearchParameters* params_in)
76
+ : QueryTables(ivfpq_in, params_in) {
77
+ FAISS_THROW_IF_NOT(METRIC_TYPE == metric_type);
78
+ }
79
+
80
+ /*****************************************************
81
+ * Scaning the codes: simple PQ scan.
82
+ *****************************************************/
83
+
84
+ // This is the baseline version of scan_list_with_tables().
85
+ // It demonstrates what this function actually does.
86
+ //
87
+ // /// version of the scan where we use precomputed tables.
88
+ // template <class SearchResultType>
89
+ // void scan_list_with_table(
90
+ // size_t ncode,
91
+ // const uint8_t* codes,
92
+ // SearchResultType& res) const {
93
+ //
94
+ // for (size_t j = 0; j < ncode; j++, codes += pq.code_size) {
95
+ // if (res.skip_entry(j)) {
96
+ // continue;
97
+ // }
98
+ // float dis = dis0 + PQCodeDist::distance_single_code(
99
+ // pq, sim_table, codes);
100
+ // res.add(j, dis);
101
+ // }
102
+ // }
103
+
104
+ // This is the modified version of scan_list_with_tables().
105
+ // It was observed that doing manual unrolling of the loop that
106
+ // utilizes distance_single_code() speeds up the computations.
107
+
108
+ /// version of the scan where we use precomputed tables.
109
+ template <class SearchResultType>
110
+ void scan_list_with_table(
111
+ size_t ncode,
112
+ const uint8_t* codes,
113
+ SearchResultType& res) const {
114
+ int counter = 0;
115
+
116
+ size_t saved_j[4] = {0, 0, 0, 0};
117
+ for (size_t j = 0; j < ncode; j++) {
118
+ if (res.skip_entry(j)) {
119
+ continue;
120
+ }
121
+
122
+ saved_j[0] = (counter == 0) ? j : saved_j[0];
123
+ saved_j[1] = (counter == 1) ? j : saved_j[1];
124
+ saved_j[2] = (counter == 2) ? j : saved_j[2];
125
+ saved_j[3] = (counter == 3) ? j : saved_j[3];
126
+
127
+ counter += 1;
128
+ if (counter == 4) {
129
+ float distance_0 = 0;
130
+ float distance_1 = 0;
131
+ float distance_2 = 0;
132
+ float distance_3 = 0;
133
+ PQCodeDist::distance_four_codes(
134
+ pq.M,
135
+ pq.nbits,
136
+ sim_table,
137
+ codes + saved_j[0] * pq.code_size,
138
+ codes + saved_j[1] * pq.code_size,
139
+ codes + saved_j[2] * pq.code_size,
140
+ codes + saved_j[3] * pq.code_size,
141
+ distance_0,
142
+ distance_1,
143
+ distance_2,
144
+ distance_3);
145
+
146
+ res.add(saved_j[0], dis0 + distance_0);
147
+ res.add(saved_j[1], dis0 + distance_1);
148
+ res.add(saved_j[2], dis0 + distance_2);
149
+ res.add(saved_j[3], dis0 + distance_3);
150
+ counter = 0;
151
+ }
152
+ }
153
+
154
+ if (counter >= 1) {
155
+ float dis = dis0 +
156
+ PQCodeDist::distance_single_code(
157
+ pq.M,
158
+ pq.nbits,
159
+ sim_table,
160
+ codes + saved_j[0] * pq.code_size);
161
+ res.add(saved_j[0], dis);
162
+ }
163
+ if (counter >= 2) {
164
+ float dis = dis0 +
165
+ PQCodeDist::distance_single_code(
166
+ pq.M,
167
+ pq.nbits,
168
+ sim_table,
169
+ codes + saved_j[1] * pq.code_size);
170
+ res.add(saved_j[1], dis);
171
+ }
172
+ if (counter >= 3) {
173
+ float dis = dis0 +
174
+ PQCodeDist::distance_single_code(
175
+ pq.M,
176
+ pq.nbits,
177
+ sim_table,
178
+ codes + saved_j[2] * pq.code_size);
179
+ res.add(saved_j[2], dis);
180
+ }
181
+ }
182
+
183
+ /// tables are not precomputed, but pointers are provided to the
184
+ /// relevant X_c|x_r tables
185
+ template <class SearchResultType>
186
+ void scan_list_with_pointer(
187
+ size_t ncode,
188
+ const uint8_t* codes,
189
+ SearchResultType& res) const {
190
+ for (size_t j = 0; j < ncode; j++, codes += pq.code_size) {
191
+ if (res.skip_entry(j)) {
192
+ continue;
193
+ }
194
+ PQDecoder decoder(codes, pq.nbits);
195
+ float dis = dis0;
196
+ const float* tab = sim_table_2;
197
+
198
+ for (size_t m = 0; m < pq.M; m++) {
199
+ int ci = decoder.decode();
200
+ dis += sim_table_ptrs[m][ci] - 2 * tab[ci];
201
+ tab += pq.ksub;
202
+ }
203
+ res.add(j, dis);
204
+ }
205
+ }
206
+
207
+ /// nothing is precomputed: access residuals on-the-fly
208
+ template <class SearchResultType>
209
+ void scan_on_the_fly_dist(
210
+ size_t ncode,
211
+ const uint8_t* codes,
212
+ SearchResultType& res) const {
213
+ const float* dvec;
214
+ float local_dis0 = 0;
215
+ if (by_residual) {
216
+ if (METRIC_TYPE == METRIC_INNER_PRODUCT) {
217
+ ivfpq.quantizer->reconstruct(key, residual_vec);
218
+ local_dis0 = fvec_inner_product_dispatch(residual_vec, qi, d);
219
+ } else {
220
+ ivfpq.quantizer->compute_residual(qi, residual_vec, key);
221
+ }
222
+ dvec = residual_vec;
223
+ } else {
224
+ dvec = qi;
225
+ local_dis0 = 0;
226
+ }
227
+
228
+ for (size_t j = 0; j < ncode; j++, codes += pq.code_size) {
229
+ if (res.skip_entry(j)) {
230
+ continue;
231
+ }
232
+ pq.decode(codes, decoded_vec);
233
+
234
+ float dis;
235
+ if (METRIC_TYPE == METRIC_INNER_PRODUCT) {
236
+ dis = local_dis0 +
237
+ fvec_inner_product_dispatch(decoded_vec, qi, d);
238
+ } else {
239
+ dis = fvec_L2sqr_dispatch(decoded_vec, dvec, d);
240
+ }
241
+ res.add(j, dis);
242
+ }
243
+ }
244
+
245
+ /*****************************************************
246
+ * Scanning codes with polysemous filtering
247
+ *****************************************************/
248
+
249
+ // This is the baseline version of scan_list_polysemous_hc().
250
+ // It demonstrates what this function actually does.
251
+
252
+ // template <class HammingComputer, class SearchResultType>
253
+ // void scan_list_polysemous_hc(
254
+ // size_t ncode,
255
+ // const uint8_t* codes,
256
+ // SearchResultType& res) const {
257
+ // int ht = ivfpq.polysemous_ht;
258
+ // size_t n_hamming_pass = 0, nup = 0;
259
+ //
260
+ // int code_size = pq.code_size;
261
+ //
262
+ // HammingComputer hc(q_code.data(), code_size);
263
+ //
264
+ // for (size_t j = 0; j < ncode; j++, codes += code_size) {
265
+ // if (res.skip_entry(j)) {
266
+ // continue;
267
+ // }
268
+ // const uint8_t* b_code = codes;
269
+ // int hd = hc.hamming(b_code);
270
+ // if (hd < ht) {
271
+ // n_hamming_pass++;
272
+ //
273
+ // float dis =
274
+ // dis0 +
275
+ // PQCodeDist::distance_single_code(
276
+ // pq, sim_table, codes);
277
+ //
278
+ // res.add(j, dis);
279
+ // }
280
+ // }
281
+ // #pragma omp critical
282
+ // { indexIVFPQ_stats.n_hamming_pass += n_hamming_pass; }
283
+ // }
284
+
285
+ // This is the modified version of scan_list_with_tables().
286
+ // It was observed that doing manual unrolling of the loop that
287
+ // utilizes distance_single_code() speeds up the computations.
288
+
289
+ template <class HammingComputer, class SearchResultType>
290
+ void scan_list_polysemous_hc(
291
+ size_t ncode,
292
+ const uint8_t* codes,
293
+ SearchResultType& res) const {
294
+ int ht = ivfpq.polysemous_ht;
295
+ size_t n_hamming_pass = 0;
296
+
297
+ int code_size = static_cast<int>(pq.code_size);
298
+
299
+ size_t saved_j[8];
300
+ int counter = 0;
301
+
302
+ HammingComputer hc(q_code.data(), code_size);
303
+
304
+ for (size_t j = 0; j < (ncode / 4) * 4; j += 4) {
305
+ const uint8_t* b_code = codes + j * code_size;
306
+
307
+ // Unrolling is a key. Basically, doing multiple popcount
308
+ // operations one after another speeds things up.
309
+
310
+ // 9999999 is just an arbitrary large number
311
+ int hd0 = (res.skip_entry(j + 0))
312
+ ? 99999999
313
+ : hc.hamming(b_code + 0 * code_size);
314
+ int hd1 = (res.skip_entry(j + 1))
315
+ ? 99999999
316
+ : hc.hamming(b_code + 1 * code_size);
317
+ int hd2 = (res.skip_entry(j + 2))
318
+ ? 99999999
319
+ : hc.hamming(b_code + 2 * code_size);
320
+ int hd3 = (res.skip_entry(j + 3))
321
+ ? 99999999
322
+ : hc.hamming(b_code + 3 * code_size);
323
+
324
+ saved_j[counter] = j + 0;
325
+ counter = (hd0 < ht) ? (counter + 1) : counter;
326
+ saved_j[counter] = j + 1;
327
+ counter = (hd1 < ht) ? (counter + 1) : counter;
328
+ saved_j[counter] = j + 2;
329
+ counter = (hd2 < ht) ? (counter + 1) : counter;
330
+ saved_j[counter] = j + 3;
331
+ counter = (hd3 < ht) ? (counter + 1) : counter;
332
+
333
+ if (counter >= 4) {
334
+ // process four codes at the same time
335
+ n_hamming_pass += 4;
336
+
337
+ float distance_0 = dis0;
338
+ float distance_1 = dis0;
339
+ float distance_2 = dis0;
340
+ float distance_3 = dis0;
341
+ PQCodeDist::distance_four_codes(
342
+ pq.M,
343
+ pq.nbits,
344
+ sim_table,
345
+ codes + saved_j[0] * pq.code_size,
346
+ codes + saved_j[1] * pq.code_size,
347
+ codes + saved_j[2] * pq.code_size,
348
+ codes + saved_j[3] * pq.code_size,
349
+ distance_0,
350
+ distance_1,
351
+ distance_2,
352
+ distance_3);
353
+
354
+ res.add(saved_j[0], dis0 + distance_0);
355
+ res.add(saved_j[1], dis0 + distance_1);
356
+ res.add(saved_j[2], dis0 + distance_2);
357
+ res.add(saved_j[3], dis0 + distance_3);
358
+
359
+ //
360
+ counter -= 4;
361
+ saved_j[0] = saved_j[4];
362
+ saved_j[1] = saved_j[5];
363
+ saved_j[2] = saved_j[6];
364
+ saved_j[3] = saved_j[7];
365
+ }
366
+ }
367
+
368
+ for (int kk = 0; kk < counter; kk++) {
369
+ n_hamming_pass++;
370
+
371
+ float dis = dis0 +
372
+ PQCodeDist::distance_single_code(
373
+ pq.M,
374
+ pq.nbits,
375
+ sim_table,
376
+ codes + saved_j[kk] * pq.code_size);
377
+
378
+ res.add(saved_j[kk], dis);
379
+ }
380
+
381
+ // process leftovers
382
+ for (size_t j = (ncode / 4) * 4; j < ncode; j++) {
383
+ if (res.skip_entry(j)) {
384
+ continue;
385
+ }
386
+ const uint8_t* b_code = codes + j * code_size;
387
+ int hd = hc.hamming(b_code);
388
+ if (hd < ht) {
389
+ n_hamming_pass++;
390
+
391
+ float dis = dis0 +
392
+ PQCodeDist::distance_single_code(
393
+ pq.M,
394
+ pq.nbits,
395
+ sim_table,
396
+ codes + j * code_size);
397
+
398
+ res.add(j, dis);
399
+ }
400
+ }
401
+
402
+ #pragma omp critical
403
+ {
404
+ indexIVFPQ_stats.n_hamming_pass += n_hamming_pass;
405
+ }
406
+ }
407
+
408
+ template <class SearchResultType>
409
+ void scan_list_polysemous(
410
+ size_t ncode,
411
+ const uint8_t* codes,
412
+ SearchResultType& res) const {
413
+ with_HammingComputer<PQCodeDist::simd_level>(
414
+ pq.code_size, [&]<class HammingComputer>() {
415
+ this->scan_list_polysemous_hc<
416
+ HammingComputer,
417
+ SearchResultType>(ncode, codes, res);
418
+ });
419
+ }
420
+ };
421
+
422
+ /* We put as many parameters as possible in template. Hopefully the
423
+ * gain in runtime is worth the code bloat.
424
+ *
425
+ * C is the comparator < or >, it is directly related to METRIC_TYPE.
426
+ *
427
+ * precompute_mode is how much we precompute (2 = precompute distance tables,
428
+ * 1 = precompute pointers to distances, 0 = compute distances one by one).
429
+ * Currently only 2 is supported
430
+ *
431
+ * use_sel: store or ignore the IDSelector
432
+ */
433
+ template <MetricType METRIC_TYPE, class C, class PQCodeDist, bool use_sel>
434
+ struct IVFPQScanner : IVFPQScannerT<idx_t, METRIC_TYPE, PQCodeDist>,
435
+ InvertedListScanner {
436
+ using InvertedListScanner::scan_codes;
437
+ int precompute_mode;
438
+ const IDSelector* sel;
439
+
440
+ IVFPQScanner(
441
+ const IndexIVFPQ& ivfpq_in,
442
+ bool store_pairs_in,
443
+ int precompute_mode_in,
444
+ const IDSelector* sel_in)
445
+ : IVFPQScannerT<idx_t, METRIC_TYPE, PQCodeDist>(ivfpq_in, nullptr),
446
+ precompute_mode(precompute_mode_in),
447
+ sel(sel_in) {
448
+ this->store_pairs = store_pairs_in;
449
+ this->keep_max = is_similarity_metric(METRIC_TYPE);
450
+ this->code_size = this->pq.code_size;
451
+ }
452
+
453
+ void set_query(const float* query) override {
454
+ this->init_query(query);
455
+ }
456
+
457
+ void set_list(idx_t list_no_in, float coarse_dis_in) override {
458
+ this->list_no = list_no_in;
459
+ this->init_list(list_no_in, coarse_dis_in, precompute_mode);
460
+ }
461
+
462
+ float distance_to_code(const uint8_t* code) const override {
463
+ FAISS_THROW_IF_NOT(precompute_mode == 2);
464
+ float dis = this->dis0 +
465
+ PQCodeDist::distance_single_code(
466
+ this->pq.M, this->pq.nbits, this->sim_table, code);
467
+ return dis;
468
+ }
469
+
470
+ size_t scan_codes(
471
+ size_t ncode,
472
+ const uint8_t* codes,
473
+ const idx_t* ids,
474
+ ResultHandler& handler) const override {
475
+ WrappedSearchResult<C, use_sel> res(
476
+ this->key,
477
+ this->store_pairs ? nullptr : ids,
478
+ this->sel,
479
+ handler);
480
+
481
+ if (this->polysemous_ht > 0) {
482
+ FAISS_THROW_IF_NOT(precompute_mode == 2);
483
+ this->scan_list_polysemous(ncode, codes, res);
484
+ } else if (precompute_mode == 2) {
485
+ this->scan_list_with_table(ncode, codes, res);
486
+ } else if (precompute_mode == 1) {
487
+ this->scan_list_with_pointer(ncode, codes, res);
488
+ } else if (precompute_mode == 0) {
489
+ this->scan_on_the_fly_dist(ncode, codes, res);
490
+ } else {
491
+ FAISS_THROW_MSG("bad precomp mode");
492
+ }
493
+ return res.nup;
494
+ }
495
+ };
496
+
497
+ template <SIMDLevel SL>
498
+ InvertedListScanner* make_IVFPQInvertedListScanner(
499
+ const IndexIVFPQ& ivfpq,
500
+ bool store_pairs,
501
+ const IDSelector* sel);
502
+
503
+ // NOLINTNEXTLINE(facebook-hte-MisplacedTemplateSpecialization)
504
+ template <>
505
+ InvertedListScanner* make_IVFPQInvertedListScanner<THE_SIMD_LEVEL>(
506
+ const IndexIVFPQ& ivfpq,
507
+ bool store_pairs,
508
+ const IDSelector* sel) {
509
+ auto make = [&]<class PQCodeDist, bool use_sel>() -> InvertedListScanner* {
510
+ if (ivfpq.metric_type == METRIC_INNER_PRODUCT) {
511
+ return new IVFPQScanner<
512
+ METRIC_INNER_PRODUCT,
513
+ CMin<float, idx_t>,
514
+ PQCodeDist,
515
+ use_sel>(ivfpq, store_pairs, 2, sel);
516
+ } else if (ivfpq.metric_type == METRIC_L2) {
517
+ return new IVFPQScanner<
518
+ METRIC_L2,
519
+ CMax<float, idx_t>,
520
+ PQCodeDist,
521
+ use_sel>(ivfpq, store_pairs, 2, sel);
522
+ } else {
523
+ FAISS_THROW_MSG("unsupported metric type");
524
+ }
525
+ };
526
+
527
+ auto with_decoder = [&]<bool use_sel>() -> InvertedListScanner* {
528
+ if (ivfpq.pq.nbits == 8) {
529
+ return make.template
530
+ operator()<PQCodeDistance<PQDecoder8, THE_SIMD_LEVEL>, use_sel>();
531
+ } else if (ivfpq.pq.nbits == 16) {
532
+ return make.template
533
+ operator()<PQCodeDistance<PQDecoder16, THE_SIMD_LEVEL>, use_sel>();
534
+ } else {
535
+ return make.template operator()<
536
+ PQCodeDistance<PQDecoderGeneric, THE_SIMD_LEVEL>,
537
+ use_sel>();
538
+ }
539
+ };
540
+
541
+ if (sel) {
542
+ return with_decoder.template operator()<true>();
543
+ } else {
544
+ return with_decoder.template operator()<false>();
545
+ }
546
+ }
547
+
548
+ } // namespace pq_code_distance
549
+ } // namespace faiss