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
@@ -8,12 +8,12 @@
8
8
  #pragma once
9
9
 
10
10
  #include <faiss/IndexIVF.h>
11
- #include <faiss/impl/FastScanDistancePostProcessing.h>
11
+ #include <faiss/impl/fast_scan/FastScanDistancePostProcessing.h>
12
+ #include <faiss/impl/fast_scan/fast_scan.h>
12
13
  #include <faiss/utils/AlignedTable.h>
13
14
 
14
15
  namespace faiss {
15
16
 
16
- struct NormTableScaler;
17
17
  struct SIMDResultHandlerToFloat;
18
18
  struct Quantizer;
19
19
 
@@ -41,14 +41,14 @@ struct Quantizer;
41
41
 
42
42
  struct IndexIVFFastScan : IndexIVF {
43
43
  // size of the kernel
44
- int bbs; // set at build time
44
+ int bbs = 0; // set at build time
45
45
 
46
- size_t M;
47
- size_t nbits;
48
- size_t ksub;
46
+ size_t M = 0;
47
+ size_t nbits = 0;
48
+ size_t ksub = 0;
49
49
 
50
50
  // M rounded up to a multiple of 2
51
- size_t M2;
51
+ size_t M2 = 0;
52
52
 
53
53
  // search-time implementation
54
54
  int implem = 0;
@@ -156,7 +156,7 @@ struct IndexIVFFastScan : IndexIVF {
156
156
  * @param context processing context containing query factors
157
157
  * processor
158
158
  */
159
- void compute_LUT_uint8(
159
+ virtual void compute_LUT_uint8(
160
160
  size_t n,
161
161
  const float* x,
162
162
  const CoarseQuantized& cq,
@@ -222,45 +222,31 @@ struct IndexIVFFastScan : IndexIVF {
222
222
  RangeSearchResult* result,
223
223
  const SearchParameters* params = nullptr) const override;
224
224
 
225
- /** Create a KNN handler for this index type
225
+ /** Create a SIMD-dispatched scanner for knn search (IVF variant).
226
226
  *
227
- * This method can be overridden by derived classes to provide
228
- * specialized handlers (e.g., IVFRaBitQHeapHandler for RaBitQ indexes).
229
- * Base implementation creates standard handlers based on k and impl.
227
+ * Returns a FastScanCodeScanner that bundles handler + accumulation
228
+ * kernel behind the SIMD dispatch boundary. ntotal is not passed
229
+ * because IVF sets it per-list via handler->ntotal.
230
+ * Derived classes override this to provide custom handlers
231
+ * (e.g. RaBitQ).
230
232
  *
231
- * @param is_max true for max-heap (inner product), false for
232
- * min-heap (L2 distance)
233
- * @param impl implementation number:
234
- * - even (10, 12, 14): use heap for top-k
235
- * - odd (11, 13, 15): use reservoir sampling
236
- * @param n number of queries
237
- * @param k number of neighbors to find per query
238
- * @param distances output array for distances (n * k), will be
239
- * populated by handler
240
- * @param labels output array for result IDs (n * k), will be
241
- * populated by handler
242
- * @param sel optional ID selector to filter results (nullptr =
243
- * no filtering)
244
- * @param context processing context containing additional data
245
- * @param normalizers optional array of size 2*n for converting quantized
246
- * uint16 distances to float.
247
- *
248
- * @return Allocated result handler (caller owns and must delete).
249
- * Handler processes SIMD batches and populates distances/labels.
250
- *
251
- * @note The returned handler must be deleted by caller after use.
252
- * Typical usage: handler->begin() → process batches → handler->end()
233
+ * @param is_max whether to use CMax comparator (true) or CMin
234
+ * @param n number of queries
235
+ * @param k number of neighbors to find
236
+ * @param distances output distances array
237
+ * @param labels output labels array
238
+ * @param sel optional ID selector
239
+ * @return scanner
253
240
  */
254
- virtual SIMDResultHandlerToFloat* make_knn_handler(
241
+ virtual std::unique_ptr<FastScanCodeScanner> make_knn_scanner(
255
242
  bool is_max,
256
- int impl,
257
243
  idx_t n,
258
244
  idx_t k,
259
245
  float* distances,
260
246
  idx_t* labels,
261
247
  const IDSelector* sel,
262
- const FastScanDistancePostProcessing& context,
263
- const float* normalizers = nullptr) const;
248
+ int impl = 0,
249
+ const FastScanDistancePostProcessing& context = {}) const;
264
250
 
265
251
  // dispatch to implementations and parallelize
266
252
  void search_dispatch_implem(
@@ -306,16 +292,18 @@ struct IndexIVFFastScan : IndexIVF {
306
292
  const IVFSearchParameters* params = nullptr) const;
307
293
 
308
294
  // implem 10 and 12 are not multithreaded internally, so
309
- // export search stats
295
+ // export search stats. k is required for ensure_topk_full support.
310
296
  void search_implem_10(
311
297
  idx_t n,
312
298
  const float* x,
299
+ idx_t k,
313
300
  SIMDResultHandlerToFloat& handler,
314
301
  const CoarseQuantized& cq,
315
302
  size_t* ndis_out,
316
303
  size_t* nlist_out,
317
304
  const FastScanDistancePostProcessing& context,
318
- const IVFSearchParameters* params = nullptr) const;
305
+ const IVFSearchParameters* params,
306
+ FastScanCodeScanner& scanner) const;
319
307
 
320
308
  void search_implem_12(
321
309
  idx_t n,
@@ -325,7 +313,8 @@ struct IndexIVFFastScan : IndexIVF {
325
313
  size_t* ndis_out,
326
314
  size_t* nlist_out,
327
315
  const FastScanDistancePostProcessing& context,
328
- const IVFSearchParameters* params = nullptr) const;
316
+ const IVFSearchParameters* params,
317
+ FastScanCodeScanner& scanner) const;
329
318
 
330
319
  // implem 14 is multithreaded internally across nprobes and queries
331
320
  void search_implem_14(
@@ -359,6 +348,18 @@ struct IndexIVFFastScan : IndexIVF {
359
348
  */
360
349
  void sa_decode(idx_t n, const uint8_t* bytes, float* x) const override;
361
350
 
351
+ /** Get the size of the code portion packed by pq4_pack_codes.
352
+ *
353
+ * Returns the number of bytes per vector that are interleaved into
354
+ * SIMD blocks by pq4_pack_codes, excluding any embedded metadata
355
+ * (e.g., RaBitQ factors). The meaning of these bytes depends on the
356
+ * quantizer: for PQ/AQ they are 4-bit sub-quantizer nibbles, for
357
+ * RaBitQ they are 1-bit-per-dimension sign bits packed into nibbles.
358
+ *
359
+ * Must be implemented by all derived classes.
360
+ */
361
+ virtual size_t fast_scan_code_size() const = 0;
362
+
362
363
  protected:
363
364
  /** Get stride for interpreting codes during SIMD packing.
364
365
  *
@@ -13,7 +13,6 @@
13
13
 
14
14
  #include <cinttypes>
15
15
  #include <cstdio>
16
- #include <numeric>
17
16
 
18
17
  #include <faiss/IndexFlat.h>
19
18
 
@@ -22,7 +21,13 @@
22
21
 
23
22
  #include <faiss/impl/FaissAssert.h>
24
23
  #include <faiss/impl/expanded_scanners.h>
24
+ #include <faiss/utils/distances_dispatch.h>
25
25
  #include <faiss/utils/extra_distances.h>
26
+
27
+ #define THE_SIMD_LEVEL SIMDLevel::NONE
28
+ // NOLINTNEXTLINE(facebook-hte-InlineHeader)
29
+ #include <faiss/utils/simd_impl/IVFFlatScanner-inl.h>
30
+
26
31
  #include <faiss/utils/utils.h>
27
32
 
28
33
  namespace faiss {
@@ -32,18 +37,18 @@ namespace faiss {
32
37
  ******************************************/
33
38
 
34
39
  IndexIVFFlat::IndexIVFFlat(
35
- Index* quantizer,
36
- size_t d,
37
- size_t nlist,
40
+ Index* quantizer_in,
41
+ size_t d_in,
42
+ size_t nlist_in,
38
43
  MetricType metric,
39
- bool own_invlists)
44
+ bool own_invlists_in)
40
45
  : IndexIVF(
41
- quantizer,
42
- d,
43
- nlist,
44
- sizeof(float) * d,
46
+ quantizer_in,
47
+ d_in,
48
+ nlist_in,
49
+ sizeof(float) * d_in,
45
50
  metric,
46
- own_invlists) {
51
+ own_invlists_in) {
47
52
  code_size = sizeof(float) * d;
48
53
  by_residual = false;
49
54
  }
@@ -61,7 +66,7 @@ void IndexIVFFlat::add_core(
61
66
  FAISS_THROW_IF_NOT(is_trained);
62
67
  FAISS_THROW_IF_NOT(coarse_idx);
63
68
  FAISS_THROW_IF_NOT(!by_residual);
64
- assert(invlists);
69
+ FAISS_THROW_IF_NOT_MSG(invlists, "invlists not initialized");
65
70
  direct_map.check_can_add(xids);
66
71
 
67
72
  int64_t n_add = 0;
@@ -74,7 +79,7 @@ void IndexIVFFlat::add_core(
74
79
  int rank = omp_get_thread_num();
75
80
 
76
81
  // each thread takes care of a subset of lists
77
- for (size_t i = 0; i < n; i++) {
82
+ for (idx_t i = 0; i < n; i++) {
78
83
  idx_t list_no = coarse_idx[i];
79
84
 
80
85
  if (list_no >= 0 && list_no % nt == rank) {
@@ -110,7 +115,7 @@ void IndexIVFFlat::encode_vectors(
110
115
  memcpy(codes, x, code_size * n);
111
116
  } else {
112
117
  size_t coarse_size = coarse_code_size();
113
- for (size_t i = 0; i < n; i++) {
118
+ for (idx_t i = 0; i < n; i++) {
114
119
  int64_t list_no = list_nos[i];
115
120
  uint8_t* code = codes + i * (code_size + coarse_size);
116
121
  const float* xi = x + i * d;
@@ -129,7 +134,7 @@ void IndexIVFFlat::decode_vectors(
129
134
  const uint8_t* codes,
130
135
  const idx_t* /*listnos*/,
131
136
  float* x) const {
132
- for (size_t i = 0; i < n; i++) {
137
+ for (idx_t i = 0; i < n; i++) {
133
138
  const uint8_t* code = codes + i * code_size;
134
139
  float* xi = x + i * d;
135
140
  memcpy(xi, code, code_size);
@@ -138,55 +143,13 @@ void IndexIVFFlat::decode_vectors(
138
143
 
139
144
  void IndexIVFFlat::sa_decode(idx_t n, const uint8_t* bytes, float* x) const {
140
145
  size_t coarse_size = coarse_code_size();
141
- for (size_t i = 0; i < n; i++) {
146
+ for (idx_t i = 0; i < n; i++) {
142
147
  const uint8_t* code = bytes + i * (code_size + coarse_size);
143
148
  float* xi = x + i * d;
144
149
  memcpy(xi, code + coarse_size, code_size);
145
150
  }
146
151
  }
147
152
 
148
- namespace {
149
-
150
- template <typename VectorDistance>
151
- struct IVFFlatScanner : InvertedListScanner {
152
- VectorDistance vd;
153
- using C = typename VectorDistance::C;
154
-
155
- IVFFlatScanner(
156
- const VectorDistance& vd,
157
- bool store_pairs,
158
- const IDSelector* sel)
159
- : InvertedListScanner(store_pairs, sel), vd(vd) {
160
- keep_max = vd.is_similarity;
161
- code_size = vd.d * sizeof(float);
162
- }
163
-
164
- const float* xi;
165
- void set_query(const float* query) override {
166
- this->xi = query;
167
- }
168
-
169
- void set_list(idx_t list_no, float /* coarse_dis */) override {
170
- this->list_no = list_no;
171
- }
172
-
173
- float distance_to_code(const uint8_t* code) const final {
174
- const float* yj = (float*)code;
175
- return vd(xi, yj);
176
- }
177
-
178
- // redefining the scan_codes allows to inline the distance_to_code
179
- size_t scan_codes(
180
- size_t list_size,
181
- const uint8_t* codes,
182
- const idx_t* ids,
183
- ResultHandler& handler) const {
184
- return run_scan_codes_fix_C<C>(*this, list_size, codes, ids, handler);
185
- }
186
- };
187
-
188
- } // anonymous namespace
189
-
190
153
  InvertedListScanner* IndexIVFFlat::get_InvertedListScanner(
191
154
  bool store_pairs,
192
155
  const IDSelector* sel,
@@ -209,12 +172,17 @@ void IndexIVFFlat::reconstruct_from_offset(
209
172
  ******************************************/
210
173
 
211
174
  IndexIVFFlatDedup::IndexIVFFlatDedup(
212
- Index* quantizer,
213
- size_t d,
214
- size_t nlist_,
215
- MetricType metric_type,
216
- bool own_invlists)
217
- : IndexIVFFlat(quantizer, d, nlist_, metric_type, own_invlists) {}
175
+ Index* quantizer_in,
176
+ size_t d_in,
177
+ size_t nlist_in,
178
+ MetricType metric_type_in,
179
+ bool own_invlists_in)
180
+ : IndexIVFFlat(
181
+ quantizer_in,
182
+ d_in,
183
+ nlist_in,
184
+ metric_type_in,
185
+ own_invlists_in) {}
218
186
 
219
187
  void IndexIVFFlatDedup::train(idx_t n, const float* x) {
220
188
  std::unordered_map<uint64_t, idx_t> map;
@@ -247,7 +215,7 @@ void IndexIVFFlatDedup::add_with_ids(
247
215
  const float* x,
248
216
  const idx_t* xids) {
249
217
  FAISS_THROW_IF_NOT(is_trained);
250
- assert(invlists);
218
+ FAISS_THROW_IF_NOT_MSG(invlists, "invlists not initialized");
251
219
  FAISS_THROW_IF_NOT_MSG(
252
220
  direct_map.no(), "IVFFlatDedup not implemented with direct_map");
253
221
  std::unique_ptr<int64_t[]> idx(new int64_t[na]);
@@ -261,7 +229,7 @@ void IndexIVFFlatDedup::add_with_ids(
261
229
  int rank = omp_get_thread_num();
262
230
 
263
231
  // each thread takes care of a subset of lists
264
- for (size_t i = 0; i < na; i++) {
232
+ for (idx_t i = 0; i < na; i++) {
265
233
  int64_t list_no = idx[i];
266
234
 
267
235
  if (list_no < 0 || list_no % nt != rank) {
@@ -320,7 +288,7 @@ void IndexIVFFlatDedup::search_preassigned(
320
288
  idx_t* labels,
321
289
  bool store_pairs,
322
290
  const IVFSearchParameters* params,
323
- IndexIVFStats* stats) const {
291
+ IndexIVFStats* /*stats*/) const {
324
292
  FAISS_THROW_IF_NOT_MSG(
325
293
  !store_pairs, "store_pairs not supported in IVFDedup");
326
294
 
@@ -401,7 +369,7 @@ size_t IndexIVFFlatDedup::remove_ids(const IDSelector& sel) {
401
369
  std::vector<int64_t> toremove(nlist);
402
370
 
403
371
  #pragma omp parallel for
404
- for (int64_t i = 0; i < nlist; i++) {
372
+ for (idx_t i = 0; i < static_cast<idx_t>(nlist); i++) {
405
373
  int64_t l0 = invlists->list_size(i), l = l0, j = 0;
406
374
  InvertedLists::ScopedIds idsi(invlists, i);
407
375
  while (j < l) {
@@ -429,7 +397,7 @@ size_t IndexIVFFlatDedup::remove_ids(const IDSelector& sel) {
429
397
  }
430
398
  // this will not run well in parallel on ondisk because of possible shrinks
431
399
  int64_t nremove = 0;
432
- for (int64_t i = 0; i < nlist; i++) {
400
+ for (idx_t i = 0; i < static_cast<idx_t>(nlist); i++) {
433
401
  if (toremove[i] > 0) {
434
402
  nremove += toremove[i];
435
403
  invlists->resize(i, invlists->list_size(i) - toremove[i]);
@@ -62,6 +62,38 @@ struct IndexIVFFlat : IndexIVF {
62
62
  IndexIVFFlat();
63
63
  };
64
64
 
65
+ template <typename VectorDistance>
66
+ struct IVFFlatScanner : InvertedListScanner {
67
+ VectorDistance vd;
68
+ using C = typename VectorDistance::C;
69
+
70
+ IVFFlatScanner(
71
+ const VectorDistance& vd,
72
+ bool store_pairs,
73
+ const IDSelector* sel)
74
+ : InvertedListScanner(store_pairs, sel), vd(vd) {
75
+ keep_max = vd.is_similarity;
76
+ code_size = vd.d * sizeof(float);
77
+ }
78
+
79
+ const float* xi = nullptr;
80
+ void set_query(const float* query) override {
81
+ this->xi = query;
82
+ }
83
+
84
+ void set_list(idx_t list_no, float /* coarse_dis */) override {
85
+ this->list_no = list_no;
86
+ }
87
+
88
+ float distance_to_code(const uint8_t* code) const final;
89
+
90
+ size_t scan_codes(
91
+ size_t list_size,
92
+ const uint8_t* codes,
93
+ const idx_t* ids,
94
+ ResultHandler& handler) const override;
95
+ };
96
+
65
97
  struct IndexIVFFlatDedup : IndexIVFFlat {
66
98
  /** Maps ids stored in the index to the ids of vectors that are
67
99
  * the same. When a vector is unique, it does not appear in the
@@ -20,29 +20,35 @@
20
20
  #include <faiss/impl/ResultHandler.h>
21
21
 
22
22
  #include <faiss/impl/FaissAssert.h>
23
+ #include <faiss/utils/distances_dispatch.h>
23
24
  #include <faiss/utils/extra_distances.h>
24
25
  #include <faiss/utils/utils.h>
25
26
 
26
27
  namespace faiss {
27
28
 
28
29
  IndexIVFFlatPanorama::IndexIVFFlatPanorama(
29
- Index* quantizer,
30
- size_t d,
31
- size_t nlist,
32
- int n_levels,
30
+ Index* quantizer_in,
31
+ size_t d_in,
32
+ size_t nlist_in,
33
+ int n_levels_in,
33
34
  MetricType metric,
34
- bool own_invlists)
35
- : IndexIVFFlat(quantizer, d, nlist, metric, false), n_levels(n_levels) {
35
+ bool own_invlists_in,
36
+ size_t batch_size_in)
37
+ : IndexIVFFlat(quantizer_in, d_in, nlist_in, metric, false),
38
+ n_levels(n_levels_in),
39
+ batch_size(batch_size_in) {
36
40
  FAISS_THROW_IF_NOT(metric == METRIC_L2 || metric == METRIC_INNER_PRODUCT);
37
41
 
38
42
  // We construct the inverted lists here so that we can use the
39
43
  // level-oriented storage. This does not cause a leak as we constructed
40
44
  // IndexIVF first, with own_invlists set to false.
41
- this->invlists = new ArrayInvertedListsPanorama(nlist, code_size, n_levels);
42
- this->own_invlists = own_invlists;
45
+ this->invlists = new ArrayInvertedListsPanorama(
46
+ nlist, code_size, n_levels, batch_size);
47
+ this->own_invlists = own_invlists_in;
43
48
  }
44
49
 
45
- IndexIVFFlatPanorama::IndexIVFFlatPanorama() : n_levels(0) {}
50
+ IndexIVFFlatPanorama::IndexIVFFlatPanorama()
51
+ : n_levels(0), batch_size(Panorama::kDefaultBatchSize) {}
46
52
 
47
53
  namespace {
48
54
 
@@ -53,15 +59,26 @@ struct IVFFlatScannerPanorama : InvertedListScanner {
53
59
  using C = typename VectorDistance::C;
54
60
  static constexpr MetricType metric = VectorDistance::metric;
55
61
 
62
+ mutable std::vector<uint32_t> active_indices_;
63
+ mutable std::vector<uint8_t> active_byteset_;
64
+ mutable std::vector<float> exact_distances_;
65
+ mutable std::vector<float> dot_buffer_;
66
+
56
67
  IVFFlatScannerPanorama(
57
- const VectorDistance& vd,
58
- const ArrayInvertedListsPanorama* storage,
59
- bool store_pairs,
60
- const IDSelector* sel)
61
- : InvertedListScanner(store_pairs, sel), vd(vd), storage(storage) {
68
+ const VectorDistance& vd_in,
69
+ const ArrayInvertedListsPanorama* storage_in,
70
+ bool store_pairs_in,
71
+ const IDSelector* sel_in)
72
+ : InvertedListScanner(store_pairs_in, sel_in),
73
+ vd(vd_in),
74
+ storage(storage_in) {
62
75
  keep_max = vd.is_similarity;
63
76
  code_size = vd.d * sizeof(float);
64
- cum_sums.resize(storage->n_levels + 1);
77
+ cum_sums.resize(storage->pano.n_levels + 1);
78
+ active_indices_.resize(storage->pano.batch_size);
79
+ active_byteset_.resize(storage->pano.batch_size);
80
+ exact_distances_.resize(storage->pano.batch_size);
81
+ dot_buffer_.resize(storage->pano.batch_size);
65
82
  }
66
83
 
67
84
  const float* xi = nullptr;
@@ -73,8 +90,8 @@ struct IVFFlatScannerPanorama : InvertedListScanner {
73
90
  q_norm = cum_sums[0] * cum_sums[0];
74
91
  }
75
92
 
76
- void set_list(idx_t list_no, float /* coarse_dis */) override {
77
- this->list_no = list_no;
93
+ void set_list(idx_t list_no_in, float /* coarse_dis */) override {
94
+ this->list_no = list_no_in;
78
95
  }
79
96
 
80
97
  /// This function is unreachable as `IndexIVF` only calls this within
@@ -85,6 +102,8 @@ struct IVFFlatScannerPanorama : InvertedListScanner {
85
102
  "IndexIVFFlatPanorama does not support distance_to_code");
86
103
  }
87
104
 
105
+ using InvertedListScanner::scan_codes;
106
+
88
107
  size_t scan_codes(
89
108
  size_t list_size,
90
109
  const uint8_t* codes,
@@ -92,20 +111,16 @@ struct IVFFlatScannerPanorama : InvertedListScanner {
92
111
  ResultHandler& handler) const override {
93
112
  size_t nup = 0;
94
113
 
95
- const size_t n_batches =
96
- (list_size + storage->kBatchSize - 1) / storage->kBatchSize;
114
+ const size_t bs = storage->pano.batch_size;
115
+ const size_t n_batches = (list_size + bs - 1) / bs;
97
116
 
98
117
  const float* cum_sums_data = storage->get_cum_sums(list_no);
99
118
 
100
- std::vector<float> exact_distances(storage->kBatchSize);
101
- std::vector<uint32_t> active_indices(storage->kBatchSize);
102
-
103
119
  PanoramaStats local_stats;
104
120
  local_stats.reset();
105
121
 
106
122
  for (size_t batch_no = 0; batch_no < n_batches; batch_no++) {
107
- size_t batch_start = batch_no * storage->kBatchSize;
108
-
123
+ size_t batch_start = batch_no * bs;
109
124
  size_t num_active = with_metric_type(metric, [&]<MetricType M>() {
110
125
  return storage->pano.progressive_filter_batch<C, M>(
111
126
  codes,
@@ -117,23 +132,31 @@ struct IVFFlatScannerPanorama : InvertedListScanner {
117
132
  sel,
118
133
  ids,
119
134
  use_sel,
120
- active_indices,
121
- exact_distances,
135
+ active_indices_,
136
+ active_byteset_,
137
+ exact_distances_,
138
+ dot_buffer_,
122
139
  handler.threshold,
123
140
  local_stats);
124
141
  });
125
142
 
143
+ // num_active is the count of codes for which exact distance
144
+ // was computed in this batch (post-filter, post-pruning).
145
+ handler.stats.scan_cnt += num_active;
146
+
126
147
  // Add batch survivors to heap.
127
148
  for (size_t i = 0; i < num_active; i++) {
128
- uint32_t idx = active_indices[i];
149
+ uint32_t idx = active_indices_[i];
129
150
  size_t global_idx = batch_start + idx;
130
- float dis = exact_distances[idx];
151
+ float dis = exact_distances_[idx];
131
152
 
132
153
  if (C::cmp(handler.threshold, dis)) {
133
154
  int64_t id = store_pairs ? lo_build(list_no, global_idx)
134
155
  : ids[global_idx];
135
- handler.add_result(dis, id);
136
- nup++;
156
+ if (handler.add_result(dis, id)) {
157
+ handler.stats.nheap_updates++;
158
+ nup++;
159
+ }
137
160
  }
138
161
  }
139
162
  }
@@ -37,6 +37,7 @@ namespace faiss {
37
37
  /// `ArrayInvertedListsPanorama`, which is a struct member of `IndexIVF`.
38
38
  struct IndexIVFFlatPanorama : IndexIVFFlat {
39
39
  size_t n_levels;
40
+ size_t batch_size;
40
41
 
41
42
  std::vector<MaybeOwnedVector<float>> cum_sums;
42
43
 
@@ -46,7 +47,8 @@ struct IndexIVFFlatPanorama : IndexIVFFlat {
46
47
  size_t nlist_,
47
48
  int n_levels,
48
49
  MetricType = METRIC_L2,
49
- bool own_invlists = true);
50
+ bool own_invlists = true,
51
+ size_t batch_size = Panorama::kDefaultBatchSize);
50
52
 
51
53
  InvertedListScanner* get_InvertedListScanner(
52
54
  bool store_pairs,
@@ -13,13 +13,13 @@
13
13
  namespace faiss {
14
14
 
15
15
  IndexIVFIndependentQuantizer::IndexIVFIndependentQuantizer(
16
- Index* quantizer,
17
- IndexIVF* index_ivf,
18
- VectorTransform* vt)
19
- : Index(quantizer->d, index_ivf->metric_type),
20
- quantizer(quantizer),
21
- vt(vt),
22
- index_ivf(index_ivf) {
16
+ Index* quantizer_in,
17
+ IndexIVF* index_ivf_in,
18
+ VectorTransform* vt_in)
19
+ : Index(quantizer_in->d, index_ivf_in->metric_type),
20
+ quantizer(quantizer_in),
21
+ vt(vt_in),
22
+ index_ivf(index_ivf_in) {
23
23
  if (vt) {
24
24
  FAISS_THROW_IF_NOT_MSG(
25
25
  vt->d_in == d && vt->d_out == index_ivf->d,
@@ -29,14 +29,16 @@ IndexIVFIndependentQuantizer::IndexIVFIndependentQuantizer(
29
29
  }
30
30
 
31
31
  if (quantizer->is_trained && quantizer->ntotal != 0) {
32
- FAISS_THROW_IF_NOT(quantizer->ntotal == index_ivf->nlist);
32
+ FAISS_THROW_IF_NOT(
33
+ quantizer->ntotal == static_cast<idx_t>(index_ivf->nlist));
33
34
  }
34
35
  if (index_ivf->is_trained && vt) {
35
36
  FAISS_THROW_IF_NOT(vt->is_trained);
36
37
  }
37
38
  ntotal = index_ivf->ntotal;
38
39
  is_trained =
39
- (quantizer->is_trained && quantizer->ntotal == index_ivf->nlist &&
40
+ (quantizer->is_trained &&
41
+ quantizer->ntotal == static_cast<idx_t>(index_ivf->nlist) &&
40
42
  (!vt || vt->is_trained) && index_ivf->is_trained);
41
43
 
42
44
  // disable precomputed tables because they use the distances that are
@@ -57,15 +59,16 @@ IndexIVFIndependentQuantizer::~IndexIVFIndependentQuantizer() {
57
59
  namespace {
58
60
 
59
61
  struct VTransformedVectors : TransformedVectors {
60
- VTransformedVectors(const VectorTransform* vt, idx_t n, const float* x)
61
- : TransformedVectors(x, vt ? vt->apply(n, x) : x) {}
62
+ VTransformedVectors(const VectorTransform* vt, idx_t n, const float* x_in)
63
+ : TransformedVectors(x_in, vt ? vt->apply(n, x_in) : x_in) {}
62
64
  };
63
65
 
64
66
  struct SubsampledVectors : TransformedVectors {
65
- SubsampledVectors(int d, idx_t* n, idx_t max_n, const float* x)
67
+ SubsampledVectors(int d, idx_t* n, idx_t max_n, const float* x_in)
66
68
  : TransformedVectors(
67
- x,
68
- fvecs_maybe_subsample(d, (size_t*)n, max_n, x, true)) {}
69
+ x_in,
70
+ fvecs_maybe_subsample(d, (size_t*)n, max_n, x_in, true)) {
71
+ }
69
72
  };
70
73
 
71
74
  } // anonymous namespace
@@ -88,7 +91,7 @@ void IndexIVFIndependentQuantizer::search(
88
91
  idx_t* labels,
89
92
  const SearchParameters* params) const {
90
93
  FAISS_THROW_IF_NOT_MSG(!params, "search parameters not supported");
91
- int nprobe = index_ivf->nprobe;
94
+ size_t nprobe = index_ivf->nprobe;
92
95
  std::vector<float> D(n * nprobe);
93
96
  std::vector<idx_t> I(n * nprobe);
94
97
  quantizer->search(n, x, nprobe, D.data(), I.data());