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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/ext/faiss/extconf.rb +2 -1
- data/ext/faiss/{index_rb.cpp → index.cpp} +1 -1
- data/ext/faiss/index_binary.cpp +1 -1
- data/ext/faiss/kmeans.cpp +1 -1
- data/ext/faiss/pca_matrix.cpp +1 -1
- data/ext/faiss/product_quantizer.cpp +1 -1
- data/ext/faiss/{utils_rb.cpp → utils.cpp} +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +93 -80
- data/vendor/faiss/faiss/Clustering.cpp +39 -240
- data/vendor/faiss/faiss/Clustering.h +6 -0
- data/vendor/faiss/faiss/IVFlib.cpp +41 -21
- data/vendor/faiss/faiss/Index.cpp +6 -5
- data/vendor/faiss/faiss/Index.h +5 -5
- data/vendor/faiss/faiss/Index2Layer.cpp +37 -53
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +49 -37
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +36 -34
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +4 -1
- data/vendor/faiss/faiss/IndexBinary.cpp +5 -3
- data/vendor/faiss/faiss/IndexBinary.h +4 -4
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +1 -1
- data/vendor/faiss/faiss/IndexBinaryFlat.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -4
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +88 -97
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +9 -3
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +45 -236
- data/vendor/faiss/faiss/IndexBinaryHash.h +6 -6
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +89 -417
- data/vendor/faiss/faiss/IndexFastScan.cpp +72 -109
- data/vendor/faiss/faiss/IndexFastScan.h +25 -23
- data/vendor/faiss/faiss/IndexFlat.cpp +27 -20
- data/vendor/faiss/faiss/IndexFlat.h +21 -18
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +42 -19
- data/vendor/faiss/faiss/IndexHNSW.cpp +374 -206
- data/vendor/faiss/faiss/IndexHNSW.h +16 -2
- data/vendor/faiss/faiss/IndexIDMap.cpp +25 -21
- data/vendor/faiss/faiss/IndexIDMap.h +9 -7
- data/vendor/faiss/faiss/IndexIVF.cpp +467 -364
- data/vendor/faiss/faiss/IndexIVF.h +33 -12
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +79 -76
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +96 -93
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +4 -1
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +357 -238
- data/vendor/faiss/faiss/IndexIVFFastScan.h +42 -41
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +39 -69
- data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +56 -33
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +73 -846
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +151 -121
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +23 -20
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +30 -52
- data/vendor/faiss/faiss/IndexIVFRaBitQ.h +2 -1
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +475 -476
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +248 -93
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +41 -127
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
- data/vendor/faiss/faiss/IndexLSH.cpp +36 -19
- data/vendor/faiss/faiss/IndexLattice.cpp +13 -13
- data/vendor/faiss/faiss/IndexNNDescent.cpp +36 -21
- data/vendor/faiss/faiss/IndexNNDescent.h +2 -2
- data/vendor/faiss/faiss/IndexNSG.cpp +38 -23
- data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +31 -11
- data/vendor/faiss/faiss/IndexPQ.cpp +128 -221
- data/vendor/faiss/faiss/IndexPQ.h +3 -2
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +20 -14
- data/vendor/faiss/faiss/IndexPQFastScan.h +3 -0
- data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -18
- data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +11 -36
- data/vendor/faiss/faiss/IndexRaBitQ.h +2 -1
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +41 -277
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +183 -27
- data/vendor/faiss/faiss/IndexRefine.cpp +30 -25
- data/vendor/faiss/faiss/IndexRefine.h +4 -4
- data/vendor/faiss/faiss/IndexReplicas.cpp +6 -6
- data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +15 -14
- data/vendor/faiss/faiss/IndexRowwiseMinMax.h +1 -1
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +150 -20
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +10 -0
- data/vendor/faiss/faiss/IndexShards.cpp +10 -9
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
- data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
- data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
- data/vendor/faiss/faiss/MetaIndexes.h +1 -1
- data/vendor/faiss/faiss/MetricType.h +14 -7
- data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
- data/vendor/faiss/faiss/SuperKMeans.h +97 -0
- data/vendor/faiss/faiss/VectorTransform.cpp +237 -149
- data/vendor/faiss/faiss/VectorTransform.h +16 -16
- data/vendor/faiss/faiss/build.cpp +23 -0
- data/vendor/faiss/faiss/build.h +15 -0
- data/vendor/faiss/faiss/clone_index.cpp +48 -47
- data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +1 -1
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +902 -12
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +702 -10
- data/vendor/faiss/faiss/factory_tools.cpp +9 -0
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
- data/vendor/faiss/faiss/gpu/GpuResources.h +3 -2
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +15 -16
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +5 -4
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
- data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
- data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
- data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
- data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
- data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
- data/vendor/faiss/faiss/gpu_metal/MetalDistance.h +87 -0
- data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +58 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +181 -0
- data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +111 -0
- data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +45 -0
- data/vendor/faiss/faiss/gpu_metal/MetalResources.h +79 -0
- data/vendor/faiss/faiss/gpu_metal/StandardMetalResources.h +35 -0
- data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFFlat.h +193 -0
- data/vendor/faiss/faiss/impl/AdSampling.cpp +103 -0
- data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +29 -25
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -0
- data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
- data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
- data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +16 -16
- data/vendor/faiss/faiss/impl/CodePacker.cpp +3 -3
- data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +1 -1
- data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
- data/vendor/faiss/faiss/impl/FaissAssert.h +6 -3
- data/vendor/faiss/faiss/impl/FaissException.h +50 -3
- data/vendor/faiss/faiss/impl/HNSW.cpp +639 -507
- data/vendor/faiss/faiss/impl/HNSW.h +61 -44
- data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
- data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
- data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +82 -77
- data/vendor/faiss/faiss/impl/NNDescent.cpp +62 -25
- data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
- data/vendor/faiss/faiss/impl/NSG.cpp +53 -32
- data/vendor/faiss/faiss/impl/NSG.h +4 -4
- data/vendor/faiss/faiss/impl/Panorama.cpp +23 -6
- data/vendor/faiss/faiss/impl/Panorama.h +269 -87
- data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
- data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +46 -32
- data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
- data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +55 -25
- data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +55 -49
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +65 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +302 -283
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +26 -23
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ResultHandler.h +100 -75
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +318 -7
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +77 -1
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
- data/vendor/faiss/faiss/impl/VisitedTable.cpp +10 -10
- data/vendor/faiss/faiss/impl/VisitedTable.h +70 -28
- data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
- data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
- data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
- data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
- data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
- data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
- data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
- data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
- data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
- data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
- data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
- data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
- data/vendor/faiss/faiss/impl/expanded_scanners.h +8 -3
- data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
- data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
- data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
- data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
- data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
- data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +270 -0
- data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +169 -2
- data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
- data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
- data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -356
- data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
- data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
- data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +282 -134
- data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
- data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +83 -0
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +113 -0
- data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +150 -0
- data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +142 -0
- data/vendor/faiss/faiss/impl/index_read.cpp +1227 -79
- data/vendor/faiss/faiss/impl/index_read_utils.h +1 -1
- data/vendor/faiss/faiss/impl/index_write.cpp +96 -13
- data/vendor/faiss/faiss/impl/io.cpp +6 -6
- data/vendor/faiss/faiss/impl/io_macros.h +58 -16
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +37 -23
- data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
- data/vendor/faiss/faiss/impl/mapped_io.cpp +6 -6
- data/vendor/faiss/faiss/impl/platform_macros.h +15 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +23 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +23 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +23 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx2.cpp → pq_code_distance-avx2.h} +9 -13
- data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx512.cpp → pq_code_distance-avx512.h} +9 -57
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +45 -107
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +274 -5
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +10 -7
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +105 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +70 -0
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +311 -477
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
- data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +1 -1
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +9 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +419 -19
- data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +27 -1
- data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +3 -3
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +387 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +553 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +559 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +341 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +425 -3
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +290 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +337 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +192 -8
- data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +12 -0
- data/vendor/faiss/faiss/impl/simd_dispatch.h +157 -66
- data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +264 -172
- data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
- data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +270 -218
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
- data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
- data/vendor/faiss/faiss/impl/svs_io.h +8 -2
- data/vendor/faiss/faiss/index_factory.cpp +90 -18
- data/vendor/faiss/faiss/index_io.h +40 -0
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +66 -16
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +28 -15
- data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +170 -86
- data/vendor/faiss/faiss/invlists/InvertedLists.h +88 -25
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +13 -13
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
- data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +142 -21
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +33 -7
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +3 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +77 -27
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +10 -4
- data/vendor/faiss/faiss/utils/Heap.cpp +10 -10
- data/vendor/faiss/faiss/utils/NeuralNet.cpp +47 -36
- data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
- data/vendor/faiss/faiss/utils/bf16.h +34 -0
- data/vendor/faiss/faiss/utils/distances.cpp +390 -560
- data/vendor/faiss/faiss/utils/distances.h +20 -1
- data/vendor/faiss/faiss/utils/distances_dispatch.h +117 -37
- data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
- data/vendor/faiss/faiss/utils/distances_simd.cpp +5 -178
- data/vendor/faiss/faiss/utils/extra_distances.cpp +9 -8
- data/vendor/faiss/faiss/utils/extra_distances.h +32 -6
- data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
- data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
- data/vendor/faiss/faiss/utils/hamming.h +92 -2
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +16 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +15 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +210 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_spr.h +171 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-generic.h +368 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +322 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-rvv.h +39 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer.h +146 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +481 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +15 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +15 -0
- data/vendor/faiss/faiss/utils/partitioning.cpp +66 -989
- data/vendor/faiss/faiss/utils/partitioning.h +31 -0
- data/vendor/faiss/faiss/utils/popcount.h +29 -0
- data/vendor/faiss/faiss/utils/pq_code_distance.h +2 -2
- data/vendor/faiss/faiss/utils/prefetch.h +2 -2
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +30 -30
- data/vendor/faiss/faiss/utils/quantize_lut.h +1 -1
- data/vendor/faiss/faiss/utils/rabitq_simd.h +57 -536
- data/vendor/faiss/faiss/utils/random.cpp +6 -6
- data/vendor/faiss/faiss/utils/simd_impl/IVFFlatScanner-inl.h +51 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +5 -1
- data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +213 -4
- data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +163 -10
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +250 -4
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +7 -4
- data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +189 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_simdlib256.h +195 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +2 -1
- data/vendor/faiss/faiss/utils/{distances_fused/simdlib_based.h → simd_impl/exhaustive_L2sqr_blas_cmax.h} +5 -10
- data/vendor/faiss/faiss/utils/simd_impl/hamming_impl.h +481 -0
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +14 -0
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +14 -0
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +1031 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +355 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +477 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512_spr.cpp +343 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +55 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
- data/vendor/faiss/faiss/utils/simd_levels.cpp +29 -7
- data/vendor/faiss/faiss/utils/simd_levels.h +93 -1
- data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
- data/vendor/faiss/faiss/utils/utils.cpp +5 -5
- data/vendor/faiss/faiss/utils/utils.h +3 -3
- metadata +129 -34
- data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
- data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -224
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -230
- data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
- data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
- data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
- data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -235
- data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
- data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
- data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -449
- data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
- data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
- data/vendor/faiss/faiss/utils/simdlib.h +0 -42
- data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -365
- /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(¤t_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
|
-
|
|
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::
|
|
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::
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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::
|
|
37
|
+
SVSStorageKind storage = SVSStorageKind::SVS_LVQ4x0,
|
|
38
|
+
bool is_static = false);
|
|
38
39
|
|
|
39
40
|
~IndexSVSVamanaLVQ() override = default;
|
|
40
41
|
};
|