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
@@ -0,0 +1,225 @@
1
+ /*
2
+ * Portions Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ /*
9
+ * Portions Copyright 2026 Intel Corporation
10
+ *
11
+ * Licensed under the Apache License, Version 2.0 (the "License");
12
+ * you may not use this file except in compliance with the License.
13
+ * You may obtain a copy of the License at
14
+ *
15
+ * http://www.apache.org/licenses/LICENSE-2.0
16
+ *
17
+ * Unless required by applicable law or agreed to in writing, software
18
+ * distributed under the License is distributed on an "AS IS" BASIS,
19
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ * See the License for the specific language governing permissions and
21
+ * limitations under the License.
22
+ */
23
+
24
+ #include <faiss/svs/IndexSVSFaissUtils.h>
25
+ #include <faiss/svs/IndexSVSIVFLeanVec.h>
26
+
27
+ #include <svs/runtime/dynamic_ivf_index.h>
28
+ #include <svs/runtime/ivf_index.h>
29
+ #include <svs/runtime/training.h>
30
+
31
+ #include <memory>
32
+ #include <numeric>
33
+
34
+ namespace faiss {
35
+
36
+ IndexSVSIVFLeanVec::IndexSVSIVFLeanVec() : IndexSVSIVF() {
37
+ is_trained = false;
38
+ storage_kind = SVSStorageKind::SVS_LeanVec4x4;
39
+ }
40
+
41
+ IndexSVSIVFLeanVec::IndexSVSIVFLeanVec(
42
+ idx_t d,
43
+ size_t nlist,
44
+ MetricType metric,
45
+ size_t leanvec_dims,
46
+ SVSStorageKind storage_kind,
47
+ bool is_static)
48
+ : IndexSVSIVF(d, nlist, metric, storage_kind, is_static) {
49
+ is_trained = false;
50
+ leanvec_d = leanvec_dims == 0 ? d / 2 : leanvec_dims;
51
+ }
52
+
53
+ IndexSVSIVFLeanVec::~IndexSVSIVFLeanVec() {
54
+ if (training_data) {
55
+ auto status = svs_runtime::LeanVecTrainingData::destroy(training_data);
56
+ FAISS_ASSERT(status.ok());
57
+ training_data = nullptr;
58
+ }
59
+ // Base class destructor handles impl cleanup
60
+ }
61
+
62
+ void IndexSVSIVFLeanVec::train(idx_t n, const float* x) {
63
+ train_with_queries(n, x, 0, nullptr);
64
+ }
65
+
66
+ void IndexSVSIVFLeanVec::train_with_queries(
67
+ idx_t n,
68
+ const float* x,
69
+ idx_t n_train_q,
70
+ const float* xq_train) {
71
+ FAISS_THROW_IF_MSG(
72
+ training_data || impl, "Index already trained or contains data.");
73
+
74
+ FAISS_THROW_IF_NOT_MSG(
75
+ IndexSVSIVF::is_lvq_leanvec_enabled(),
76
+ "LVQ/LeanVec support not available on this platform or build");
77
+
78
+ // Build LeanVec training data
79
+ auto status = svs_runtime::LeanVecTrainingData::build(
80
+ &training_data, d, n, x, n_train_q, xq_train, leanvec_d);
81
+ if (!status.ok()) {
82
+ FAISS_THROW_MSG(status.message());
83
+ }
84
+ FAISS_THROW_IF_NOT_MSG(
85
+ training_data, "Failed to build leanvec training info.");
86
+
87
+ // Now build the IVF index with the training data
88
+ create_impl(n, x);
89
+ is_trained = true;
90
+ }
91
+
92
+ void IndexSVSIVFLeanVec::reset() {
93
+ if (training_data) {
94
+ auto status = svs_runtime::LeanVecTrainingData::destroy(training_data);
95
+ FAISS_ASSERT(status.ok());
96
+ training_data = nullptr;
97
+ }
98
+ IndexSVSIVF::reset();
99
+ }
100
+
101
+ void IndexSVSIVFLeanVec::serialize_training_data(std::ostream& out) const {
102
+ FAISS_THROW_IF_NOT_MSG(
103
+ training_data, "Cannot serialize: Training data not initialized.");
104
+
105
+ auto status = training_data->save(out);
106
+ if (!status.ok()) {
107
+ FAISS_THROW_MSG(status.message());
108
+ }
109
+ }
110
+
111
+ void IndexSVSIVFLeanVec::deserialize_training_data(std::istream& in) {
112
+ svs_runtime::LeanVecTrainingData* tdata = nullptr;
113
+ auto status = svs_runtime::LeanVecTrainingData::load(&tdata, in);
114
+ if (!status.ok()) {
115
+ FAISS_THROW_MSG(status.message());
116
+ }
117
+ FAISS_THROW_IF_NOT_MSG(tdata, "Failed to load leanvec training data.");
118
+ training_data = tdata;
119
+ }
120
+
121
+ void IndexSVSIVFLeanVec::create_impl(idx_t n, const float* x) {
122
+ FAISS_THROW_IF_NOT(!impl);
123
+ ntotal = 0;
124
+ auto svs_metric = to_svs_metric(metric_type);
125
+ auto svs_storage_kind = to_svs_storage_kind(storage_kind);
126
+ auto build_params = svs_runtime::IVFIndex::BuildParams{
127
+ .num_centroids = num_centroids,
128
+ .minibatch_size = minibatch_size,
129
+ .num_iterations = num_iterations,
130
+ .is_hierarchical = is_hierarchical,
131
+ .training_fraction = training_fraction,
132
+ .hierarchical_level1_clusters = hierarchical_level1_clusters,
133
+ .seed = seed,
134
+ };
135
+ auto search_params = svs_runtime::IVFIndex::SearchParams{
136
+ .n_probes = n_probes,
137
+ .k_reorder = k_reorder,
138
+ };
139
+
140
+ auto status = svs_runtime::Status_Ok;
141
+ if (is_static) {
142
+ if (training_data) {
143
+ status = svs_runtime::IVFIndexLeanVec::build(
144
+ &impl,
145
+ d,
146
+ svs_metric,
147
+ svs_storage_kind,
148
+ static_cast<size_t>(n),
149
+ x,
150
+ training_data,
151
+ build_params,
152
+ search_params,
153
+ num_threads,
154
+ intra_query_threads);
155
+ } else {
156
+ status = svs_runtime::IVFIndexLeanVec::build(
157
+ &impl,
158
+ d,
159
+ svs_metric,
160
+ svs_storage_kind,
161
+ static_cast<size_t>(n),
162
+ x,
163
+ leanvec_d,
164
+ build_params,
165
+ search_params,
166
+ num_threads,
167
+ intra_query_threads);
168
+ }
169
+ } else {
170
+ std::vector<size_t> labels(n);
171
+ std::iota(labels.begin(), labels.end(), 0);
172
+
173
+ svs_runtime::DynamicIVFIndex* dyn_impl = nullptr;
174
+ if (training_data) {
175
+ status = svs_runtime::DynamicIVFIndexLeanVec::build(
176
+ &dyn_impl,
177
+ d,
178
+ svs_metric,
179
+ svs_storage_kind,
180
+ static_cast<size_t>(n),
181
+ x,
182
+ labels.data(),
183
+ training_data,
184
+ build_params,
185
+ search_params,
186
+ num_threads,
187
+ intra_query_threads);
188
+ } else {
189
+ status = svs_runtime::DynamicIVFIndexLeanVec::build(
190
+ &dyn_impl,
191
+ d,
192
+ svs_metric,
193
+ svs_storage_kind,
194
+ static_cast<size_t>(n),
195
+ x,
196
+ labels.data(),
197
+ leanvec_d,
198
+ build_params,
199
+ search_params,
200
+ num_threads,
201
+ intra_query_threads);
202
+ }
203
+ impl = dyn_impl;
204
+ }
205
+
206
+ if (!status.ok()) {
207
+ FAISS_THROW_MSG(status.message());
208
+ }
209
+ FAISS_THROW_IF_NOT(impl);
210
+
211
+ // Force reinitialization of SVS search infrastructure after build.
212
+ // Same workaround as in IndexSVSIVF::create_impl — the move chain through
213
+ // the orchestrator wrappers can leave matmul_results_ inconsistent
214
+ // when threads > centroids.
215
+ size_t current_threads = 0;
216
+ impl->get_num_threads(&current_threads);
217
+ auto st = impl->set_num_threads(current_threads);
218
+ if (!st.ok()) {
219
+ FAISS_THROW_MSG(st.message());
220
+ }
221
+
222
+ ntotal = n;
223
+ }
224
+
225
+ } // namespace faiss
@@ -0,0 +1,71 @@
1
+ /*
2
+ * Portions Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ /*
9
+ * Portions Copyright 2026 Intel Corporation
10
+ *
11
+ * Licensed under the Apache License, Version 2.0 (the "License");
12
+ * you may not use this file except in compliance with the License.
13
+ * You may obtain a copy of the License at
14
+ *
15
+ * http://www.apache.org/licenses/LICENSE-2.0
16
+ *
17
+ * Unless required by applicable law or agreed to in writing, software
18
+ * distributed under the License is distributed on an "AS IS" BASIS,
19
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ * See the License for the specific language governing permissions and
21
+ * limitations under the License.
22
+ */
23
+
24
+ #pragma once
25
+
26
+ #include <faiss/svs/IndexSVSIVF.h>
27
+
28
+ namespace faiss {
29
+
30
+ struct IndexSVSIVFLeanVec : IndexSVSIVF {
31
+ IndexSVSIVFLeanVec();
32
+
33
+ IndexSVSIVFLeanVec(
34
+ idx_t d,
35
+ size_t nlist,
36
+ MetricType metric = METRIC_L2,
37
+ size_t leanvec_dims = 0,
38
+ SVSStorageKind storage = SVSStorageKind::SVS_LeanVec4x4,
39
+ bool is_static = false);
40
+
41
+ ~IndexSVSIVFLeanVec() override;
42
+
43
+ /* Default train assumes in-distribution data */
44
+ void train(idx_t n, const float* x) override;
45
+
46
+ /* Generic train with out-of-distribution parameters.
47
+ * Out-of-distribution (OOD) means database vectors and queries _can_ be
48
+ * sampled from different distributions (e.g., cross-modal). More details in
49
+ * the original publication, arXiv:2312.16335.
50
+ */
51
+ void train_with_queries(
52
+ idx_t n,
53
+ const float* x,
54
+ idx_t n_train_q,
55
+ const float* xq_train) override;
56
+
57
+ void reset() override;
58
+
59
+ void serialize_training_data(std::ostream& out) const;
60
+ void deserialize_training_data(std::istream& in);
61
+
62
+ size_t leanvec_d = 0;
63
+
64
+ /* Training information */
65
+ svs_runtime::LeanVecTrainingData* training_data{nullptr};
66
+
67
+ protected:
68
+ void create_impl(idx_t n, const float* x) override;
69
+ };
70
+
71
+ } // namespace faiss
@@ -31,6 +31,7 @@
31
31
  #include <svs/runtime/vamana_index.h>
