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
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
|
+
#include <optional>
|
|
10
11
|
#include <queue>
|
|
11
12
|
#include <vector>
|
|
12
13
|
|
|
@@ -16,7 +17,6 @@
|
|
|
16
17
|
#include <faiss/impl/DistanceComputer.h>
|
|
17
18
|
#include <faiss/impl/FaissAssert.h>
|
|
18
19
|
#include <faiss/impl/maybe_owned_vector.h>
|
|
19
|
-
#include <faiss/impl/platform_macros.h>
|
|
20
20
|
#include <faiss/utils/Heap.h>
|
|
21
21
|
#include <faiss/utils/random.h>
|
|
22
22
|
|
|
@@ -25,6 +25,8 @@ namespace faiss {
|
|
|
25
25
|
// Forward declarations to avoid circular dependency.
|
|
26
26
|
struct IndexHNSW;
|
|
27
27
|
struct IndexHNSWFlatPanorama;
|
|
28
|
+
struct MinimaxHeap;
|
|
29
|
+
class LockVector;
|
|
28
30
|
|
|
29
31
|
/** Implementation of the Hierarchical Navigable Small World
|
|
30
32
|
* datastructure.
|
|
@@ -45,8 +47,6 @@ struct IndexHNSWFlatPanorama;
|
|
|
45
47
|
struct VisitedTable;
|
|
46
48
|
struct DistanceComputer; // from AuxIndexStructures
|
|
47
49
|
struct HNSWStats;
|
|
48
|
-
template <class C>
|
|
49
|
-
struct ResultHandler;
|
|
50
50
|
|
|
51
51
|
struct SearchParametersHNSW : SearchParameters {
|
|
52
52
|
int efSearch = 16;
|
|
@@ -65,37 +65,11 @@ struct HNSW {
|
|
|
65
65
|
|
|
66
66
|
typedef std::pair<float, storage_idx_t> Node;
|
|
67
67
|
|
|
68
|
-
/** Heap structure that allows fast access and updates.
|
|
69
|
-
*/
|
|
70
|
-
struct MinimaxHeap {
|
|
71
|
-
int n;
|
|
72
|
-
int k;
|
|
73
|
-
int nvalid;
|
|
74
|
-
|
|
75
|
-
std::vector<storage_idx_t> ids;
|
|
76
|
-
std::vector<float> dis;
|
|
77
|
-
typedef faiss::CMax<float, storage_idx_t> HC;
|
|
78
|
-
|
|
79
|
-
explicit MinimaxHeap(int n) : n(n), k(0), nvalid(0), ids(n), dis(n) {}
|
|
80
|
-
|
|
81
|
-
void push(storage_idx_t i, float v);
|
|
82
|
-
|
|
83
|
-
float max() const;
|
|
84
|
-
|
|
85
|
-
int size() const;
|
|
86
|
-
|
|
87
|
-
void clear();
|
|
88
|
-
|
|
89
|
-
int pop_min(float* vmin_out = nullptr);
|
|
90
|
-
|
|
91
|
-
int count_below(float thresh);
|
|
92
|
-
};
|
|
93
|
-
|
|
94
68
|
/// to sort pairs of (id, distance) from nearest to farthest or the reverse
|
|
95
69
|
struct NodeDistCloser {
|
|
96
70
|
float d;
|
|
97
71
|
int id;
|
|
98
|
-
NodeDistCloser(float
|
|
72
|
+
NodeDistCloser(float d_in, int id_in) : d(d_in), id(id_in) {}
|
|
99
73
|
bool operator<(const NodeDistCloser& obj1) const {
|
|
100
74
|
return d < obj1.d;
|
|
101
75
|
}
|
|
@@ -104,7 +78,7 @@ struct HNSW {
|
|
|
104
78
|
struct NodeDistFarther {
|
|
105
79
|
float d;
|
|
106
80
|
int id;
|
|
107
|
-
NodeDistFarther(float
|
|
81
|
+
NodeDistFarther(float d_in, int id_in) : d(d_in), id(id_in) {}
|
|
108
82
|
bool operator<(const NodeDistFarther& obj1) const {
|
|
109
83
|
return d > obj1.d;
|
|
110
84
|
}
|
|
@@ -143,6 +117,10 @@ struct HNSW {
|
|
|
143
117
|
/// expansion factor at search time
|
|
144
118
|
int efSearch = 16;
|
|
145
119
|
|
|
120
|
+
/// when pruning, leave room for more neighbors to avoid O(n^2)
|
|
121
|
+
/// costs and lock contention on frequently-pruned nodes.
|
|
122
|
+
float prune_headroom = 0.2f;
|
|
123
|
+
|
|
146
124
|
/// during search: do we check whether the next best distance is good
|
|
147
125
|
/// enough?
|
|
148
126
|
bool check_relative_distance = true;
|
|
@@ -153,6 +131,9 @@ struct HNSW {
|
|
|
153
131
|
/// use Panorama progressive pruning in search
|
|
154
132
|
bool is_panorama = false;
|
|
155
133
|
|
|
134
|
+
// See impl/VisitedTable.h.
|
|
135
|
+
std::optional<bool> use_visited_hashset;
|
|
136
|
+
|
|
156
137
|
// methods that initialize the tree sizes
|
|
157
138
|
|
|
158
139
|
/// initialize the assign_probas and cum_nneighbor_per_level to
|
|
@@ -189,7 +170,7 @@ struct HNSW {
|
|
|
189
170
|
storage_idx_t nearest,
|
|
190
171
|
float d_nearest,
|
|
191
172
|
int level,
|
|
192
|
-
|
|
173
|
+
LockVector& locks,
|
|
193
174
|
VisitedTable& vt,
|
|
194
175
|
bool keep_max_size_level0 = false);
|
|
195
176
|
|
|
@@ -199,7 +180,7 @@ struct HNSW {
|
|
|
199
180
|
DistanceComputer& ptdis,
|
|
200
181
|
int pt_level,
|
|
201
182
|
int pt_id,
|
|
202
|
-
|
|
183
|
+
LockVector& locks,
|
|
203
184
|
VisitedTable& vt,
|
|
204
185
|
bool keep_max_size_level0 = false);
|
|
205
186
|
|
|
@@ -212,14 +193,14 @@ struct HNSW {
|
|
|
212
193
|
HNSWStats search(
|
|
213
194
|
DistanceComputer& qdis,
|
|
214
195
|
const IndexHNSW* index,
|
|
215
|
-
ResultHandler
|
|
196
|
+
ResultHandler& res,
|
|
216
197
|
VisitedTable& vt,
|
|
217
198
|
const SearchParameters* params = nullptr) const;
|
|
218
199
|
|
|
219
200
|
/// search only in level 0 from a given vertex
|
|
220
201
|
void search_level_0(
|
|
221
202
|
DistanceComputer& qdis,
|
|
222
|
-
ResultHandler
|
|
203
|
+
ResultHandler& res,
|
|
223
204
|
idx_t nprobe,
|
|
224
205
|
const storage_idx_t* nearest_i,
|
|
225
206
|
const float* nearest_d,
|
|
@@ -239,7 +220,7 @@ struct HNSW {
|
|
|
239
220
|
DistanceComputer& qdis,
|
|
240
221
|
std::priority_queue<NodeDistFarther>& input,
|
|
241
222
|
std::vector<NodeDistFarther>& output,
|
|
242
|
-
|
|
223
|
+
size_t max_size,
|
|
243
224
|
bool keep_max_size_level0 = false);
|
|
244
225
|
|
|
245
226
|
void permute_entries(const idx_t* map);
|
|
@@ -272,8 +253,8 @@ FAISS_API extern HNSWStats hnsw_stats;
|
|
|
272
253
|
int search_from_candidates(
|
|
273
254
|
const HNSW& hnsw,
|
|
274
255
|
DistanceComputer& qdis,
|
|
275
|
-
ResultHandler
|
|
276
|
-
|
|
256
|
+
ResultHandler& res,
|
|
257
|
+
MinimaxHeap& candidates,
|
|
277
258
|
VisitedTable& vt,
|
|
278
259
|
HNSWStats& stats,
|
|
279
260
|
int level,
|
|
@@ -288,8 +269,8 @@ int search_from_candidates_panorama(
|
|
|
288
269
|
const HNSW& hnsw,
|
|
289
270
|
const IndexHNSW* index,
|
|
290
271
|
DistanceComputer& qdis,
|
|
291
|
-
ResultHandler
|
|
292
|
-
|
|
272
|
+
ResultHandler& res,
|
|
273
|
+
MinimaxHeap& candidates,
|
|
293
274
|
VisitedTable& vt,
|
|
294
275
|
HNSWStats& stats,
|
|
295
276
|
int level,
|
|
@@ -14,8 +14,11 @@ namespace faiss {
|
|
|
14
14
|
* IDSelectorRange
|
|
15
15
|
***********************************************************************/
|
|
16
16
|
|
|
17
|
-
IDSelectorRange::IDSelectorRange(
|
|
18
|
-
|
|
17
|
+
IDSelectorRange::IDSelectorRange(
|
|
18
|
+
idx_t imin_in,
|
|
19
|
+
idx_t imax_in,
|
|
20
|
+
bool assume_sorted_in)
|
|
21
|
+
: imin(imin_in), imax(imax_in), assume_sorted(assume_sorted_in) {}
|
|
19
22
|
|
|
20
23
|
bool IDSelectorRange::is_member(idx_t id) const {
|
|
21
24
|
return id >= imin && id < imax;
|
|
@@ -67,10 +70,11 @@ void IDSelectorRange::find_sorted_ids_bounds(
|
|
|
67
70
|
* IDSelectorArray
|
|
68
71
|
***********************************************************************/
|
|
69
72
|
|
|
70
|
-
IDSelectorArray::IDSelectorArray(size_t
|
|
73
|
+
IDSelectorArray::IDSelectorArray(size_t n_in, const idx_t* ids_in)
|
|
74
|
+
: n(n_in), ids(ids_in) {}
|
|
71
75
|
|
|
72
76
|
bool IDSelectorArray::is_member(idx_t id) const {
|
|
73
|
-
for (
|
|
77
|
+
for (size_t i = 0; i < n; i++) {
|
|
74
78
|
if (ids[i] == id) {
|
|
75
79
|
return true;
|
|
76
80
|
}
|
|
@@ -84,15 +88,15 @@ bool IDSelectorArray::is_member(idx_t id) const {
|
|
|
84
88
|
|
|
85
89
|
IDSelectorBatch::IDSelectorBatch(size_t n, const idx_t* indices) {
|
|
86
90
|
nbits = 0;
|
|
87
|
-
while (n > (
|
|
91
|
+
while (n > (size_t{1} << nbits)) {
|
|
88
92
|
nbits++;
|
|
89
93
|
}
|
|
90
94
|
nbits += 5;
|
|
91
95
|
// for n = 1M, nbits = 25 is optimal, see P56659518
|
|
92
96
|
|
|
93
97
|
mask = ((idx_t)1 << nbits) - 1;
|
|
94
|
-
bloom.resize(
|
|
95
|
-
for (
|
|
98
|
+
bloom.resize(size_t{1} << (nbits - 3), 0);
|
|
99
|
+
for (size_t i = 0; i < n; i++) {
|
|
96
100
|
idx_t id = indices[i];
|
|
97
101
|
set.insert(id);
|
|
98
102
|
id &= mask;
|
|
@@ -101,9 +105,9 @@ IDSelectorBatch::IDSelectorBatch(size_t n, const idx_t* indices) {
|
|
|
101
105
|
}
|
|
102
106
|
|
|
103
107
|
bool IDSelectorBatch::is_member(idx_t i) const {
|
|
104
|
-
|
|
108
|
+
idx_t im = i & mask;
|
|
105
109
|
if (!(bloom[im >> 3] & (1 << (im & 7)))) {
|
|
106
|
-
return
|
|
110
|
+
return false;
|
|
107
111
|
}
|
|
108
112
|
return set.count(i);
|
|
109
113
|
}
|
|
@@ -112,8 +116,8 @@ bool IDSelectorBatch::is_member(idx_t i) const {
|
|
|
112
116
|
* IDSelectorBitmap
|
|
113
117
|
***********************************************************************/
|
|
114
118
|
|
|
115
|
-
IDSelectorBitmap::IDSelectorBitmap(size_t
|
|
116
|
-
: n(
|
|
119
|
+
IDSelectorBitmap::IDSelectorBitmap(size_t n_in, const uint8_t* bitmap_in)
|
|
120
|
+
: n(n_in), bitmap(bitmap_in) {}
|
|
117
121
|
|
|
118
122
|
bool IDSelectorBitmap::is_member(idx_t ii) const {
|
|
119
123
|
uint64_t i = ii;
|
|
@@ -116,7 +116,7 @@ struct IDSelectorBitmap : IDSelector {
|
|
|
116
116
|
/** reverts the membership test of another selector */
|
|
117
117
|
struct IDSelectorNot : IDSelector {
|
|
118
118
|
const IDSelector* sel;
|
|
119
|
-
explicit IDSelectorNot(const IDSelector*
|
|
119
|
+
explicit IDSelectorNot(const IDSelector* sel_) : sel(sel_) {}
|
|
120
120
|
bool is_member(idx_t id) const final {
|
|
121
121
|
return !sel->is_member(id);
|
|
122
122
|
}
|
|
@@ -125,7 +125,7 @@ struct IDSelectorNot : IDSelector {
|
|
|
125
125
|
|
|
126
126
|
/// selects all entries (useful for benchmarking)
|
|
127
127
|
struct IDSelectorAll : IDSelector {
|
|
128
|
-
bool is_member(idx_t id) const final {
|
|
128
|
+
bool is_member(idx_t /* id */) const final {
|
|
129
129
|
return true;
|
|
130
130
|
}
|
|
131
131
|
virtual ~IDSelectorAll() {}
|
|
@@ -136,8 +136,8 @@ struct IDSelectorAll : IDSelector {
|
|
|
136
136
|
struct IDSelectorAnd : IDSelector {
|
|
137
137
|
const IDSelector* lhs;
|
|
138
138
|
const IDSelector* rhs;
|
|
139
|
-
IDSelectorAnd(const IDSelector*
|
|
140
|
-
: lhs(
|
|
139
|
+
IDSelectorAnd(const IDSelector* lhs_, const IDSelector* rhs_)
|
|
140
|
+
: lhs(lhs_), rhs(rhs_) {}
|
|
141
141
|
bool is_member(idx_t id) const final {
|
|
142
142
|
return lhs->is_member(id) && rhs->is_member(id);
|
|
143
143
|
}
|
|
@@ -149,8 +149,8 @@ struct IDSelectorAnd : IDSelector {
|
|
|
149
149
|
struct IDSelectorOr : IDSelector {
|
|
150
150
|
const IDSelector* lhs;
|
|
151
151
|
const IDSelector* rhs;
|
|
152
|
-
IDSelectorOr(const IDSelector*
|
|
153
|
-
: lhs(
|
|
152
|
+
IDSelectorOr(const IDSelector* lhs_, const IDSelector* rhs_)
|
|
153
|
+
: lhs(lhs_), rhs(rhs_) {}
|
|
154
154
|
bool is_member(idx_t id) const final {
|
|
155
155
|
return lhs->is_member(id) || rhs->is_member(id);
|
|
156
156
|
}
|
|
@@ -162,8 +162,8 @@ struct IDSelectorOr : IDSelector {
|
|
|
162
162
|
struct IDSelectorXOr : IDSelector {
|
|
163
163
|
const IDSelector* lhs;
|
|
164
164
|
const IDSelector* rhs;
|
|
165
|
-
IDSelectorXOr(const IDSelector*
|
|
166
|
-
: lhs(
|
|
165
|
+
IDSelectorXOr(const IDSelector* lhs_, const IDSelector* rhs_)
|
|
166
|
+
: lhs(lhs_), rhs(rhs_) {}
|
|
167
167
|
bool is_member(idx_t id) const final {
|
|
168
168
|
return lhs->is_member(id) ^ rhs->is_member(id);
|
|
169
169
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* 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
|
+
#ifndef FAISS_INVERTED_LIST_SCANNER_STATS_H
|
|
9
|
+
#define FAISS_INVERTED_LIST_SCANNER_STATS_H
|
|
10
|
+
|
|
11
|
+
#include <cstddef>
|
|
12
|
+
|
|
13
|
+
namespace faiss {
|
|
14
|
+
|
|
15
|
+
/** Per-list statistics returned by inverted-list scanners. */
|
|
16
|
+
struct InvertedListScannerStats {
|
|
17
|
+
/// Number of distances computed after IDSelector filtering.
|
|
18
|
+
size_t scan_cnt = 0;
|
|
19
|
+
|
|
20
|
+
/// Number of heap updates.
|
|
21
|
+
size_t nheap_updates = 0;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
} // namespace faiss
|
|
25
|
+
|
|
26
|
+
#endif
|
|
@@ -18,14 +18,15 @@
|
|
|
18
18
|
|
|
19
19
|
#include <faiss/impl/AuxIndexStructures.h>
|
|
20
20
|
#include <faiss/impl/FaissAssert.h>
|
|
21
|
+
#include <faiss/impl/simd_dispatch.h>
|
|
21
22
|
#include <faiss/utils/distances.h>
|
|
22
23
|
#include <faiss/utils/utils.h>
|
|
23
24
|
|
|
24
|
-
#include <faiss/
|
|
25
|
+
#include <faiss/impl/approx_topk/approx_topk.h>
|
|
25
26
|
|
|
26
27
|
// this is needed for prefetching
|
|
27
28
|
|
|
28
|
-
#ifdef
|
|
29
|
+
#ifdef COMPILE_SIMD_AVX2
|
|
29
30
|
#include <xmmintrin.h>
|
|
30
31
|
#endif
|
|
31
32
|
|
|
@@ -153,12 +154,15 @@ lsq::LSQTimer lsq_timer;
|
|
|
153
154
|
using lsq::LSQTimerScope;
|
|
154
155
|
|
|
155
156
|
LocalSearchQuantizer::LocalSearchQuantizer(
|
|
156
|
-
size_t
|
|
157
|
-
size_t
|
|
158
|
-
size_t
|
|
159
|
-
Search_type_t
|
|
160
|
-
: AdditiveQuantizer(
|
|
161
|
-
|
|
157
|
+
size_t d_in,
|
|
158
|
+
size_t M_in,
|
|
159
|
+
size_t nbits_in,
|
|
160
|
+
Search_type_t search_type_in)
|
|
161
|
+
: AdditiveQuantizer(
|
|
162
|
+
d_in,
|
|
163
|
+
std::vector<size_t>(M_in, nbits_in),
|
|
164
|
+
search_type_in) {
|
|
165
|
+
K = (1 << nbits_in);
|
|
162
166
|
std::srand(random_seed);
|
|
163
167
|
}
|
|
164
168
|
|
|
@@ -169,7 +173,7 @@ LocalSearchQuantizer::~LocalSearchQuantizer() {
|
|
|
169
173
|
LocalSearchQuantizer::LocalSearchQuantizer() : LocalSearchQuantizer(0, 0, 0) {}
|
|
170
174
|
|
|
171
175
|
void LocalSearchQuantizer::train(size_t n, const float* x) {
|
|
172
|
-
FAISS_THROW_IF_NOT(K == (1 << nbits[0]));
|
|
176
|
+
FAISS_THROW_IF_NOT(K == static_cast<size_t>(1 << nbits[0]));
|
|
173
177
|
nperts = std::min(nperts, M);
|
|
174
178
|
|
|
175
179
|
lsq_timer.reset();
|
|
@@ -193,7 +197,7 @@ void LocalSearchQuantizer::train(size_t n, const float* x) {
|
|
|
193
197
|
std::vector<float> stddev(d, 0);
|
|
194
198
|
|
|
195
199
|
#pragma omp parallel for
|
|
196
|
-
for (int64_t i = 0; i < d; i++) {
|
|
200
|
+
for (int64_t i = 0; i < static_cast<int64_t>(d); i++) {
|
|
197
201
|
float mean = 0;
|
|
198
202
|
for (size_t j = 0; j < n; j++) {
|
|
199
203
|
mean += x[j * d + i];
|
|
@@ -361,7 +365,7 @@ void LocalSearchQuantizer::update_codebooks(
|
|
|
361
365
|
}
|
|
362
366
|
|
|
363
367
|
// add a regularization term to B'B
|
|
364
|
-
for (
|
|
368
|
+
for (size_t i = 0; i < M * K; i++) {
|
|
365
369
|
bb[i * (M * K) + i] += lambd;
|
|
366
370
|
}
|
|
367
371
|
|
|
@@ -426,7 +430,7 @@ void LocalSearchQuantizer::update_codebooks(
|
|
|
426
430
|
}
|
|
427
431
|
|
|
428
432
|
// add a regularization term to B'B
|
|
429
|
-
for (
|
|
433
|
+
for (size_t i = 0; i < M * K; i++) {
|
|
430
434
|
bb[i * (M * K) + i] += lambd;
|
|
431
435
|
}
|
|
432
436
|
|
|
@@ -539,7 +543,7 @@ void LocalSearchQuantizer::icm_encode_impl(
|
|
|
539
543
|
std::mt19937& gen,
|
|
540
544
|
size_t n,
|
|
541
545
|
size_t ils_iters,
|
|
542
|
-
bool
|
|
546
|
+
bool verbose_in) const {
|
|
543
547
|
std::vector<float> unaries(n * M * K); // [M, n, K]
|
|
544
548
|
compute_unary_terms(x, unaries.data(), n);
|
|
545
549
|
|
|
@@ -563,7 +567,7 @@ void LocalSearchQuantizer::icm_encode_impl(
|
|
|
563
567
|
|
|
564
568
|
// select the best code for every vector xi
|
|
565
569
|
#pragma omp parallel for reduction(+ : n_betters, mean_obj)
|
|
566
|
-
for (int64_t i = 0; i < n; i++) {
|
|
570
|
+
for (int64_t i = 0; i < static_cast<int64_t>(n); i++) {
|
|
567
571
|
if (icm_objs[i] < best_objs[i]) {
|
|
568
572
|
best_objs[i] = icm_objs[i];
|
|
569
573
|
memcpy(best_codes.data() + i * M,
|
|
@@ -577,7 +581,7 @@ void LocalSearchQuantizer::icm_encode_impl(
|
|
|
577
581
|
|
|
578
582
|
memcpy(codes, best_codes.data(), sizeof(int32_t) * n * M);
|
|
579
583
|
|
|
580
|
-
if (
|
|
584
|
+
if (verbose_in) {
|
|
581
585
|
printf("\tils_iter %zd: obj = %lf, n_betters/n = %zd/%zd\n",
|
|
582
586
|
iter1,
|
|
583
587
|
mean_obj,
|
|
@@ -596,73 +600,75 @@ void LocalSearchQuantizer::icm_encode_step(
|
|
|
596
600
|
FAISS_THROW_IF_NOT(M != 0 && K != 0);
|
|
597
601
|
FAISS_THROW_IF_NOT(binaries != nullptr);
|
|
598
602
|
|
|
603
|
+
// Resolve SIMD level once, not per iteration of the n × n_iters × M loop.
|
|
604
|
+
with_simd_level_256bit([&]<SIMDLevel SL>() {
|
|
599
605
|
#pragma omp parallel for schedule(dynamic)
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
// compute objective function by adding unary
|
|
613
|
-
// and binary terms together
|
|
614
|
-
for (size_t other_m = 0; other_m < M; other_m++) {
|
|
615
|
-
if (other_m == m) {
|
|
616
|
-
continue;
|
|
606
|
+
for (int64_t i = 0; i < static_cast<int64_t>(n); i++) {
|
|
607
|
+
std::vector<float> objs(K);
|
|
608
|
+
|
|
609
|
+
for (size_t iter = 0; iter < n_iters; iter++) {
|
|
610
|
+
// condition on the m-th subcode
|
|
611
|
+
for (size_t m = 0; m < M; m++) {
|
|
612
|
+
// copy
|
|
613
|
+
auto u = unaries + m * n * K + i * K;
|
|
614
|
+
for (size_t code = 0; code < K; code++) {
|
|
615
|
+
objs[code] = u[code];
|
|
617
616
|
}
|
|
618
617
|
|
|
619
|
-
|
|
620
|
-
//
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
618
|
+
// compute objective function by adding unary
|
|
619
|
+
// and binary terms together
|
|
620
|
+
for (size_t other_m = 0; other_m < M; other_m++) {
|
|
621
|
+
if (other_m == m) {
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
#ifdef COMPILE_SIMD_AVX2
|
|
626
|
+
// TODO: add platform-independent compiler-independent
|
|
627
|
+
// prefetch utilities.
|
|
628
|
+
if (other_m + 1 < M) {
|
|
629
|
+
// do a single prefetch
|
|
630
|
+
int32_t code2 = codes[i * M + other_m + 1];
|
|
631
|
+
// for (int32_t code = 0; code < K; code += 64) {
|
|
632
|
+
int32_t code = 0;
|
|
633
|
+
{
|
|
634
|
+
size_t binary_idx = (other_m + 1) * M * K * K +
|
|
635
|
+
m * K * K + code2 * K + code;
|
|
636
|
+
_mm_prefetch(
|
|
637
|
+
(const char*)(binaries + binary_idx),
|
|
638
|
+
_MM_HINT_T0);
|
|
639
|
+
}
|
|
633
640
|
}
|
|
634
|
-
}
|
|
635
641
|
#endif
|
|
636
642
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
643
|
+
for (size_t code = 0; code < K; code++) {
|
|
644
|
+
int32_t code2 = codes[i * M + other_m];
|
|
645
|
+
size_t binary_idx = other_m * M * K * K +
|
|
646
|
+
m * K * K + code2 * K + code;
|
|
647
|
+
// binaries[m, other_m, code, code2].
|
|
648
|
+
// It is symmetric over (m <-> other_m)
|
|
649
|
+
// and (code <-> code2).
|
|
650
|
+
// So, replace the op with
|
|
651
|
+
// binaries[other_m, m, code2, code].
|
|
652
|
+
objs[code] += binaries[binary_idx];
|
|
653
|
+
}
|
|
647
654
|
}
|
|
648
|
-
}
|
|
649
655
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
656
|
+
// find the optimal value of the m-th subcode
|
|
657
|
+
float best_obj = HUGE_VALF;
|
|
658
|
+
int32_t best_code = 0;
|
|
653
659
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
K, objs.data(), 1, &best_obj, &best_code);
|
|
660
|
+
// find one using SIMD. The following operation is similar
|
|
661
|
+
// to the search of the smallest element in objs
|
|
662
|
+
HeapWithBucketsCMaxFloat<16, 1, SL>::addn(
|
|
663
|
+
K, objs.data(), 1, &best_obj, &best_code);
|
|
659
664
|
|
|
660
|
-
|
|
661
|
-
|
|
665
|
+
// done
|
|
666
|
+
codes[i * M + m] = best_code;
|
|
662
667
|
|
|
663
|
-
|
|
668
|
+
} // loop M
|
|
669
|
+
}
|
|
664
670
|
}
|
|
665
|
-
}
|
|
671
|
+
});
|
|
666
672
|
}
|
|
667
673
|
void LocalSearchQuantizer::perturb_codes(
|
|
668
674
|
int32_t* codes,
|
|
@@ -684,22 +690,24 @@ void LocalSearchQuantizer::perturb_codes(
|
|
|
684
690
|
void LocalSearchQuantizer::compute_binary_terms(float* binaries) const {
|
|
685
691
|
LSQTimerScope scope(&lsq_timer, "compute_binary_terms");
|
|
686
692
|
|
|
693
|
+
with_simd_level([&]<SIMDLevel SL>() {
|
|
687
694
|
#pragma omp parallel for
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
695
|
+
for (int64_t m12 = 0; m12 < static_cast<int64_t>(M * M); m12++) {
|
|
696
|
+
size_t m1 = m12 / M;
|
|
697
|
+
size_t m2 = m12 % M;
|
|
698
|
+
|
|
699
|
+
for (size_t code1 = 0; code1 < K; code1++) {
|
|
700
|
+
for (size_t code2 = 0; code2 < K; code2++) {
|
|
701
|
+
const float* c1 = codebooks.data() + m1 * K * d + code1 * d;
|
|
702
|
+
const float* c2 = codebooks.data() + m2 * K * d + code2 * d;
|
|
703
|
+
float ip = fvec_inner_product<SL>(c1, c2, d);
|
|
704
|
+
// binaries[m1, m2, code1, code2] = ip * 2
|
|
705
|
+
binaries[m1 * M * K * K + m2 * K * K + code1 * K + code2] =
|
|
706
|
+
ip * 2;
|
|
707
|
+
}
|
|
700
708
|
}
|
|
701
709
|
}
|
|
702
|
-
}
|
|
710
|
+
});
|
|
703
711
|
}
|
|
704
712
|
|
|
705
713
|
void LocalSearchQuantizer::compute_unary_terms(
|
|
@@ -741,7 +749,7 @@ void LocalSearchQuantizer::compute_unary_terms(
|
|
|
741
749
|
fvec_norms_L2sqr(norms.data(), codebooks.data(), d, M * K);
|
|
742
750
|
|
|
743
751
|
#pragma omp parallel for
|
|
744
|
-
for (int64_t i = 0; i < n; i++) {
|
|
752
|
+
for (int64_t i = 0; i < static_cast<int64_t>(n); i++) {
|
|
745
753
|
for (size_t m = 0; m < M; m++) {
|
|
746
754
|
float* u = unaries + m * n * K + i * K;
|
|
747
755
|
fvec_add(K, u, norms.data() + m * K, u);
|
|
@@ -760,23 +768,27 @@ float LocalSearchQuantizer::evaluate(
|
|
|
760
768
|
std::vector<float> decoded_x(n * d, 0.0f);
|
|
761
769
|
float obj = 0.0f;
|
|
762
770
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
771
|
+
with_simd_level([&]<SIMDLevel SL>() {
|
|
772
|
+
float local_obj = 0.0f;
|
|
773
|
+
#pragma omp parallel for reduction(+ : local_obj)
|
|
774
|
+
for (int64_t i = 0; i < static_cast<int64_t>(n); i++) {
|
|
775
|
+
const auto code = codes + i * M;
|
|
776
|
+
const auto decoded_i = decoded_x.data() + i * d;
|
|
777
|
+
for (size_t m = 0; m < M; m++) {
|
|
778
|
+
// c = codebooks[m, code[m]]
|
|
779
|
+
const auto c = codebooks.data() + m * K * d + code[m] * d;
|
|
780
|
+
fvec_add(d, decoded_i, c, decoded_i);
|
|
781
|
+
}
|
|
772
782
|
|
|
773
|
-
|
|
774
|
-
|
|
783
|
+
float err = fvec_L2sqr<SL>(x + i * d, decoded_i, d);
|
|
784
|
+
local_obj += err;
|
|
775
785
|
|
|
776
|
-
|
|
777
|
-
|
|
786
|
+
if (objs) {
|
|
787
|
+
objs[i] = err;
|
|
788
|
+
}
|
|
778
789
|
}
|
|
779
|
-
|
|
790
|
+
obj = local_obj;
|
|
791
|
+
});
|
|
780
792
|
|
|
781
793
|
obj = obj / n;
|
|
782
794
|
return obj;
|
|
@@ -784,8 +796,8 @@ float LocalSearchQuantizer::evaluate(
|
|
|
784
796
|
|
|
785
797
|
namespace lsq {
|
|
786
798
|
|
|
787
|
-
IcmEncoder::IcmEncoder(const LocalSearchQuantizer*
|
|
788
|
-
: verbose(false), lsq(
|
|
799
|
+
IcmEncoder::IcmEncoder(const LocalSearchQuantizer* lsq_in)
|
|
800
|
+
: verbose(false), lsq(lsq_in) {}
|
|
789
801
|
|
|
790
802
|
void IcmEncoder::set_binary_term() {
|
|
791
803
|
auto M = lsq->M;
|
|
@@ -823,8 +835,8 @@ void LSQTimer::reset() {
|
|
|
823
835
|
t.clear();
|
|
824
836
|
}
|
|
825
837
|
|
|
826
|
-
LSQTimerScope::LSQTimerScope(LSQTimer*
|
|
827
|
-
: timer(
|
|
838
|
+
LSQTimerScope::LSQTimerScope(LSQTimer* timer_in, std::string name_in)
|
|
839
|
+
: timer(timer_in), name(std::move(name_in)), finished(false) {
|
|
828
840
|
t0 = getmillisecs();
|
|
829
841
|
}
|
|
830
842
|
|