faiss 0.5.3 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/ext/faiss/ext.cpp +1 -1
- data/ext/faiss/extconf.rb +4 -4
- data/ext/faiss/index.cpp +63 -45
- data/ext/faiss/index_binary.cpp +37 -27
- data/ext/faiss/kmeans.cpp +9 -8
- data/ext/faiss/pca_matrix.cpp +9 -7
- data/ext/faiss/product_quantizer.cpp +13 -11
- data/ext/faiss/utils.cpp +4 -2
- data/ext/faiss/utils.h +4 -0
- data/lib/faiss/version.rb +1 -1
- data/lib/faiss.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +214 -82
- data/vendor/faiss/faiss/AutoTune.h +14 -1
- data/vendor/faiss/faiss/Clustering.cpp +97 -249
- data/vendor/faiss/faiss/Clustering.h +18 -0
- data/vendor/faiss/faiss/IVFlib.cpp +67 -44
- data/vendor/faiss/faiss/Index.cpp +25 -12
- data/vendor/faiss/faiss/Index.h +26 -4
- data/vendor/faiss/faiss/Index2Layer.cpp +37 -53
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +68 -61
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +36 -34
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +4 -1
- data/vendor/faiss/faiss/IndexBinary.cpp +6 -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 +92 -95
- 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 +120 -414
- data/vendor/faiss/faiss/IndexFastScan.cpp +105 -129
- data/vendor/faiss/faiss/IndexFastScan.h +35 -24
- data/vendor/faiss/faiss/IndexFlat.cpp +216 -152
- data/vendor/faiss/faiss/IndexFlat.h +32 -14
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +88 -41
- data/vendor/faiss/faiss/IndexFlatCodes.h +7 -1
- data/vendor/faiss/faiss/IndexHNSW.cpp +299 -187
- data/vendor/faiss/faiss/IndexHNSW.h +30 -14
- data/vendor/faiss/faiss/IndexIDMap.cpp +26 -22
- data/vendor/faiss/faiss/IndexIDMap.h +9 -7
- data/vendor/faiss/faiss/IndexIVF.cpp +535 -405
- data/vendor/faiss/faiss/IndexIVF.h +47 -16
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +77 -74
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +105 -99
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +6 -3
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +379 -249
- data/vendor/faiss/faiss/IndexIVFFastScan.h +65 -60
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +41 -124
- data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +89 -138
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +77 -907
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +184 -122
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +23 -18
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +59 -60
- data/vendor/faiss/faiss/IndexIVFRaBitQ.h +4 -3
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +564 -416
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +269 -111
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +41 -127
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
- data/vendor/faiss/faiss/IndexLSH.cpp +44 -25
- data/vendor/faiss/faiss/IndexLattice.cpp +41 -36
- data/vendor/faiss/faiss/IndexNNDescent.cpp +37 -21
- data/vendor/faiss/faiss/IndexNNDescent.h +2 -2
- data/vendor/faiss/faiss/IndexNSG.cpp +40 -23
- data/vendor/faiss/faiss/IndexNSG.h +0 -2
- data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +32 -12
- data/vendor/faiss/faiss/IndexPQ.cpp +129 -213
- 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 +31 -43
- data/vendor/faiss/faiss/IndexRaBitQ.h +4 -3
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +135 -317
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +192 -34
- data/vendor/faiss/faiss/IndexRefine.cpp +30 -55
- 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 +82 -14
- data/vendor/faiss/faiss/IndexShards.cpp +13 -13
- 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 +29 -6
- data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
- data/vendor/faiss/faiss/SuperKMeans.h +97 -0
- data/vendor/faiss/faiss/VectorTransform.cpp +349 -141
- data/vendor/faiss/faiss/VectorTransform.h +39 -16
- data/vendor/faiss/faiss/build.cpp +23 -0
- data/vendor/faiss/faiss/build.h +15 -0
- data/vendor/faiss/faiss/clone_index.cpp +55 -51
- 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/PQ-avx2-inl.h +38 -38
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
- data/vendor/faiss/faiss/{cppcontrib/factory_tools.cpp → factory_tools.cpp} +6 -1
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +1 -1
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
- data/vendor/faiss/faiss/gpu/GpuResources.h +1 -1
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +9 -9
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +4 -3
- 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/MetalFlatKernels.h +40 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +51 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
- data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +66 -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/impl/AdSampling.cpp +103 -0
- data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +64 -34
- 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 -28
- 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 +367 -0
- data/vendor/faiss/faiss/impl/ClusteringInitialization.h +107 -0
- data/vendor/faiss/faiss/impl/CodePacker.cpp +7 -3
- data/vendor/faiss/faiss/impl/CodePacker.h +11 -3
- data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +83 -0
- data/vendor/faiss/faiss/impl/CodePackerRaBitQ.h +47 -0
- data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
- data/vendor/faiss/faiss/impl/FaissAssert.h +64 -3
- data/vendor/faiss/faiss/impl/FaissException.h +50 -3
- data/vendor/faiss/faiss/impl/HNSW.cpp +117 -351
- data/vendor/faiss/faiss/impl/HNSW.h +21 -40
- 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 +114 -102
- data/vendor/faiss/faiss/impl/NNDescent.cpp +63 -26
- data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
- data/vendor/faiss/faiss/impl/NSG.cpp +44 -26
- data/vendor/faiss/faiss/impl/NSG.h +20 -10
- data/vendor/faiss/faiss/impl/Panorama.cpp +76 -52
- data/vendor/faiss/faiss/impl/Panorama.h +265 -78
- 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 +62 -37
- 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 +99 -80
- data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +135 -37
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +148 -21
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +298 -301
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +3 -10
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +15 -41
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.h +0 -4
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +40 -32
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ResultHandler.h +218 -113
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +119 -2362
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +27 -3
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
- data/vendor/faiss/faiss/impl/VisitedTable.cpp +42 -0
- data/vendor/faiss/faiss/impl/VisitedTable.h +76 -0
- 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 +163 -0
- 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 +268 -0
- data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +176 -4
- 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 -348
- 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} +290 -142
- 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 +91 -0
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -0
- data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +104 -0
- data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +111 -0
- data/vendor/faiss/faiss/impl/index_read.cpp +1950 -505
- data/vendor/faiss/faiss/impl/index_read_utils.h +1 -2
- data/vendor/faiss/faiss/impl/index_write.cpp +112 -21
- data/vendor/faiss/faiss/impl/io.cpp +6 -6
- data/vendor/faiss/faiss/impl/io_macros.h +33 -16
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +81 -40
- data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
- data/vendor/faiss/faiss/impl/mapped_io.cpp +15 -8
- data/vendor/faiss/faiss/impl/platform_macros.h +11 -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 +21 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +21 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +21 -0
- data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx2.h → pq_code_distance/pq_code_distance-avx2.h} +43 -220
- data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx512.h → pq_code_distance/pq_code_distance-avx512.h} +25 -112
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +59 -0
- 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 +256 -0
- data/vendor/faiss/faiss/impl/{code_distance/code_distance-sve.h → pq_code_distance/pq_code_distance-sve.cpp} +57 -146
- data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +68 -0
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +320 -483
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
- data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +121 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +137 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +371 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +190 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +94 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +603 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +597 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +388 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +630 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +311 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +387 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +54 -0
- data/vendor/faiss/faiss/impl/simd_dispatch.h +173 -0
- data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +274 -171
- 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 +275 -217
- 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 +115 -28
- data/vendor/faiss/faiss/index_io.h +53 -3
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +73 -20
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +24 -14
- data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +157 -73
- data/vendor/faiss/faiss/invlists/InvertedLists.h +86 -23
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +14 -14
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +9 -19
- data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
- data/vendor/faiss/faiss/svs/IndexSVSFlat.h +2 -0
- 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 +25 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +19 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +19 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +14 -0
- data/vendor/faiss/faiss/utils/Heap.cpp +56 -10
- data/vendor/faiss/faiss/utils/Heap.h +21 -0
- data/vendor/faiss/faiss/utils/NeuralNet.cpp +54 -40
- 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/distances.cpp +507 -559
- data/vendor/faiss/faiss/utils/distances.h +118 -1
- data/vendor/faiss/faiss/utils/distances_dispatch.h +250 -0
- 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 +72 -3681
- data/vendor/faiss/faiss/utils/extra_distances.cpp +60 -102
- data/vendor/faiss/faiss/utils/extra_distances.h +79 -7
- 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 +15 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.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 +234 -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 -987
- 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 +251 -0
- 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 +124 -343
- 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 +154 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +777 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +306 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +1431 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +1095 -0
- 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 +392 -0
- 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 +1085 -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_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 +334 -0
- data/vendor/faiss/faiss/utils/simd_levels.h +183 -0
- data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
- data/vendor/faiss/faiss/utils/utils.cpp +21 -14
- data/vendor/faiss/faiss/utils/utils.h +3 -3
- metadata +156 -42
- data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
- data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
- data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +0 -81
- data/vendor/faiss/faiss/impl/code_distance/code_distance.h +0 -186
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -216
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -224
- 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 -228
- 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 -450
- 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 -296
- /data/vendor/faiss/faiss/{cppcontrib/factory_tools.h → factory_tools.h} +0 -0
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
#include <faiss/impl/NNDescent.h>
|
|
11
11
|
|
|
12
12
|
#include <mutex>
|
|
13
|
-
#include <string>
|
|
14
13
|
|
|
15
14
|
#include <faiss/impl/AuxIndexStructures.h>
|
|
16
15
|
#include <faiss/impl/DistanceComputer.h>
|
|
16
|
+
#include <faiss/impl/VisitedTable.h>
|
|
17
17
|
|
|
18
18
|
namespace faiss {
|
|
19
19
|
|
|
@@ -23,7 +23,7 @@ namespace nndescent {
|
|
|
23
23
|
|
|
24
24
|
void gen_random(std::mt19937& rng, int* addr, const int size, const int N);
|
|
25
25
|
|
|
26
|
-
Nhood::Nhood(int l
|
|
26
|
+
Nhood::Nhood(int /* l */, int s, std::mt19937& rng, int N) {
|
|
27
27
|
M = s;
|
|
28
28
|
nn_new.resize(s * 2);
|
|
29
29
|
gen_random(rng, nn_new.data(), (int)nn_new.size(), N);
|
|
@@ -31,25 +31,46 @@ Nhood::Nhood(int l, int s, std::mt19937& rng, int N) {
|
|
|
31
31
|
|
|
32
32
|
/// Copy operator
|
|
33
33
|
Nhood& Nhood::operator=(const Nhood& other) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
if (this != &other) {
|
|
35
|
+
M = other.M;
|
|
36
|
+
nn_new = other.nn_new;
|
|
37
|
+
nn_old = other.nn_old;
|
|
38
|
+
rnn_new = other.rnn_new;
|
|
39
|
+
rnn_old = other.rnn_old;
|
|
40
|
+
pool = other.pool;
|
|
41
|
+
}
|
|
41
42
|
return *this;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
/// Copy constructor
|
|
45
|
-
Nhood::Nhood(const Nhood& other)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
Nhood::Nhood(const Nhood& other)
|
|
47
|
+
: pool(other.pool),
|
|
48
|
+
M(other.M),
|
|
49
|
+
nn_old(other.nn_old),
|
|
50
|
+
nn_new(other.nn_new),
|
|
51
|
+
rnn_old(other.rnn_old),
|
|
52
|
+
rnn_new(other.rnn_new) {}
|
|
53
|
+
|
|
54
|
+
/// Move constructor
|
|
55
|
+
Nhood::Nhood(Nhood&& other) noexcept
|
|
56
|
+
: pool(std::move(other.pool)),
|
|
57
|
+
M(other.M),
|
|
58
|
+
nn_old(std::move(other.nn_old)),
|
|
59
|
+
nn_new(std::move(other.nn_new)),
|
|
60
|
+
rnn_old(std::move(other.rnn_old)),
|
|
61
|
+
rnn_new(std::move(other.rnn_new)) {}
|
|
62
|
+
|
|
63
|
+
/// Move assignment operator
|
|
64
|
+
Nhood& Nhood::operator=(Nhood&& other) noexcept {
|
|
65
|
+
if (this != &other) {
|
|
66
|
+
M = other.M;
|
|
67
|
+
nn_new = std::move(other.nn_new);
|
|
68
|
+
nn_old = std::move(other.nn_old);
|
|
69
|
+
rnn_new = std::move(other.rnn_new);
|
|
70
|
+
rnn_old = std::move(other.rnn_old);
|
|
71
|
+
pool = std::move(other.pool);
|
|
72
|
+
}
|
|
73
|
+
return *this;
|
|
53
74
|
}
|
|
54
75
|
|
|
55
76
|
/// Insert a point into the candidate pool
|
|
@@ -58,7 +79,7 @@ void Nhood::insert(int id, float dist) {
|
|
|
58
79
|
if (dist > pool.front().distance) {
|
|
59
80
|
return;
|
|
60
81
|
}
|
|
61
|
-
for (
|
|
82
|
+
for (size_t i = 0; i < pool.size(); i++) {
|
|
62
83
|
if (id == pool[i].id) {
|
|
63
84
|
return;
|
|
64
85
|
}
|
|
@@ -90,6 +111,22 @@ void Nhood::join(C callback) const {
|
|
|
90
111
|
}
|
|
91
112
|
|
|
92
113
|
void gen_random(std::mt19937& rng, int* addr, const int size, const int N) {
|
|
114
|
+
FAISS_THROW_IF_NOT_FMT(
|
|
115
|
+
size > 0 && size <= N,
|
|
116
|
+
"gen_random: size (%d) must be > 0 and <= N (%d)",
|
|
117
|
+
size,
|
|
118
|
+
N);
|
|
119
|
+
if (size == N) {
|
|
120
|
+
// Special case: return all indices in random order
|
|
121
|
+
for (int i = 0; i < size; ++i) {
|
|
122
|
+
addr[i] = i;
|
|
123
|
+
}
|
|
124
|
+
for (int i = size - 1; i > 0; --i) {
|
|
125
|
+
int j = rng() % (i + 1);
|
|
126
|
+
std::swap(addr[i], addr[j]);
|
|
127
|
+
}
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
93
130
|
for (int i = 0; i < size; ++i) {
|
|
94
131
|
addr[i] = rng() % (N - size);
|
|
95
132
|
}
|
|
@@ -153,7 +190,7 @@ using namespace nndescent;
|
|
|
153
190
|
|
|
154
191
|
constexpr int NUM_EVAL_POINTS = 100;
|
|
155
192
|
|
|
156
|
-
NNDescent::NNDescent(const int
|
|
193
|
+
NNDescent::NNDescent(const int d_in, const int K_in) : K(K_in), d(d_in) {
|
|
157
194
|
L = K + 50;
|
|
158
195
|
}
|
|
159
196
|
|
|
@@ -197,7 +234,7 @@ void NNDescent::update() {
|
|
|
197
234
|
auto& nn = graph[n];
|
|
198
235
|
std::sort(nn.pool.begin(), nn.pool.end());
|
|
199
236
|
|
|
200
|
-
if (nn.pool.size() > L) {
|
|
237
|
+
if (nn.pool.size() > static_cast<size_t>(L)) {
|
|
201
238
|
nn.pool.resize(L);
|
|
202
239
|
}
|
|
203
240
|
nn.pool.reserve(L); // keep the pool size be L
|
|
@@ -238,7 +275,7 @@ void NNDescent::update() {
|
|
|
238
275
|
// the candidate pool of the other side
|
|
239
276
|
if (nn.distance > other.pool.back().distance) {
|
|
240
277
|
LockGuard guard(other.lock);
|
|
241
|
-
if (other.rnn_new.size() < R) {
|
|
278
|
+
if (other.rnn_new.size() < static_cast<size_t>(R)) {
|
|
242
279
|
other.rnn_new.push_back(n);
|
|
243
280
|
} else {
|
|
244
281
|
int pos = rng() % R;
|
|
@@ -254,7 +291,7 @@ void NNDescent::update() {
|
|
|
254
291
|
// the candidate pool of the other side
|
|
255
292
|
if (nn.distance > other.pool.back().distance) {
|
|
256
293
|
LockGuard guard(other.lock);
|
|
257
|
-
if (other.rnn_old.size() < R) {
|
|
294
|
+
if (other.rnn_old.size() < static_cast<size_t>(R)) {
|
|
258
295
|
other.rnn_old.push_back(n);
|
|
259
296
|
} else {
|
|
260
297
|
int pos = rng() % R;
|
|
@@ -280,7 +317,7 @@ void NNDescent::update() {
|
|
|
280
317
|
|
|
281
318
|
nn_new.insert(nn_new.end(), rnn_new.begin(), rnn_new.end());
|
|
282
319
|
nn_old.insert(nn_old.end(), rnn_old.begin(), rnn_old.end());
|
|
283
|
-
if (nn_old.size() > R * 2) {
|
|
320
|
+
if (nn_old.size() > static_cast<size_t>(R * 2)) {
|
|
284
321
|
nn_old.resize(R * 2);
|
|
285
322
|
nn_old.reserve(R * 2);
|
|
286
323
|
}
|
|
@@ -294,7 +331,7 @@ void NNDescent::nndescent(DistanceComputer& qdis, bool verbose) {
|
|
|
294
331
|
int num_eval_points = std::min(NUM_EVAL_POINTS, ntotal);
|
|
295
332
|
std::vector<int> eval_points(num_eval_points);
|
|
296
333
|
std::vector<std::vector<int>> acc_eval_set(num_eval_points);
|
|
297
|
-
std::mt19937 rng(random_seed * 6577
|
|
334
|
+
std::mt19937 rng(random_seed * 6577);
|
|
298
335
|
gen_random(rng, eval_points.data(), eval_points.size(), ntotal);
|
|
299
336
|
generate_eval_set(qdis, eval_points, acc_eval_set, ntotal);
|
|
300
337
|
for (int it = 0; it < iter; it++) {
|
|
@@ -315,7 +352,7 @@ void NNDescent::generate_eval_set(
|
|
|
315
352
|
std::vector<std::vector<int>>& v,
|
|
316
353
|
int N) {
|
|
317
354
|
#pragma omp parallel for
|
|
318
|
-
for (int i = 0; i < c.size(); i++) {
|
|
355
|
+
for (int i = 0; i < static_cast<int>(c.size()); i++) {
|
|
319
356
|
std::vector<Neighbor> tmp;
|
|
320
357
|
for (int j = 0; j < N; j++) {
|
|
321
358
|
if (c[i] == j) {
|
|
@@ -488,7 +525,7 @@ void NNDescent::search(
|
|
|
488
525
|
++k;
|
|
489
526
|
}
|
|
490
527
|
}
|
|
491
|
-
for (
|
|
528
|
+
for (int i = 0; i < topk; i++) {
|
|
492
529
|
indices[i] = retset[i].id;
|
|
493
530
|
dists[i] = retset[i].distance;
|
|
494
531
|
}
|
|
@@ -54,8 +54,8 @@ struct Neighbor {
|
|
|
54
54
|
bool flag;
|
|
55
55
|
|
|
56
56
|
Neighbor() = default;
|
|
57
|
-
Neighbor(int
|
|
58
|
-
: id(
|
|
57
|
+
Neighbor(int id_in, float distance_in, bool f)
|
|
58
|
+
: id(id_in), distance(distance_in), flag(f) {}
|
|
59
59
|
|
|
60
60
|
inline bool operator<(const Neighbor& other) const {
|
|
61
61
|
return distance < other.distance;
|
|
@@ -80,6 +80,10 @@ struct Nhood {
|
|
|
80
80
|
|
|
81
81
|
Nhood(const Nhood& other);
|
|
82
82
|
|
|
83
|
+
Nhood(Nhood&& other) noexcept;
|
|
84
|
+
|
|
85
|
+
Nhood& operator=(Nhood&& other) noexcept;
|
|
86
|
+
|
|
83
87
|
void insert(int id, float dist);
|
|
84
88
|
|
|
85
89
|
template <typename C>
|
|
@@ -8,11 +8,13 @@
|
|
|
8
8
|
#include <faiss/impl/NSG.h>
|
|
9
9
|
|
|
10
10
|
#include <algorithm>
|
|
11
|
+
#include <limits>
|
|
11
12
|
#include <memory>
|
|
12
13
|
#include <mutex>
|
|
13
14
|
#include <stack>
|
|
14
15
|
|
|
15
16
|
#include <faiss/impl/DistanceComputer.h>
|
|
17
|
+
#include <faiss/impl/VisitedTable.h>
|
|
16
18
|
|
|
17
19
|
namespace faiss {
|
|
18
20
|
|
|
@@ -41,8 +43,8 @@ struct Neighbor {
|
|
|
41
43
|
bool flag;
|
|
42
44
|
|
|
43
45
|
Neighbor() = default;
|
|
44
|
-
Neighbor(int
|
|
45
|
-
: id(
|
|
46
|
+
Neighbor(int id_in, float distance_in, bool f)
|
|
47
|
+
: id(id_in), distance(distance_in), flag(f) {}
|
|
46
48
|
|
|
47
49
|
inline bool operator<(const Neighbor& other) const {
|
|
48
50
|
return distance < other.distance;
|
|
@@ -54,7 +56,7 @@ struct Node {
|
|
|
54
56
|
float distance;
|
|
55
57
|
|
|
56
58
|
Node() = default;
|
|
57
|
-
Node(int
|
|
59
|
+
Node(int id_in, float distance_in) : id(id_in), distance(distance_in) {}
|
|
58
60
|
|
|
59
61
|
inline bool operator<(const Node& other) const {
|
|
60
62
|
return distance < other.distance;
|
|
@@ -109,10 +111,9 @@ inline int insert_into_pool(Neighbor* addr, int K, Neighbor nn) {
|
|
|
109
111
|
|
|
110
112
|
using namespace nsg;
|
|
111
113
|
|
|
112
|
-
NSG::NSG(int
|
|
114
|
+
NSG::NSG(int R_in) : R(R_in), rng(0x0903) {
|
|
113
115
|
L = R + 32;
|
|
114
116
|
C = R + 100;
|
|
115
|
-
srand(0x1998);
|
|
116
117
|
}
|
|
117
118
|
|
|
118
119
|
void NSG::search(
|
|
@@ -130,7 +131,7 @@ void NSG::search(
|
|
|
130
131
|
search_on_graph<false>(
|
|
131
132
|
*final_graph, dis, vt, enterpoint, pool_size, retset, tmp);
|
|
132
133
|
|
|
133
|
-
for (
|
|
134
|
+
for (int i = 0; i < k; i++) {
|
|
134
135
|
I[i] = retset[i].id;
|
|
135
136
|
D[i] = retset[i].distance;
|
|
136
137
|
}
|
|
@@ -178,7 +179,7 @@ void NSG::build(
|
|
|
178
179
|
is_built = true;
|
|
179
180
|
|
|
180
181
|
if (verbose) {
|
|
181
|
-
int max = 0, min =
|
|
182
|
+
int max = 0, min = std::numeric_limits<int>::max();
|
|
182
183
|
double avg = 0;
|
|
183
184
|
|
|
184
185
|
for (int i = 0; i < n; i++) {
|
|
@@ -233,7 +234,7 @@ void NSG::init_graph(Index* storage, const nsg::Graph<idx_t>& knn_graph) {
|
|
|
233
234
|
std::unique_ptr<DistanceComputer> dis(storage_distance_computer(storage));
|
|
234
235
|
|
|
235
236
|
dis->set_query(center.get());
|
|
236
|
-
VisitedTable vt(ntotal);
|
|
237
|
+
VisitedTable vt(ntotal, use_visited_hashset);
|
|
237
238
|
|
|
238
239
|
// Do not collect the visited nodes
|
|
239
240
|
search_on_graph<false>(knn_graph, *dis, vt, ep, L, retset, tmpset);
|
|
@@ -255,16 +256,18 @@ void NSG::search_on_graph(
|
|
|
255
256
|
retset.resize(pool_size + 1);
|
|
256
257
|
std::vector<int> init_ids(pool_size);
|
|
257
258
|
|
|
259
|
+
vt.reserve(pool_size);
|
|
260
|
+
|
|
258
261
|
int num_ids = 0;
|
|
259
262
|
std::vector<index_t> neighbors(graph.K);
|
|
260
263
|
size_t nneigh = graph.get_neighbors(ep, neighbors.data());
|
|
261
|
-
for (
|
|
264
|
+
for (size_t i = 0; i < init_ids.size() && i < nneigh; i++) {
|
|
262
265
|
int id = (int)neighbors[i];
|
|
263
266
|
if (id >= ntotal) {
|
|
264
267
|
continue;
|
|
265
268
|
}
|
|
266
269
|
|
|
267
|
-
init_ids[
|
|
270
|
+
init_ids[num_ids] = id;
|
|
268
271
|
vt.set(id);
|
|
269
272
|
num_ids += 1;
|
|
270
273
|
}
|
|
@@ -280,7 +283,7 @@ void NSG::search_on_graph(
|
|
|
280
283
|
vt.set(id);
|
|
281
284
|
}
|
|
282
285
|
|
|
283
|
-
for (
|
|
286
|
+
for (size_t i = 0; i < init_ids.size(); i++) {
|
|
284
287
|
int id = init_ids[i];
|
|
285
288
|
|
|
286
289
|
float dist = dis(id);
|
|
@@ -302,9 +305,9 @@ void NSG::search_on_graph(
|
|
|
302
305
|
int n = retset[k].id;
|
|
303
306
|
|
|
304
307
|
size_t nneigh_for_n = graph.get_neighbors(n, neighbors.data());
|
|
305
|
-
for (
|
|
308
|
+
for (size_t m = 0; m < nneigh_for_n; m++) {
|
|
306
309
|
int id = neighbors[m];
|
|
307
|
-
if (id
|
|
310
|
+
if (id >= ntotal || vt.get(id)) {
|
|
308
311
|
continue;
|
|
309
312
|
}
|
|
310
313
|
vt.set(id);
|
|
@@ -341,7 +344,7 @@ void NSG::link(
|
|
|
341
344
|
std::vector<Node> pool;
|
|
342
345
|
std::vector<Neighbor> tmp;
|
|
343
346
|
|
|
344
|
-
VisitedTable vt(ntotal);
|
|
347
|
+
VisitedTable vt(ntotal, use_visited_hashset);
|
|
345
348
|
std::unique_ptr<DistanceComputer> dis(
|
|
346
349
|
storage_distance_computer(storage));
|
|
347
350
|
|
|
@@ -396,16 +399,30 @@ void NSG::sync_prune(
|
|
|
396
399
|
|
|
397
400
|
std::vector<Node> result;
|
|
398
401
|
|
|
402
|
+
if (pool.empty()) {
|
|
403
|
+
for (int i = 0; i < R; i++) {
|
|
404
|
+
graph.at(q, i).id = EMPTY_ID;
|
|
405
|
+
}
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
|
|
399
409
|
int start = 0;
|
|
400
410
|
if (pool[start].id == q) {
|
|
401
411
|
start++;
|
|
402
412
|
}
|
|
413
|
+
if (start >= static_cast<int>(pool.size())) {
|
|
414
|
+
for (int i = 0; i < R; i++) {
|
|
415
|
+
graph.at(q, i).id = EMPTY_ID;
|
|
416
|
+
}
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
403
419
|
result.push_back(pool[start]);
|
|
404
420
|
|
|
405
|
-
while (result.size() <
|
|
421
|
+
while (result.size() < static_cast<size_t>(R) &&
|
|
422
|
+
(++start) < static_cast<int>(pool.size()) && start < C) {
|
|
406
423
|
auto& p = pool[start];
|
|
407
424
|
bool occlude = false;
|
|
408
|
-
for (
|
|
425
|
+
for (size_t t = 0; t < result.size(); t++) {
|
|
409
426
|
if (p.id == result[t].id) {
|
|
410
427
|
occlude = true;
|
|
411
428
|
break;
|
|
@@ -421,8 +438,8 @@ void NSG::sync_prune(
|
|
|
421
438
|
}
|
|
422
439
|
}
|
|
423
440
|
|
|
424
|
-
for (
|
|
425
|
-
if (i < result.size()) {
|
|
441
|
+
for (int i = 0; i < R; i++) {
|
|
442
|
+
if (static_cast<size_t>(i) < result.size()) {
|
|
426
443
|
graph.at(q, i).id = result[i].id;
|
|
427
444
|
graph.at(q, i).distance = result[i].distance;
|
|
428
445
|
} else {
|
|
@@ -436,7 +453,7 @@ void NSG::add_reverse_links(
|
|
|
436
453
|
std::vector<std::mutex>& locks,
|
|
437
454
|
DistanceComputer& dis,
|
|
438
455
|
nsg::Graph<Node>& graph) {
|
|
439
|
-
for (
|
|
456
|
+
for (int i = 0; i < R; i++) {
|
|
440
457
|
if (graph.at(q, i).id == EMPTY_ID) {
|
|
441
458
|
break;
|
|
442
459
|
}
|
|
@@ -465,17 +482,18 @@ void NSG::add_reverse_links(
|
|
|
465
482
|
}
|
|
466
483
|
|
|
467
484
|
tmp_pool.push_back(sn);
|
|
468
|
-
if (tmp_pool.size() > R) {
|
|
485
|
+
if (tmp_pool.size() > static_cast<size_t>(R)) {
|
|
469
486
|
std::vector<Node> result;
|
|
470
487
|
int start = 0;
|
|
471
488
|
std::sort(tmp_pool.begin(), tmp_pool.end());
|
|
472
489
|
result.push_back(tmp_pool[start]);
|
|
473
490
|
|
|
474
|
-
while (result.size() <
|
|
491
|
+
while (result.size() < static_cast<size_t>(R) &&
|
|
492
|
+
(++start) < static_cast<int>(tmp_pool.size())) {
|
|
475
493
|
auto& p = tmp_pool[start];
|
|
476
494
|
bool occlude = false;
|
|
477
495
|
|
|
478
|
-
for (
|
|
496
|
+
for (size_t t = 0; t < result.size(); t++) {
|
|
479
497
|
if (p.id == result[t].id) {
|
|
480
498
|
occlude = true;
|
|
481
499
|
break;
|
|
@@ -494,7 +512,7 @@ void NSG::add_reverse_links(
|
|
|
494
512
|
|
|
495
513
|
{
|
|
496
514
|
LockGuard guard(locks[des]);
|
|
497
|
-
for (
|
|
515
|
+
for (size_t t = 0; t < result.size(); t++) {
|
|
498
516
|
graph.at(des, t) = result[t];
|
|
499
517
|
}
|
|
500
518
|
}
|
|
@@ -513,8 +531,8 @@ void NSG::add_reverse_links(
|
|
|
513
531
|
|
|
514
532
|
int NSG::tree_grow(Index* storage, std::vector<int>& degrees) {
|
|
515
533
|
int root = enterpoint;
|
|
516
|
-
VisitedTable vt(ntotal);
|
|
517
|
-
VisitedTable vt2(ntotal);
|
|
534
|
+
VisitedTable vt(ntotal, use_visited_hashset);
|
|
535
|
+
VisitedTable vt2(ntotal, use_visited_hashset);
|
|
518
536
|
|
|
519
537
|
int num_attached = 0;
|
|
520
538
|
int cnt = 0;
|
|
@@ -613,7 +631,7 @@ int NSG::attach_unlinked(
|
|
|
613
631
|
|
|
614
632
|
int node;
|
|
615
633
|
bool found = false;
|
|
616
|
-
for (
|
|
634
|
+
for (size_t i = 0; i < pool.size(); i++) {
|
|
617
635
|
node = pool[i].id;
|
|
618
636
|
if (degrees[node] < R && node != id) {
|
|
619
637
|
found = true;
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
#include <memory>
|
|
11
11
|
#include <mutex>
|
|
12
|
+
#include <optional>
|
|
12
13
|
#include <vector>
|
|
13
14
|
|
|
14
15
|
#include <omp.h>
|
|
15
16
|
|
|
16
17
|
#include <faiss/Index.h>
|
|
17
|
-
#include <faiss/impl/AuxIndexStructures.h>
|
|
18
18
|
#include <faiss/impl/FaissAssert.h>
|
|
19
19
|
#include <faiss/utils/Heap.h>
|
|
20
20
|
#include <faiss/utils/random.h>
|
|
@@ -38,6 +38,7 @@ namespace faiss {
|
|
|
38
38
|
*/
|
|
39
39
|
|
|
40
40
|
struct DistanceComputer; // from AuxIndexStructures
|
|
41
|
+
struct VisitedTable;
|
|
41
42
|
|
|
42
43
|
namespace nsg {
|
|
43
44
|
|
|
@@ -59,18 +60,20 @@ struct Graph {
|
|
|
59
60
|
bool own_fields; ///< the underlying data owned by itself or not
|
|
60
61
|
|
|
61
62
|
// construct from a known graph
|
|
62
|
-
Graph(node_t*
|
|
63
|
-
: data(
|
|
63
|
+
Graph(node_t* data_in, int N_in, int K_in)
|
|
64
|
+
: data(data_in), K(K_in), N(N_in), own_fields(false) {}
|
|
64
65
|
|
|
65
66
|
// construct an empty graph
|
|
66
67
|
// NOTE: the newly allocated data needs to be destroyed at destruction time
|
|
67
|
-
Graph(int
|
|
68
|
-
|
|
68
|
+
Graph(int N_in, int K_in) : K(K_in), N(N_in), own_fields(true) {
|
|
69
|
+
size_t total = faiss::mul_no_overflow(
|
|
70
|
+
(size_t)N_in, (size_t)K_in, "Graph allocation");
|
|
71
|
+
data = new node_t[total];
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
// copy constructor
|
|
72
75
|
Graph(const Graph& g) : Graph(g.N, g.K) {
|
|
73
|
-
memcpy(data, g.data, N * K * sizeof(node_t));
|
|
76
|
+
memcpy(data, g.data, (size_t)N * (size_t)K * sizeof(node_t));
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
// release the allocated memory if needed
|
|
@@ -82,21 +85,25 @@ struct Graph {
|
|
|
82
85
|
|
|
83
86
|
// access the j-th neighbor of node i
|
|
84
87
|
inline node_t at(int i, int j) const {
|
|
85
|
-
|
|
88
|
+
FAISS_CHECK_RANGE_DEBUG(i, 0, N);
|
|
89
|
+
FAISS_CHECK_RANGE_DEBUG(j, 0, K);
|
|
90
|
+
return data[(size_t)i * K + j];
|
|
86
91
|
}
|
|
87
92
|
|
|
88
93
|
// access the j-th neighbor of node i by reference
|
|
89
94
|
inline node_t& at(int i, int j) {
|
|
90
|
-
|
|
95
|
+
FAISS_CHECK_RANGE_DEBUG(i, 0, N);
|
|
96
|
+
FAISS_CHECK_RANGE_DEBUG(j, 0, K);
|
|
97
|
+
return data[(size_t)i * K + j];
|
|
91
98
|
}
|
|
92
99
|
|
|
93
100
|
// get all neighbors of node i (used during search only)
|
|
94
101
|
virtual size_t get_neighbors(int i, node_t* neighbors) const {
|
|
95
102
|
for (int j = 0; j < K; j++) {
|
|
96
|
-
if (data[i * K + j] < 0) {
|
|
103
|
+
if (data[(size_t)i * K + j] < 0) {
|
|
97
104
|
return j;
|
|
98
105
|
}
|
|
99
|
-
neighbors[j] = data[i * K + j];
|
|
106
|
+
neighbors[j] = data[(size_t)i * K + j];
|
|
100
107
|
}
|
|
101
108
|
return K;
|
|
102
109
|
}
|
|
@@ -122,6 +129,9 @@ struct NSG {
|
|
|
122
129
|
// search-time parameters
|
|
123
130
|
int search_L = 16; ///< length of the search path
|
|
124
131
|
|
|
132
|
+
// See impl/VisitedTable.h.
|
|
133
|
+
std::optional<bool> use_visited_hashset;
|
|
134
|
+
|
|
125
135
|
int enterpoint; ///< enterpoint
|
|
126
136
|
|
|
127
137
|
std::shared_ptr<nsg::Graph<int32_t>> final_graph; ///< NSG graph structure
|
|
@@ -10,23 +10,77 @@
|
|
|
10
10
|
#include <algorithm>
|
|
11
11
|
#include <cmath>
|
|
12
12
|
#include <cstring>
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
#include <faiss/impl/FaissAssert.h>
|
|
14
15
|
|
|
15
16
|
namespace faiss {
|
|
16
17
|
|
|
18
|
+
namespace {
|
|
19
|
+
|
|
20
|
+
/// Helper function to compute cumulative sums by iterating backwards through
|
|
21
|
+
/// levels. This is the core logic shared by compute_cumulative_sums and
|
|
22
|
+
/// compute_query_cum_sums.
|
|
23
|
+
template <typename OffsetFunc>
|
|
24
|
+
inline void compute_cum_sums_impl(
|
|
25
|
+
const float* vector,
|
|
26
|
+
float* output,
|
|
27
|
+
size_t d,
|
|
28
|
+
size_t n_levels,
|
|
29
|
+
size_t level_width_floats,
|
|
30
|
+
OffsetFunc&& get_offset) {
|
|
31
|
+
// Iterate backwards through levels, accumulating sum as we go.
|
|
32
|
+
// This avoids computing the suffix sum for each vector, which takes
|
|
33
|
+
// extra memory.
|
|
34
|
+
float sum = 0.0f;
|
|
35
|
+
|
|
36
|
+
for (int level = n_levels - 1; level >= 0; level--) {
|
|
37
|
+
size_t start_idx = level * level_width_floats;
|
|
38
|
+
size_t end_idx = std::min(
|
|
39
|
+
(level + 1) * level_width_floats, static_cast<size_t>(d));
|
|
40
|
+
|
|
41
|
+
for (size_t j = start_idx; j < end_idx; j++) {
|
|
42
|
+
sum += vector[j] * vector[j];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
output[get_offset(level)] = std::sqrt(sum);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
output[get_offset(n_levels)] = 0.0f;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
} // namespace
|
|
52
|
+
|
|
17
53
|
/**************************************************************
|
|
18
54
|
* Panorama structure implementation
|
|
19
55
|
**************************************************************/
|
|
20
56
|
|
|
21
|
-
Panorama::Panorama(
|
|
22
|
-
|
|
57
|
+
Panorama::Panorama(
|
|
58
|
+
size_t code_size_in,
|
|
59
|
+
size_t n_levels_in,
|
|
60
|
+
size_t batch_size_in)
|
|
61
|
+
: code_size(code_size_in),
|
|
62
|
+
n_levels(n_levels_in),
|
|
63
|
+
batch_size(batch_size_in) {
|
|
23
64
|
set_derived_values();
|
|
24
65
|
}
|
|
25
66
|
|
|
26
67
|
void Panorama::set_derived_values() {
|
|
68
|
+
FAISS_THROW_IF_NOT_MSG(n_levels > 0, "Panorama: n_levels must be > 0");
|
|
27
69
|
this->d = code_size / sizeof(float);
|
|
70
|
+
FAISS_THROW_IF_NOT_MSG(n_levels <= d, "Panorama: n_levels must be <= d");
|
|
28
71
|
this->level_width_floats = ((d + n_levels - 1) / n_levels);
|
|
29
72
|
this->level_width = this->level_width_floats * sizeof(float);
|
|
73
|
+
size_t n_real_levels = d / level_width_floats;
|
|
74
|
+
if (d > n_real_levels * level_width_floats) {
|
|
75
|
+
n_real_levels++;
|
|
76
|
+
}
|
|
77
|
+
if (this->n_levels != n_real_levels) {
|
|
78
|
+
fprintf(stderr,
|
|
79
|
+
"WARNING truncating nlevels from %zu to %zu\n",
|
|
80
|
+
this->n_levels,
|
|
81
|
+
n_real_levels);
|
|
82
|
+
this->n_levels = n_real_levels;
|
|
83
|
+
}
|
|
30
84
|
}
|
|
31
85
|
|
|
32
86
|
/**
|
|
@@ -69,64 +123,34 @@ void Panorama::compute_cumulative_sums(
|
|
|
69
123
|
float* cumsum_base,
|
|
70
124
|
size_t offset,
|
|
71
125
|
size_t n_entry,
|
|
72
|
-
const float* vectors) {
|
|
73
|
-
std::vector<float> suffix_sums(d + 1);
|
|
74
|
-
|
|
126
|
+
const float* vectors) const {
|
|
75
127
|
for (size_t entry_idx = 0; entry_idx < n_entry; entry_idx++) {
|
|
76
128
|
size_t current_pos = offset + entry_idx;
|
|
77
129
|
size_t batch_no = current_pos / batch_size;
|
|
78
130
|
size_t pos_in_batch = current_pos % batch_size;
|
|
79
131
|
|
|
80
132
|
const float* vector = vectors + entry_idx * d;
|
|
81
|
-
|
|
82
|
-
// Compute suffix sums of squared values.
|
|
83
|
-
suffix_sums[d] = 0.0f;
|
|
84
|
-
for (int j = d - 1; j >= 0; j--) {
|
|
85
|
-
float squared_val = vector[j] * vector[j];
|
|
86
|
-
suffix_sums[j] = suffix_sums[j + 1] + squared_val;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Store cumulative sums in batch-oriented layout.
|
|
90
133
|
size_t cumsum_batch_offset = batch_no * batch_size * (n_levels + 1);
|
|
91
134
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// Last level sum is always 0.
|
|
104
|
-
size_t cumsum_offset =
|
|
105
|
-
cumsum_batch_offset + n_levels * batch_size + pos_in_batch;
|
|
106
|
-
cumsum_base[cumsum_offset] = 0.0f;
|
|
135
|
+
auto get_offset = [&](size_t level) {
|
|
136
|
+
return cumsum_batch_offset + level * batch_size + pos_in_batch;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
compute_cum_sums_impl(
|
|
140
|
+
vector,
|
|
141
|
+
cumsum_base,
|
|
142
|
+
d,
|
|
143
|
+
n_levels,
|
|
144
|
+
level_width_floats,
|
|
145
|
+
get_offset);
|
|
107
146
|
}
|
|
108
147
|
}
|
|
109
148
|
|
|
110
149
|
void Panorama::compute_query_cum_sums(const float* query, float* query_cum_sums)
|
|
111
150
|
const {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
for (int j = d - 1; j >= 0; j--) {
|
|
116
|
-
float squared_val = query[j] * query[j];
|
|
117
|
-
suffix_sums[j] = suffix_sums[j + 1] + squared_val;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
for (size_t level = 0; level < n_levels; level++) {
|
|
121
|
-
size_t start_idx = level * level_width_floats;
|
|
122
|
-
if (start_idx < d) {
|
|
123
|
-
query_cum_sums[level] = std::sqrt(suffix_sums[start_idx]);
|
|
124
|
-
} else {
|
|
125
|
-
query_cum_sums[level] = 0.0f;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
query_cum_sums[n_levels] = 0.0f;
|
|
151
|
+
auto get_offset = [](size_t level) { return level; };
|
|
152
|
+
compute_cum_sums_impl(
|
|
153
|
+
query, query_cum_sums, d, n_levels, level_width_floats, get_offset);
|
|
130
154
|
}
|
|
131
155
|
|
|
132
156
|
void Panorama::reconstruct(idx_t key, float* recons, const uint8_t* codes_base)
|
|
@@ -139,12 +163,12 @@ void Panorama::reconstruct(idx_t key, float* recons, const uint8_t* codes_base)
|
|
|
139
163
|
|
|
140
164
|
for (size_t level = 0; level < n_levels; level++) {
|
|
141
165
|
size_t level_offset = level * level_width * batch_size;
|
|
166
|
+
size_t actual_level_width =
|
|
167
|
+
std::min(level_width, code_size - level * level_width);
|
|
142
168
|
const uint8_t* src = codes_base + batch_offset + level_offset +
|
|
143
|
-
pos_in_batch *
|
|
169
|
+
pos_in_batch * actual_level_width;
|
|
144
170
|
uint8_t* dest = recons_buffer + level * level_width;
|
|
145
|
-
|
|
146
|
-
std::min(level_width, code_size - level * level_width);
|
|
147
|
-
memcpy(dest, src, copy_size);
|
|
171
|
+
memcpy(dest, src, actual_level_width);
|
|
148
172
|
}
|
|
149
173
|
}
|
|
150
174
|
|