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
@@ -38,6 +38,15 @@ const std::map<faiss::ScalarQuantizer::QuantizerType, std::string> sq_types = {
38
38
  {faiss::ScalarQuantizer::QT_bf16, "SQbf16"},
39
39
  {faiss::ScalarQuantizer::QT_8bit_direct_signed, "SQ8_direct_signed"},
40
40
  {faiss::ScalarQuantizer::QT_8bit_direct, "SQ8_direct"},
41
+ {faiss::ScalarQuantizer::QT_1bit_tqmse, "SQtqmse1"},
42
+ {faiss::ScalarQuantizer::QT_2bit_tqmse, "SQtqmse2"},
43
+ {faiss::ScalarQuantizer::QT_3bit_tqmse, "SQtqmse3"},
44
+ {faiss::ScalarQuantizer::QT_4bit_tqmse, "SQtqmse4"},
45
+ {faiss::ScalarQuantizer::QT_8bit_tqmse, "SQtqmse8"},
46
+ {faiss::ScalarQuantizer::QT_2bit_tq, "SQtq2"},
47
+ {faiss::ScalarQuantizer::QT_3bit_tq, "SQtq3"},
48
+ {faiss::ScalarQuantizer::QT_4bit_tq, "SQtq4"},
49
+ {faiss::ScalarQuantizer::QT_5bit_tq, "SQtq5"},
41
50
  };
42
51
 
