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
@@ -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,
@@ -201,7 +164,9 @@ void IndexIVFFlat::reconstruct_from_offset(
201
164
  int64_t list_no,
202
165
  int64_t offset,
203
166
  float* recons) const {
204
- memcpy(recons, invlists->get_single_code(list_no, offset), code_size);
167
+ memcpy(recons,
168
+ InvertedLists::ScopedCodes(invlists, list_no, offset).get(),
169
+ code_size);
205
170
  }
206
171
 
207
172
  /*****************************************
@@ -209,12 +174,17 @@ void IndexIVFFlat::reconstruct_from_offset(
209
174
  ******************************************/
210
175
 
211
176
  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) {}
177
+ Index* quantizer_in,
178
+ size_t d_in,
179
+ size_t nlist_in,
180
+ MetricType metric_type_in,
181
+ bool own_invlists_in)
182
+ : IndexIVFFlat(
183
+ quantizer_in,
184
+ d_in,
185
+ nlist_in,
186
+ metric_type_in,
187
+ own_invlists_in) {}
218
188
 
219
189
  void IndexIVFFlatDedup::train(idx_t n, const float* x) {
220
190
  std::unordered_map<uint64_t, idx_t> map;
@@ -247,7 +217,7 @@ void IndexIVFFlatDedup::add_with_ids(
247
217
  const float* x,
248
218
  const idx_t* xids) {
249
219
  FAISS_THROW_IF_NOT(is_trained);
250
- assert(invlists);
220
+ FAISS_THROW_IF_NOT_MSG(invlists, "invlists not initialized");
251
221
  FAISS_THROW_IF_NOT_MSG(
252
222
  direct_map.no(), "IVFFlatDedup not implemented with direct_map");
253
223
  std::unique_ptr<int64_t[]> idx(new int64_t[na]);
@@ -261,7 +231,7 @@ void IndexIVFFlatDedup::add_with_ids(
261
231
  int rank = omp_get_thread_num();
262
232
 
263
233
  // each thread takes care of a subset of lists
264
- for (size_t i = 0; i < na; i++) {
234
+ for (idx_t i = 0; i < na; i++) {
265
235
  int64_t list_no = idx[i];
266
236
 
267
237
  if (list_no < 0 || list_no % nt != rank) {
@@ -320,7 +290,7 @@ void IndexIVFFlatDedup::search_preassigned(
320
290
  idx_t* labels,
321
291
  bool store_pairs,
322
292
  const IVFSearchParameters* params,
323
- IndexIVFStats* stats) const {
293
+ IndexIVFStats* /*stats*/) const {
324
294
  FAISS_THROW_IF_NOT_MSG(
325
295
  !store_pairs, "store_pairs not supported in IVFDedup");
326
296
 
@@ -401,7 +371,7 @@ size_t IndexIVFFlatDedup::remove_ids(const IDSelector& sel) {
401
371
  std::vector<int64_t> toremove(nlist);
402
372
 
403
373
  #pragma omp parallel for
404
- for (int64_t i = 0; i < nlist; i++) {
374
+ for (idx_t i = 0; i < static_cast<idx_t>(nlist); i++) {
405
375
  int64_t l0 = invlists->list_size(i), l = l0, j = 0;
406
376
  InvertedLists::ScopedIds idsi(invlists, i);
407
377
  while (j < l) {
@@ -429,7 +399,7 @@ size_t IndexIVFFlatDedup::remove_ids(const IDSelector& sel) {
429
399
  }
430
400
  // this will not run well in parallel on ondisk because of possible shrinks
431
401
  int64_t nremove = 0;
432
- for (int64_t i = 0; i < nlist; i++) {
402
+ for (idx_t i = 0; i < static_cast<idx_t>(nlist); i++) {
433
403
  if (toremove[i] > 0) {
434
404
  nremove += toremove[i];
435
405
  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
  }
@@ -171,9 +194,9 @@ void IndexIVFFlatPanorama::reconstruct_from_offset(
171
194
  int64_t list_no,
172
195
  int64_t offset,
173
196
  float* recons) const {
174
- const uint8_t* code = invlists->get_single_code(list_no, offset);
175
- memcpy(recons, code, code_size);
176
- invlists->release_codes(list_no, code);
197
+ memcpy(recons,
198
+ InvertedLists::ScopedCodes(invlists, list_no, offset).get(),
199
+ code_size);
177
200
  }
178
201
 
179
202
  } // namespace faiss
@@ -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());