32
32
 
33
33
  #include <cstddef>
34
+ #include <cstring>
34
35
  #include <numeric>
35
36
  #include <span>
36
37
  #include <type_traits>
@@ -64,8 +65,12 @@ IndexSVSVamana::IndexSVSVamana(
64
65
  idx_t d,
65
66
  size_t degree,
66
67
  MetricType metric,
67
- SVSStorageKind storage)
68
- : Index(d, metric), graph_max_degree{degree}, storage_kind{storage} {
68
+ SVSStorageKind storage,
69
+ bool is_static)
70
+ : Index(d, metric),
71
+ graph_max_degree{degree},
72
+ is_static{is_static},
73
+ storage_kind{storage} {
69
74
  prune_to = graph_max_degree < 4 ? graph_max_degree : graph_max_degree - 4;
70
75
  alpha = metric == METRIC_L2 ? 1.2f : 0.95f;
71
76
 
@@ -73,8 +78,9 @@ IndexSVSVamana::IndexSVSVamana(
73
78
  // NB: LVQ/LeanVec are only available on Intel(R) hardware AND when using
74
79
  // a build based on LVQ/LeanVec-enabled SVS.
75
80
  auto svs_storage = to_svs_storage_kind(storage_kind);
76
- auto status =
77
- svs_runtime::DynamicVamanaIndex::check_storage_kind(svs_storage);
81
+ auto status = is_static
82
+ ? svs_runtime::VamanaIndex::check_storage_kind(svs_storage)
83
+ : svs_runtime::DynamicVamanaIndex::check_storage_kind(svs_storage);
78
84
  if (!status.ok()) {
79
85
  FAISS_THROW_MSG(status.message());
80
86
  }
@@ -82,11 +88,19 @@ IndexSVSVamana::IndexSVSVamana(
82
88
 
83
89
  bool IndexSVSVamana::is_lvq_leanvec_enabled() {
84
90
  auto lvq = to_svs_storage_kind(SVS_LVQ4x0);
85
- auto status = svs_runtime::DynamicVamanaIndex::check_storage_kind(lvq);
91
+ auto status = svs_runtime::VamanaIndex::check_storage_kind(lvq);
92
+ if (!status.ok()) {
93
+ return false;
94
+ }
95
+ status = svs_runtime::DynamicVamanaIndex::check_storage_kind(lvq);
86
96
  if (!status.ok()) {
87
97
  return false;
88
98
  }
89
99
  auto leanvec = to_svs_storage_kind(SVS_LeanVec4x4);
100
+ status = svs_runtime::VamanaIndex::check_storage_kind(leanvec);
101
+ if (!status.ok()) {
102
+ return false;
103
+ }
90
104
  status = svs_runtime::DynamicVamanaIndex::check_storage_kind(leanvec);
91
105
  if (!status.ok()) {
92
106
  return false;
@@ -96,31 +110,83 @@ bool IndexSVSVamana::is_lvq_leanvec_enabled() {
96
110
 
97
111
  IndexSVSVamana::~IndexSVSVamana() {
98
112
  if (impl) {
99
- auto status = svs_runtime::DynamicVamanaIndex::destroy(impl);
113
+ svs_runtime::Status status;
114
+ if (is_static) {
115
+ status = svs_runtime::VamanaIndex::destroy(impl);
116
+ } else {
117
+ status = svs_runtime::DynamicVamanaIndex::destroy(
118
+ static_cast<svs_runtime::DynamicVamanaIndex*>(impl));
119
+ }
100
120
  FAISS_ASSERT(status.ok());
101
121
  impl = nullptr;
102
122
  }
103
123
  }
104
124
 
105
125
  void IndexSVSVamana::add(idx_t n, const float* x) {
126
+ if (is_static) {
127
+ FAISS_THROW_IF_MSG(
128
+ impl,
129
+ "Static Vamana index does not support add() after initial "
130
+ "build. All data must be provided in a single add() call.");
131
+ create_impl(n, x);
132
+ if (stored_vectors_valid) {
133
+ stored_vectors.resize(static_cast<size_t>(n) * d);
134
+ std::memcpy(stored_vectors.data(), x, sizeof(float) * n * d);
135
+ }
136
+ ntotal = n;
137
+ is_trained = true;
138
+ return;
139
+ }
140
+
106
141
  if (!impl) {
107
- create_impl();
142
+ create_impl(0, nullptr);
108
143
  }
109
144
 
110
145
  std::vector<size_t> labels(n);
111
146
  std::iota(labels.begin(), labels.end(), ntotal);
112
147
 
113
- auto status = impl->add(n, labels.data(), x);
148
+ auto* dyn = dynamic_impl();
149
+ auto status = dyn->add(n, labels.data(), x);
114
150
  if (!status.ok()) {
115
151
  FAISS_THROW_MSG(status.message());
116
152
  }
153
+
154
+ if (stored_vectors_valid) {
155
+ size_t prev = static_cast<size_t>(ntotal) * d;
156
+ stored_vectors.resize(prev + static_cast<size_t>(n) * d);
157
+ std::memcpy(stored_vectors.data() + prev, x, sizeof(float) * n * d);
158
+ }
117
159
  ntotal += n;
118
160
  }
119
161
 
162
+ void IndexSVSVamana::reconstruct(idx_t key, float* recons) const {
163
+ FAISS_THROW_IF_NOT_MSG(
164
+ key >= 0 && key < ntotal,
165
+ "IndexSVSVamana::reconstruct: key out of range");
166
+ FAISS_THROW_IF_NOT_MSG(
167
+ stored_vectors_valid && !stored_vectors.empty(),
168
+ "IndexSVSVamana::reconstruct: stored_vectors unavailable "
169
+ "(invalidated by remove_ids or not restored after deserialization)");
170
+ std::memcpy(recons, stored_vectors.data() + key * d, sizeof(float) * d);
171
+ }
172
+
120
173
  void IndexSVSVamana::reset() {
121
174
  if (impl) {
122
- impl->reset();
175
+ if (is_static) {
176
+ // Static index: destroy the impl so the next add() rebuilds from
177
+ // scratch. The static SVS backend has no in-place reset that
178
+ // permits a follow-up add().
179
+ auto status = svs_runtime::VamanaIndex::destroy(impl);
180
+ FAISS_ASSERT(status.ok());
181
+ impl = nullptr;
182
+ } else {
183
+ // Dynamic index: in-place reset preserves the impl and avoids
184
+ // tearing down its allocated state.
185
+ impl->reset();
186
+ }
123
187
  }
188
+ stored_vectors.clear();
189
+ stored_vectors_valid = true;
124
190
  is_trained = false;
125
191
  ntotal = 0;
126
192
  }
@@ -184,15 +250,22 @@ void IndexSVSVamana::range_search(
184
250
  }
185
251
 
186
252
  size_t IndexSVSVamana::remove_ids(const IDSelector& sel) {
253
+ FAISS_THROW_IF_MSG(
254
+ is_static,
255
+ "Static Vamana index does not support remove_ids(). "
256
+ "The index is immutable after creation.");
187
257
  FAISS_THROW_IF_NOT(impl);
258
+ auto* dyn = dynamic_impl();
188
259
  auto id_filter = FaissIDFilter{sel};
189
260
  size_t removed = 0;
190
- auto Status = impl->remove_selected(&removed, id_filter);
261
+ auto Status = dyn->remove_selected(&removed, id_filter);
191
262
  ntotal -= removed;
263
+ stored_vectors.clear();
264
+ stored_vectors_valid = false;
192
265
  return removed;
193
266
  }
194
267
 
195
- void IndexSVSVamana::create_impl() {
268
+ void IndexSVSVamana::create_impl(idx_t n, const float* x) {
196
269
  FAISS_THROW_IF_NOT(!impl);
197
270
  ntotal = 0;
198
271
  auto svs_metric = to_svs_metric(metric_type);
@@ -209,15 +282,45 @@ void IndexSVSVamana::create_impl() {
209
282
  .search_window_size = search_window_size,
210
283
  .search_buffer_capacity = search_buffer_capacity,
211
284
  };
212
- auto Status = svs_runtime::DynamicVamanaIndex::build(
213
- &impl,
214
- d,
215
- svs_metric,
216
- svs_storage_kind,
217
- build_params,
218
- search_params);
219
- if (!Status.ok()) {
220
- FAISS_THROW_MSG(Status.message());
285
+
286
+ svs_runtime::Status Status;
287
+ if (is_static) {
288
+ FAISS_THROW_IF_NOT_MSG(
289
+ n > 0 && x != nullptr,
290
+ "Static Vamana index requires data at build time.");
291
+ Status = svs_runtime::VamanaIndex::build(
292
+ &impl,
293
+ d,
294
+ svs_metric,
295
+ svs_storage_kind,
296
+ build_params,
297
+ search_params);
298
+ if (!Status.ok()) {
299
+ FAISS_THROW_MSG(Status.message());
300
+ }
301
+ FAISS_THROW_IF_NOT(impl);
302
+ // Populate the static index with the full dataset (one-shot add).
303
+ Status = impl->add(static_cast<size_t>(n), x);
304
+ if (!Status.ok()) {
305
+ // Best-effort cleanup before propagating the error.
306
+ auto destroy_status = svs_runtime::VamanaIndex::destroy(impl);
307
+ FAISS_ASSERT(destroy_status.ok());
308
+ impl = nullptr;
309
+ FAISS_THROW_MSG(Status.message());
310
+ }
311
+ } else {
312
+ svs_runtime::DynamicVamanaIndex* dyn_impl = nullptr;
313
+ Status = svs_runtime::DynamicVamanaIndex::build(
314
+ &dyn_impl,
315
+ d,
316
+ svs_metric,
317
+ svs_storage_kind,
318
+ build_params,
319
+ search_params);
320
+ if (!Status.ok()) {
321
+ FAISS_THROW_MSG(Status.message());
322
+ }
323
+ impl = dyn_impl;
221
324
  }
222
325
  FAISS_THROW_IF_NOT(impl);
223
326
  }
@@ -236,10 +339,28 @@ void IndexSVSVamana::deserialize_impl(std::istream& in) {
236
339
  FAISS_THROW_IF_MSG(impl, "Cannot deserialize: SVS index already loaded.");
237
340
  auto svs_metric = to_svs_metric(metric_type);
238
341
  auto svs_storage_kind = to_svs_storage_kind(storage_kind);
239
- auto status = impl->load(&impl, in, svs_metric, svs_storage_kind);
342
+
343
+ svs_runtime::Status status;
344
+ if (is_static) {
345
+ status = svs_runtime::VamanaIndex::load(
346
+ &impl, in, svs_metric, svs_storage_kind);
347
+ } else {
348
+ svs_runtime::DynamicVamanaIndex* dyn_impl = nullptr;
349
+ status = svs_runtime::DynamicVamanaIndex::load(
350
+ &dyn_impl, in, svs_metric, svs_storage_kind);
351
+ impl = dyn_impl;
352
+ }
240
353
  if (!status.ok()) {
241
354
  FAISS_THROW_MSG(status.message());
242
355
  }
356
+ FAISS_THROW_IF_NOT_MSG(impl, "Failed to load SVS Vamana index.");
357
+ }
358
+
359
+ svs_runtime::DynamicVamanaIndex* IndexSVSVamana::dynamic_impl() const {
360
+ FAISS_THROW_IF_MSG(
361
+ is_static, "Operation not supported on a static Vamana index.");
362
+ FAISS_THROW_IF_NOT(impl);
363
+ return static_cast<svs_runtime::DynamicVamanaIndex*>(impl);
243
364
  }
244
365
 
245
366
  } // namespace faiss
@@ -30,6 +30,8 @@
30
30
  #include <svs/runtime/dynamic_vamana_index.h>
31
31
 
32
32
  #include <iostream>
33
+ #include <type_traits>
34
+ #include <vector>
33
35
 
34
36
  namespace faiss {
35
37
 
@@ -46,9 +48,11 @@ enum SVSStorageKind {
46
48
  SVS_LVQ4x0,
47
49
  SVS_LVQ4x4,
48
50
  SVS_LVQ4x8,
51
+ SVS_LVQ8x0,
49
52
  SVS_LeanVec4x4,
50
53
  SVS_LeanVec4x8,
51
54
  SVS_LeanVec8x8,
55
+ SVS_count,
52
56
  };
53
57
 
54
58
  inline svs_runtime::StorageKind to_svs_storage_kind(SVSStorageKind kind) {
@@ -65,6 +69,8 @@ inline svs_runtime::StorageKind to_svs_storage_kind(SVSStorageKind kind) {
65
69
  return svs_runtime::StorageKind::LVQ4x4;
66
70
  case SVS_LVQ4x8:
67
71
  return svs_runtime::StorageKind::LVQ4x8;
72
+ case SVS_LVQ8x0:
73
+ return svs_runtime::StorageKind::LVQ8x0;
68
74
  case SVS_LeanVec4x4:
69
75
  return svs_runtime::StorageKind::LeanVec4x4;
70
76
  case SVS_LeanVec4x8:
@@ -72,7 +78,9 @@ inline svs_runtime::StorageKind to_svs_storage_kind(SVSStorageKind kind) {
72
78
  case SVS_LeanVec8x8:
73
79
  return svs_runtime::StorageKind::LeanVec8x8;
74
80
  default:
75
- FAISS_ASSERT(false && "not supported SVS storage kind");
81
+ FAISS_THROW_FMT(
82
+ "SVSStorageKind (%d) not supported",
83
+ static_cast<std::underlying_type_t<SVSStorageKind>>(kind));
76
84
  }
77
85
  }
78
86
 
@@ -86,7 +94,10 @@ struct IndexSVSVamana : Index {
86
94
  size_t max_candidate_pool_size = 200;
87
95
  bool use_full_search_history = true;
88
96
 
89
- SVSStorageKind storage_kind;
97
+ /// Whether this is a static (immutable) Vamana index
98
+ bool is_static = false;
99
+
100
+ SVSStorageKind storage_kind = SVS_FP32;
90
101
 
91
102
  IndexSVSVamana();
92
103
 
@@ -94,7 +105,8 @@ struct IndexSVSVamana : Index {
94
105
  idx_t d,
95
106
  size_t degree,
96
107
  MetricType metric = METRIC_L2,
97
- SVSStorageKind storage = SVSStorageKind::SVS_FP32);
108
+ SVSStorageKind storage = SVSStorageKind::SVS_FP32,
109
+ bool is_static = false);
98
110
 
99
111
  ~IndexSVSVamana() override;
100
112
 
@@ -104,6 +116,8 @@ struct IndexSVSVamana : Index {
104
116
 
105
117
  void add(idx_t n, const float* x) override;
106
118
 
119
+ void reconstruct(idx_t key, float* recons) const override;
120
+
107
121
  void search(
108
122
  idx_t n,
109
123
  const float* x,
@@ -127,12 +141,24 @@ struct IndexSVSVamana : Index {
127
141
  void serialize_impl(std::ostream& out) const;
128
142
  virtual void deserialize_impl(std::istream& in);
129
143
 
130
- /* The actual SVS implementation */
131
- svs_runtime::DynamicVamanaIndex* impl{nullptr};
144
+ /* The actual SVS implementation (VamanaIndex is the base for both
145
+ static and dynamic variants) */
146
+ svs_runtime::VamanaIndex* impl{nullptr};
147
+
148
+ // The SVS runtime API does not expose vector retrieval, so we keep a copy
149
+ // of added vectors to support reconstruct(). When used as a coarse
150
+ // quantizer this holds only nlist centroids.
151
+ std::vector<float> stored_vectors;
152
+ bool stored_vectors_valid{true};
132
153
 
133
154
  protected:
134
- /* Initializes the implementation*/
135
- virtual void create_impl();
155
+ /* Initializes the implementation. For static indexes the data is consumed
156
+ at build time; for dynamic indexes n/x are ignored and add() populates
157
+ the index afterwards. */
158
+ virtual void create_impl(idx_t n, const float* x);
159
+
160
+ /* Returns the dynamic impl pointer, throwing if static */
161
+ svs_runtime::DynamicVamanaIndex* dynamic_impl() const;
136
162
  };
137
163
 
138
164
  } // namespace faiss
@@ -33,7 +33,8 @@ IndexSVSVamanaLVQ::IndexSVSVamanaLVQ(
33
33
  idx_t d,
34
34
  size_t degree,
35
35
  MetricType metric,
36
- SVSStorageKind storage)
37
- : IndexSVSVamana(d, degree, metric, storage) {}
36
+ SVSStorageKind storage,
37
+ bool is_static)
38
+ : IndexSVSVamana(d, degree, metric, storage, is_static) {}
38
39
 
39
40
  } // namespace faiss
@@ -34,7 +34,8 @@ struct IndexSVSVamanaLVQ : IndexSVSVamana {
34
34
  idx_t d,
35
35
  size_t degree,
36
36
  MetricType metric = METRIC_L2,
37
- SVSStorageKind storage = SVSStorageKind::SVS_LVQ4x4);
37
+ SVSStorageKind storage = SVSStorageKind::SVS_LVQ4x0,
38
+ bool is_static = false);
38
39
 
39
40
  ~IndexSVSVamanaLVQ() override = default;
40
41
  };