43
52
  int get_hnsw_M(const faiss::IndexHNSW* index) {
@@ -28,6 +28,7 @@
28
28
  #include <faiss/gpu/GpuIndexIVFPQ.h>
29
29
 
30
30
  #include <variant>
31
+ #include <vector>
31
32
  #include "faiss/Index.h"
32
33
 
33
34
  namespace faiss {
@@ -193,14 +194,14 @@ struct GpuIndexCagraConfig : public GpuIndexConfig {
193
194
 
194
195
  enum class search_algo {
195
196
  /// For large batch sizes.
196
- SINGLE_CTA,
197
+ SINGLE_CTA = 0,
197
198
  /// For small batch sizes.
198
- MULTI_CTA,
199
- MULTI_KERNEL,
200
- AUTO
199
+ MULTI_CTA = 1,
200
+ MULTI_KERNEL = 2,
201
+ AUTO = 100
201
202
  };
202
203
 
203
- enum class hash_mode { HASH, SMALL, AUTO };
204
+ enum class hash_mode { HASH = 0, SMALL = 1, AUTO = 100 };
204
205
 
205
206
  struct SearchParametersCagra : SearchParameters {
206
207
  /// Maximum number of queries to search at the same time (batch size). Auto
@@ -33,7 +33,8 @@
33
33
 
34
34
  #if defined USE_NVIDIA_CUVS
35
35
  #include <raft/core/device_resources.hpp>
36
- #include <rmm/mr/device/device_memory_resource.hpp>
36
+ #include <cuda/memory_resource>
37
+ #include <optional>
37
38
  #endif
38
39
 
39
40
  namespace faiss {
@@ -163,7 +164,7 @@ struct AllocRequest : public AllocInfo {
163
164
  size_t size = 0;
164
165
 
165
166
  #if defined USE_NVIDIA_CUVS
166
- rmm::mr::device_memory_resource* mr = nullptr;
167
+ std::optional<cuda::mr::any_resource<cuda::mr::device_accessible>> mr;
167
168
  #endif
168
169
  };
169
170
 
@@ -23,9 +23,9 @@
23
23
 
24
24
  #if defined USE_NVIDIA_CUVS
25
25
  #include <raft/core/device_resources.hpp>
26
- #include <rmm/mr/device/managed_memory_resource.hpp>
27
- #include <rmm/mr/device/per_device_resource.hpp>
28
- #include <rmm/mr/host/pinned_memory_resource.hpp>
26
+ #include <rmm/mr/managed_memory_resource.hpp>
27
+ #include <rmm/mr/per_device_resource.hpp>
28
+ #include <rmm/mr/pinned_host_memory_resource.hpp>
29
29
  #include <memory>
30
30
  #endif
31
31
 
@@ -92,8 +92,8 @@ std::string allocsToString(const std::unordered_map<void*, AllocRequest>& map) {
92
92
  StandardGpuResourcesImpl::StandardGpuResourcesImpl()
93
93
  :
94
94
  #if defined USE_NVIDIA_CUVS
95
- mmr_(new rmm::mr::managed_memory_resource),
96
- pmr_(new rmm::mr::pinned_memory_resource),
95
+ mmr_{},
96
+ pmr_{},
97
97
  #endif
98
98
  pinnedMemAlloc_(nullptr),
99
99
  pinnedMemAllocSize_(0),
@@ -164,7 +164,7 @@ StandardGpuResourcesImpl::~StandardGpuResourcesImpl() {
164
164
 
165
165
  if (pinnedMemAlloc_) {
166
166
  #if defined USE_NVIDIA_CUVS
167
- pmr_->deallocate(pinnedMemAlloc_, pinnedMemAllocSize_);
167
+ pmr_.deallocate_sync(pinnedMemAlloc_, pinnedMemAllocSize_);
168
168
  #else
169
169
  auto err = cudaFreeHost(pinnedMemAlloc_);
170
170
  FAISS_ASSERT_FMT(
@@ -350,7 +350,7 @@ void StandardGpuResourcesImpl::initializeForDevice(int device) {
350
350
  // pinned memory allocation
351
351
  if (defaultStreams_.empty() && pinnedMemSize_ > 0) {
352
352
  try {
353
- pinnedMemAlloc_ = pmr_->allocate(pinnedMemSize_);
353
+ pinnedMemAlloc_ = pmr_.allocate_sync(pinnedMemSize_);
354
354
  } catch (const std::bad_alloc& rmm_ex) {
355
355
  FAISS_THROW_MSG("CUDA memory allocation error");
356
356
  }
@@ -546,10 +546,9 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) {
546
546
  } else if (adjReq.space == MemorySpace::Device) {
547
547
  #if defined USE_NVIDIA_CUVS
548
548
  try {
549
- rmm::mr::device_memory_resource* current_mr =
550
- rmm::mr::get_per_device_resource(
551
- rmm::cuda_device_id{adjReq.device});
552
- p = current_mr->allocate_async(adjReq.size, adjReq.stream);
549
+ auto current_mr = rmm::mr::get_per_device_resource_ref(
550
+ rmm::cuda_device_id{adjReq.device});
551
+ p = current_mr.allocate(adjReq.stream, adjReq.size);
553
552
  adjReq.mr = current_mr;
554
553
  } catch (const std::bad_alloc& rmm_ex) {
555
554
  FAISS_THROW_MSG("CUDA memory allocation error");
@@ -562,7 +561,7 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) {
562
561
  // FIXME: as of CUDA 11, a memory allocation error appears to be
563
562
  // presented via cudaGetLastError as well, and needs to be
564
563
  // cleared. Just call the function to clear it
565
- cudaGetLastError();
564
+ (void)cudaGetLastError();
566
565
 
567
566
  std::stringstream ss;
568
567
  ss << "StandardGpuResources: alloc fail " << adjReq.toString()
@@ -584,8 +583,8 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) {
584
583
  // TODO: change this to use the current device resource once RMM has
585
584
  // a way to retrieve a "guaranteed" managed memory resource for a
586
585
  // device.
587
- p = mmr_->allocate_async(adjReq.size, adjReq.stream);
588
- adjReq.mr = mmr_.get();
586
+ p = mmr_.allocate(adjReq.stream, adjReq.size);
587
+ adjReq.mr = mmr_;
589
588
  } catch (const std::bad_alloc& rmm_ex) {
590
589
  FAISS_THROW_MSG("CUDA memory allocation error");
591
590
  }
@@ -596,7 +595,7 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) {
596
595
  // FIXME: as of CUDA 11, a memory allocation error appears to be
597
596
  // presented via cudaGetLastError as well, and needs to be cleared.
598
597
  // Just call the function to clear it
599
- cudaGetLastError();
598
+ (void)cudaGetLastError();
600
599
 
601
600
  std::stringstream ss;
602
601
  ss << "StandardGpuResources: alloc fail " << adjReq.toString()
@@ -648,7 +647,7 @@ void StandardGpuResourcesImpl::deallocMemory(int device, void* p) {
648
647
  req.space == MemorySpace::Device ||
649
648
  req.space == MemorySpace::Unified) {
650
649
  #if defined USE_NVIDIA_CUVS
651
- req.mr->deallocate_async(p, req.size, req.stream);
650
+ req.mr->deallocate(req.stream, p, req.size);
652
651
  #else
653
652
  auto err = cudaFree(p);
654
653
  FAISS_ASSERT_FMT(
@@ -25,7 +25,8 @@
25
25
 
26
26
  #if defined USE_NVIDIA_CUVS
27
27
  #include <raft/core/device_resources.hpp>
28
- #include <rmm/mr/host/pinned_memory_resource.hpp>
28
+ #include <rmm/mr/managed_memory_resource.hpp>
29
+ #include <rmm/mr/pinned_host_memory_resource.hpp>
29
30
  #endif
30
31
 
31
32
  #include <faiss/gpu/GpuResources.h>
@@ -170,10 +171,10 @@ class StandardGpuResourcesImpl : public GpuResources {
170
171
  */
171
172
 
172
173
  // managed_memory_resource
173
- std::unique_ptr<rmm::mr::device_memory_resource> mmr_;
174
+ rmm::mr::managed_memory_resource mmr_;
174
175
 
175
- // pinned_memory_resource
176
- std::unique_ptr<rmm::mr::host_memory_resource> pmr_;
176
+ // pinned_host_memory_resource
177
+ rmm::mr::pinned_host_memory_resource pmr_;
177
178
  #endif
178
179
 
179
180
  /// Pinned memory allocation for use with this GPU
@@ -11,6 +11,7 @@
11
11
  #include <faiss/gpu/impl/IndexUtils.h>
12
12
  #include <faiss/gpu/test/TestUtils.h>
13
13
  #include <faiss/gpu/utils/DeviceUtils.h>
14
+ #include <faiss/impl/IDSelector.h>
14
15
  #include <gtest/gtest.h>
15
16
  #include <sstream>
16
17
  #include <unordered_map>
@@ -761,6 +762,51 @@ TEST(TestCuvsGpuIndexFlat, SearchAndReconstruct) {
761
762
  }
762
763
  #endif
763
764
 
765
+ void testIDSelectorFlat(faiss::MetricType metricType) {
766
+ int numAdd = faiss::gpu::randVal(2000, 5000);
767
+ int dim = faiss::gpu::randVal(64, 200);
768
+ int numQuery = faiss::gpu::randVal(32, 100);
769
+ int k = faiss::gpu::randVal(10, 30);
770
+ int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
771
+
772
+ faiss::gpu::StandardGpuResources res;
773
+ res.noTempMemory();
774
+
775
+ auto queryVecs = faiss::gpu::randVecs(numQuery, dim);
776
+ faiss::gpu::GpuIndexFlatConfig config;
777
+ config.device = device;
778
+ config.use_cuvs = true;
779
+ for (bool useFloat16 : {false, true}) {
780
+ config.useFloat16 = useFloat16;
781
+ faiss::gpu::GpuIndexFlat gpuIndex(&res, dim, metricType, config);
782
+ std::vector<float> addVecs = faiss::gpu::randVecs(numAdd, dim);
783
+ gpuIndex.add(numAdd, addVecs.data());
784
+
785
+ faiss::gpu::TestIDSelectorStruct selector_struct(numAdd);
786
+ faiss::SearchParameters search_params;
787
+ for (auto& [selectorName, selector] : selector_struct.selector_map) {
788
+ search_params.sel = selector.get();
789
+ faiss::gpu::testIDSelectorSearch(
790
+ &gpuIndex,
791
+ &search_params,
792
+ queryVecs,
793
+ numQuery,
794
+ k,
795
+ selectorName);
796
+ }
797
+ }
798
+ }
799
+
800
+ #if defined USE_NVIDIA_CUVS
801
+ TEST(TestCuvsGpuIndexFlat, IDSelector_L2) {
802
+ testIDSelectorFlat(faiss::METRIC_L2);
803
+ }
804
+
805
+ TEST(TestCuvsGpuIndexFlat, IDSelector_IP) {
806
+ testIDSelectorFlat(faiss::METRIC_INNER_PRODUCT);
807
+ }
808
+ #endif
809
+
764
810
  int main(int argc, char** argv) {
765
811
  testing::InitGoogleTest(&argc, argv);
766
812
 
@@ -28,6 +28,8 @@
28
28
  #include <faiss/gpu/StandardGpuResources.h>
29
29
  #include <faiss/gpu/test/TestUtils.h>
30
30
  #include <faiss/gpu/utils/DeviceUtils.h>
31
+ #include <faiss/impl/IDSelector.h>
32
+ #include <faiss/utils/distances.h>
31
33
  #include <gtest/gtest.h>
32
34
  #include <cmath>
33
35
  #include <sstream>
@@ -354,6 +356,11 @@ TEST(TestGpuIndexIVFFlat, Float32_Query_IP) {
354
356
  }
355
357
 
356
358
  TEST(TestGpuIndexIVFFlat, LargeBatch) {
359
+ // With low-dim vectors, CPU will use non-BLAS. Force the CPU to use
360
+ // the BLAS for consistent comparison.
361
+ int saved_threshold = faiss::distance_compute_blas_threshold;
362
+ faiss::distance_compute_blas_threshold = 1;
363
+
357
364
  Options opt;
358
365
  opt.dim = 3;
359
366
  opt.numQuery = 100000;
@@ -364,6 +371,8 @@ TEST(TestGpuIndexIVFFlat, LargeBatch) {
364
371
  opt.indicesOpt = faiss::gpu::INDICES_64_BIT;
365
372
  queryTest(opt, faiss::METRIC_L2, false);
366
373
  #endif
374
+
375
+ faiss::distance_compute_blas_threshold = saved_threshold;
367
376
  }
368
377
 
369
378
  // float16 coarse quantizer
@@ -909,6 +918,53 @@ TEST(TestGpuIndexIVFFlat, Reconstruct_n) {
909
918
  EXPECT_EQ(gpuVals, cpuVals);
910
919
  }
911
920
 
921
+ void testIDSelectorIVFFlat(faiss::MetricType metricType) {
922
+ Options opt;
923
+
924
+ std::vector<float> trainVecs = faiss::gpu::randVecs(opt.numTrain, opt.dim);
925
+ std::vector<float> addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim);
926
+
927
+ faiss::gpu::StandardGpuResources res;
928
+ res.noTempMemory();
929
+
930
+ faiss::gpu::GpuIndexIVFFlatConfig config;
931
+ config.device = opt.device;
932
+ config.indicesOptions = faiss::gpu::INDICES_64_BIT;
933
+ config.use_cuvs = true;
934
+
935
+ faiss::gpu::GpuIndexIVFFlat gpuIndex(
936
+ &res, opt.dim, opt.numCentroids, metricType, config);
937
+ gpuIndex.nprobe = opt.nprobe;
938
+
939
+ gpuIndex.train(opt.numTrain, trainVecs.data());
940
+ gpuIndex.add(opt.numAdd, addVecs.data());
941
+
942
+ auto queryVecs = faiss::gpu::randVecs(opt.numQuery, opt.dim);
943
+ faiss::gpu::TestIDSelectorStruct selector_struct(opt.numAdd);
944
+ faiss::SearchParametersIVF search_params;
945
+ search_params.nprobe = opt.nprobe;
946
+ for (auto& [selectorName, selector] : selector_struct.selector_map) {
947
+ search_params.sel = selector.get();
948
+ faiss::gpu::testIDSelectorSearch(
949
+ &gpuIndex,
950
+ &search_params,
951
+ queryVecs,
952
+ opt.numQuery,
953
+ opt.k,
954
+ selectorName);
955
+ }
956
+ }
957
+
958
+ #if defined USE_NVIDIA_CUVS
959
+ TEST(TestCuvsGpuIndexIVFFlat, IDSelector_L2) {
960
+ testIDSelectorIVFFlat(faiss::METRIC_L2);
961
+ }
962
+
963
+ TEST(TestCuvsGpuIndexIVFFlat, IDSelector_IP) {
964
+ testIDSelectorIVFFlat(faiss::METRIC_INNER_PRODUCT);
965
+ }
966
+ #endif
967
+
912
968
  int main(int argc, char** argv) {
913
969
  testing::InitGoogleTest(&argc, argv);
914
970
 
@@ -6,11 +6,14 @@
6
6
  */
7
7
 
8
8
  #include <faiss/IndexFlat.h>
9
+ #include <faiss/IndexIVF.h>
9
10
  #include <faiss/IndexIVFPQ.h>
10
11
  #include <faiss/gpu/GpuIndexIVFPQ.h>
11
12
  #include <faiss/gpu/StandardGpuResources.h>
12
13
  #include <faiss/gpu/test/TestUtils.h>
13
14
  #include <faiss/gpu/utils/DeviceUtils.h>
15
+ #include <faiss/impl/IDSelector.h>
16
+ #include <faiss/utils/distances.h>
14
17
  #include <gtest/gtest.h>
15
18
  #include <cmath>
16
19
  #include <sstream>
@@ -101,7 +104,11 @@ struct Options {
101
104
  }
102
105
 
103
106
  float getCompareEpsilon() const {
104
- return 0.035f;
107
+ // With very low dimensionality (e.g., dim=4, codes=2 giving
108
+ // dimPerSubQuantizer=2), L2 distances can be very small
109
+ // (near-zero), causing relative error comparisons to be
110
+ // unstable despite tiny absolute differences.
111
+ return (dim <= 8) ? 0.15f : 0.035f;
105
112
  }
106
113
 
107
114
  float getPctMaxDiff1() const {
@@ -190,6 +197,11 @@ TEST(TestGpuIndexIVFPQ, Query_IP) {
190
197
 
191
198
  // Large batch sizes (>= 65536) should also work
192
199
  TEST(TestGpuIndexIVFPQ, LargeBatch) {
200
+ // With low-dim vectors, CPU will use non-BLAS. Force the CPU to use
201
+ // the BLAS for consistent comparison.
202
+ int saved_threshold = faiss::distance_compute_blas_threshold;
203
+ faiss::distance_compute_blas_threshold = 1;
204
+
193
205
  for (bool usePrecomputed : {false, true}) {
194
206
  Options opt;
195
207
 
@@ -202,6 +214,8 @@ TEST(TestGpuIndexIVFPQ, LargeBatch) {
202
214
 
203
215
  queryTest(opt, faiss::MetricType::METRIC_L2);
204
216
  }
217
+
218
+ faiss::distance_compute_blas_threshold = saved_threshold;
205
219
  }
206
220
 
207
221
  void testMMCodeDistance(faiss::MetricType mt) {
@@ -697,6 +711,11 @@ TEST(TestGpuIndexIVFPQ, Query_IP_Cuvs) {
697
711
 
698
712
  // Large batch sizes (>= 65536) should also work
699
713
  TEST(TestGpuIndexIVFPQ, LargeBatch_Cuvs) {
714
+ // See LargeBatch comment: force CPU BLAS path to match GPU GEMM
715
+ // decomposition for consistent L2 distance computation.
716
+ int saved_threshold = faiss::distance_compute_blas_threshold;
717
+ faiss::distance_compute_blas_threshold = 1;
718
+
700
719
  Options opt;
701
720
 
702
721
  // override for large sizes
@@ -711,6 +730,8 @@ TEST(TestGpuIndexIVFPQ, LargeBatch_Cuvs) {
711
730
  opt.bitsPerCode = 8;
712
731
 
713
732
  queryTest(opt, faiss::MetricType::METRIC_L2);
733
+
734
+ faiss::distance_compute_blas_threshold = saved_threshold;
714
735
  }
715
736
 
716
737
  TEST(TestGpuIndexIVFPQ, CopyFrom_Cuvs) {
@@ -877,6 +898,62 @@ TEST(TestGpuIndexIVFPQ, UnifiedMemory) {
877
898
  #endif
878
899
  }
879
900
 
901
+ void testIDSelectorIVFPQ(faiss::MetricType metricType) {
902
+ Options opt;
903
+
904
+ std::vector<float> trainVecs = faiss::gpu::randVecs(opt.numTrain, opt.dim);
905
+ std::vector<float> addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim);
906
+
907
+ faiss::IndexFlatL2 quantizerL2(opt.dim);
908
+ faiss::IndexFlatIP quantizerIP(opt.dim);
909
+ faiss::Index* quantizer = metricType == faiss::METRIC_L2
910
+ ? (faiss::Index*)&quantizerL2
911
+ : (faiss::Index*)&quantizerIP;
912
+
913
+ faiss::IndexIVFPQ cpuIndex(
914
+ quantizer, opt.dim, opt.numCentroids, opt.codes, opt.bitsPerCode);
915
+ cpuIndex.metric_type = metricType;
916
+ cpuIndex.train(opt.numTrain, trainVecs.data());
917
+ cpuIndex.add(opt.numAdd, addVecs.data());
918
+
919
+ faiss::gpu::StandardGpuResources res;
920
+ res.noTempMemory();
921
+
922
+ faiss::gpu::GpuIndexIVFPQConfig config;
923
+ config.device = opt.device;
924
+ config.indicesOptions = faiss::gpu::INDICES_64_BIT;
925
+ config.interleavedLayout = true;
926
+ config.use_cuvs = true;
927
+
928
+ faiss::gpu::GpuIndexIVFPQ gpuIndex(&res, &cpuIndex, config);
929
+ gpuIndex.nprobe = opt.nprobe;
930
+
931
+ auto queryVecs = faiss::gpu::randVecs(opt.numQuery, opt.dim);
932
+ faiss::gpu::TestIDSelectorStruct selector_struct(opt.numAdd);
933
+ faiss::SearchParametersIVF search_params;
934
+ search_params.nprobe = opt.nprobe;
935
+ for (auto& [selectorName, selector] : selector_struct.selector_map) {
936
+ search_params.sel = selector.get();
937
+ faiss::gpu::testIDSelectorSearch(
938
+ &gpuIndex,
939
+ &search_params,
940
+ queryVecs,
941
+ opt.numQuery,
942
+ opt.k,
943
+ selectorName);
944
+ }
945
+ }
946
+
947
+ #if defined USE_NVIDIA_CUVS
948
+ TEST(TestCuvsGpuIndexIVFPQ, IDSelector_L2) {
949
+ testIDSelectorIVFPQ(faiss::METRIC_L2);
950
+ }
951
+
952
+ TEST(TestCuvsGpuIndexIVFPQ, IDSelector_IP) {
953
+ testIDSelectorIVFPQ(faiss::METRIC_INNER_PRODUCT);
954
+ }
955
+ #endif
956
+
880
957
  int main(int argc, char** argv) {
881
958
  testing::InitGoogleTest(&argc, argv);
882
959
 
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  #include <faiss/gpu/test/TestUtils.h>
9
+ #include <faiss/impl/IDSelector.h>
9
10
  #include <faiss/utils/random.h>
10
11
  #include <gtest/gtest.h>
11
12
  #include <time.h>
@@ -429,5 +430,76 @@ void compareLists(
429
430
  }
430
431
  }
431
432
 
433
+ TestIDSelectorStruct::TestIDSelectorStruct(int numAdd) {
434
+ // Range selector [20%, 80%] of the database
435
+ size_t min_id = numAdd / 5;
436
+ size_t max_id = numAdd * 4 / 5;
437
+ selector_map["Range"] =
438
+ std::make_unique<faiss::IDSelectorRange>(min_id, max_id);
439
+
440
+ // Array selector (every 3rd element)
441
+ array_ids.clear();
442
+ for (int i = 0; i < numAdd; i += 3) {
443
+ array_ids.push_back(i);
444
+ }
445
+ selector_map["Array"] = std::make_unique<faiss::IDSelectorArray>(
446
+ array_ids.size(), array_ids.data());
447
+
448
+ // Batch selector (every 5th element)
449
+ batch_ids.clear();
450
+ for (int i = 1; i < numAdd; i += 5) {
451
+ batch_ids.push_back(i);
452
+ }
453
+ selector_map["Batch"] = std::make_unique<faiss::IDSelectorBatch>(
454
+ batch_ids.size(), batch_ids.data());
455
+
456
+ // Bitmap selector (every 4th element selected)
457
+ size_t bitmap_size = (numAdd + 7) / 8;
458
+ bitmap.resize(bitmap_size, 0);
459
+ for (int i = 0; i < numAdd; i += 4) {
460
+ int byte_idx = i / 8;
461
+ int bit_idx = i % 8;
462
+ bitmap[byte_idx] |= (1 << bit_idx);
463
+ }
464
+ selector_map["Bitmap"] =
465
+ std::make_unique<faiss::IDSelectorBitmap>(numAdd, bitmap.data());
466
+
467
+ selector_map["Not"] =
468
+ std::make_unique<faiss::IDSelectorNot>(selector_map["Range"].get());
469
+ selector_map["And"] = std::make_unique<faiss::IDSelectorAnd>(
470
+ selector_map["Range"].get(), selector_map["Array"].get());
471
+ selector_map["Or"] = std::make_unique<faiss::IDSelectorOr>(
472
+ selector_map["Range"].get(), selector_map["Batch"].get());
473
+ selector_map["XOr"] = std::make_unique<faiss::IDSelectorXOr>(
474
+ selector_map["Not"].get(), selector_map["Array"].get());
475
+ }
476
+
477
+ void testIDSelectorSearch(
478
+ faiss::Index* index,
479
+ faiss::SearchParameters* search_params,
480
+ const std::vector<float>& queryVecs,
481
+ int numQuery,
482
+ int k,
483
+ const std::string& selectorName) {
484
+ FAISS_ASSERT(search_params && search_params->sel);
485
+ std::vector<float> distances(numQuery * k, 0);
486
+ std::vector<faiss::idx_t> labels(numQuery * k, -1);
487
+ index->search(
488
+ numQuery,
489
+ queryVecs.data(),
490
+ k,
491
+ distances.data(),
492
+ labels.data(),
493
+ search_params);
494
+ faiss::IDSelector* selector = search_params->sel;
495
+ for (int i = 0; i < numQuery * k; ++i) {
496
+ if (labels[i] >= 0) {
497
+ EXPECT_TRUE(selector->is_member(labels[i]))
498
+ << "Label " << labels[i] << " @ " << i << " not in "
499
+ << selectorName << " selector";
500
+ }
501
+ }
502
+ }
503
+
432
504
  } // namespace gpu
433
505
  } // namespace faiss
@@ -13,6 +13,7 @@
13
13
  #include <gtest/gtest.h>
14
14
  #include <cstring>
15
15
  #include <initializer_list>
16
+ #include <map>
16
17
  #include <memory>
17
18
  #include <string>
18
19
  #include <vector>
@@ -141,5 +142,27 @@ void testIVFEquality(A& cpuIndex, B& gpuIndex) {
141
142
  }
142
143
  }
143
144
 
145
+ /// Run search with the given search_params and verify all returned labels are
146
+ /// members of the selector. Works with any Index that supports search with
147
+ /// SearchParameters.
148
+ void testIDSelectorSearch(
149
+ faiss::Index* index,
150
+ faiss::SearchParameters* search_params,
151
+ const std::vector<float>& queryVecs,
152
+ int numQuery,
153
+ int k,
154
+ const std::string& selectorName);
155
+
156
+ // Structure to hold all IDSelector instances
157
+ struct TestIDSelectorStruct {
158
+ // Storage for selectors that need it
159
+ std::vector<faiss::idx_t> array_ids;
160
+ std::vector<faiss::idx_t> batch_ids;
161
+ std::vector<uint8_t> bitmap;
162
+ std::map<std::string, std::unique_ptr<faiss::IDSelector>> selector_map;
163
+
164
+ explicit TestIDSelectorStruct(int numAdd);
165
+ };
166
+
144
167
  } // namespace gpu
145
168
  } // namespace faiss
@@ -36,6 +36,6 @@ namespace faiss::gpu {
36
36
  void convert_to_bitset(
37
37
  faiss::gpu::GpuResources* res,
38
38
  const faiss::IDSelector& selector,
39
- cuvs::core::bitset_view<uint32_t, uint32_t> bitset,
39
+ cuvs::core::bitset_view<uint32_t, int64_t> bitset,
40
40
  int num_threads = 0);
41
41
  } // namespace faiss::gpu
@@ -27,32 +27,32 @@
27
27
  #include <faiss/gpu/GpuResources.h>
28
28
  #include <faiss/gpu/utils/Tensor.cuh>
29
29
 
30
- #include <cuvs/distance/distance.h>
30
+ #include <cuvs/distance/distance.hpp>
31
31
 
32
32
  #pragma GCC visibility push(default)
33
33
  namespace faiss {
34
34
  namespace gpu {
35
35
 
36
- inline cuvsDistanceType metricFaissToCuvs(
36
+ inline cuvs::distance::DistanceType metricFaissToCuvs(
37
37
  MetricType metric,
38
38
  bool exactDistance) {
39
39
  switch (metric) {
40
40
  case MetricType::METRIC_INNER_PRODUCT:
41
- return cuvsDistanceType::InnerProduct;
41
+ return cuvs::distance::DistanceType::InnerProduct;
42
42
  case MetricType::METRIC_L2:
43
- return cuvsDistanceType::L2Expanded;
43
+ return cuvs::distance::DistanceType::L2Expanded;
44
44
  case MetricType::METRIC_L1:
45
- return cuvsDistanceType::L1;
45
+ return cuvs::distance::DistanceType::L1;
46
46
  case MetricType::METRIC_Linf:
47
- return cuvsDistanceType::Linf;
47
+ return cuvs::distance::DistanceType::Linf;
48
48
  case MetricType::METRIC_Lp:
49
- return cuvsDistanceType::LpUnexpanded;
49
+ return cuvs::distance::DistanceType::LpUnexpanded;
50
50
  case MetricType::METRIC_Canberra:
51
- return cuvsDistanceType::Canberra;
51
+ return cuvs::distance::DistanceType::Canberra;
52
52
  case MetricType::METRIC_BrayCurtis:
53
- return cuvsDistanceType::BrayCurtis;
53
+ return cuvs::distance::DistanceType::BrayCurtis;
54
54
  case MetricType::METRIC_JensenShannon:
55
- return cuvsDistanceType::JensenShannon;
55
+ return cuvs::distance::DistanceType::JensenShannon;
56
56
  default:
57
57
  RAFT_FAIL("Distance type not supported");
58
58
  }
@@ -71,6 +71,17 @@ idx_t inplaceGatherFilteredRows(
71
71
  GpuResources* res,
72
72
  Tensor<float, 2, true>& vecs,
73
73
  Tensor<idx_t, 1, true>& indices);
74
+
75
+ /// Copy uint32_t indices to idx_t, replacing any index >= n with -1.
76
+ /// cuVS CAGRA returns sentinel values (e.g. INT32_MAX) for result slots
77
+ /// where filtered search couldn't find a valid neighbor.
78
+ void sanitizeCuvsIndices(
79
+ GpuResources* res,
80
+ uint32_t* src,
81
+ idx_t* dst,
82
+ size_t count,
83
+ idx_t n);
84
+
74
85
  } // namespace gpu
75
86
  } // namespace faiss
76
87
  #pragma GCC visibility pop
@@ -0,0 +1,22 @@
1
+ // @lint-ignore-every LICENSELINT
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and its affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * Unified name for flat GPU index when Metal backend is built.
9
+ * Include this when using the Metal backend for API parity with
10
+ * faiss::gpu::GpuIndexFlat.
11
+ */
12
+
13
+ #pragma once
14
+
15
+ #include <faiss/gpu_metal/MetalIndexFlat.h>
16
+
17
+ namespace faiss {
18
+
19
+ /// When FAISS is built with Metal backend, GpuIndexFlat is MetalIndexFlat.
20
+ using GpuIndexFlat = gpu_metal::MetalIndexFlat;
21
+
22
+ } // namespace faiss