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
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
#include <cstdio>
|
|
15
15
|
|
|
16
16
|
#include <algorithm>
|
|
17
|
+
#include <limits>
|
|
17
18
|
#include <memory>
|
|
18
19
|
|
|
19
20
|
#include <faiss/IndexFlat.h>
|
|
@@ -24,22 +25,33 @@
|
|
|
24
25
|
#include <faiss/utils/sorting.h>
|
|
25
26
|
#include <faiss/utils/utils.h>
|
|
26
27
|
|
|
28
|
+
#include <faiss/impl/simd_dispatch.h>
|
|
29
|
+
|
|
30
|
+
// Scalar (NONE) fallback for dynamic dispatch
|
|
31
|
+
#define THE_SIMD_LEVEL SIMDLevel::NONE
|
|
32
|
+
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
33
|
+
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
34
|
+
#include <faiss/impl/binary_hamming/IndexBinaryIVF_impl.h>
|
|
35
|
+
#include <faiss/utils/hamming_distance/hamming_computer-generic.h>
|
|
36
|
+
#undef THE_SIMD_LEVEL
|
|
37
|
+
|
|
27
38
|
namespace faiss {
|
|
28
39
|
|
|
29
40
|
IndexBinaryIVF::IndexBinaryIVF(
|
|
30
|
-
IndexBinary*
|
|
31
|
-
size_t
|
|
32
|
-
size_t
|
|
33
|
-
bool
|
|
34
|
-
: IndexBinary(
|
|
41
|
+
IndexBinary* quantizer_,
|
|
42
|
+
size_t d_,
|
|
43
|
+
size_t nlist_,
|
|
44
|
+
bool own_invlists_)
|
|
45
|
+
: IndexBinary(d_),
|
|
35
46
|
invlists(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
own_invlists(
|
|
39
|
-
quantizer(
|
|
40
|
-
nlist(
|
|
41
|
-
FAISS_THROW_IF_NOT(
|
|
42
|
-
is_trained =
|
|
47
|
+
own_invlists_ ? new ArrayInvertedLists(nlist_, code_size)
|
|
48
|
+
: nullptr),
|
|
49
|
+
own_invlists(own_invlists_),
|
|
50
|
+
quantizer(quantizer_),
|
|
51
|
+
nlist(nlist_) {
|
|
52
|
+
FAISS_THROW_IF_NOT(d_ == static_cast<size_t>(quantizer_->d));
|
|
53
|
+
is_trained = quantizer_->is_trained &&
|
|
54
|
+
(static_cast<size_t>(quantizer_->ntotal) == nlist_);
|
|
43
55
|
cp.niter = 10;
|
|
44
56
|
}
|
|
45
57
|
|
|
@@ -62,7 +74,7 @@ void IndexBinaryIVF::add_core(
|
|
|
62
74
|
const idx_t* xids,
|
|
63
75
|
const idx_t* precomputed_idx) {
|
|
64
76
|
FAISS_THROW_IF_NOT(is_trained);
|
|
65
|
-
|
|
77
|
+
FAISS_THROW_IF_NOT_MSG(invlists, "invlists not initialized");
|
|
66
78
|
direct_map.check_can_add(xids);
|
|
67
79
|
|
|
68
80
|
const idx_t* idx;
|
|
@@ -78,7 +90,7 @@ void IndexBinaryIVF::add_core(
|
|
|
78
90
|
}
|
|
79
91
|
|
|
80
92
|
idx_t n_add = 0;
|
|
81
|
-
for (
|
|
93
|
+
for (idx_t i = 0; i < n; i++) {
|
|
82
94
|
idx_t id = xids ? xids[i] : ntotal + i;
|
|
83
95
|
idx_t list_no = idx[i];
|
|
84
96
|
|
|
@@ -120,25 +132,47 @@ void IndexBinaryIVF::search(
|
|
|
120
132
|
idx_t k,
|
|
121
133
|
int32_t* distances,
|
|
122
134
|
idx_t* labels,
|
|
123
|
-
const SearchParameters*
|
|
124
|
-
FAISS_THROW_IF_NOT_MSG(
|
|
125
|
-
!params, "search params not supported for this index");
|
|
135
|
+
const SearchParameters* params_in) const {
|
|
126
136
|
FAISS_THROW_IF_NOT(k > 0);
|
|
127
|
-
|
|
137
|
+
FAISS_THROW_IF_NOT_MSG(invlists, "IVF index has no inverted lists");
|
|
138
|
+
const IVFSearchParameters* params = nullptr;
|
|
139
|
+
if (params_in) {
|
|
140
|
+
params = dynamic_cast<const IVFSearchParameters*>(params_in);
|
|
141
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
142
|
+
params, "IndexBinaryIVF params have incorrect type");
|
|
143
|
+
FAISS_THROW_IF_MSG(
|
|
144
|
+
params->sel, "IDSelector is not supported for IndexBinaryIVF");
|
|
145
|
+
}
|
|
146
|
+
const size_t nprobe_ =
|
|
147
|
+
std::min(nlist, params ? params->nprobe : this->nprobe);
|
|
148
|
+
FAISS_THROW_IF_NOT(nprobe_ > 0);
|
|
128
149
|
|
|
129
|
-
|
|
130
|
-
std::unique_ptr<
|
|
131
|
-
std::unique_ptr<int32_t[]> coarse_dis(new int32_t[n * nprobe_2]);
|
|
150
|
+
std::unique_ptr<idx_t[]> idx(new idx_t[n * nprobe_]);
|
|
151
|
+
std::unique_ptr<int32_t[]> coarse_dis(new int32_t[n * nprobe_]);
|
|
132
152
|
|
|
133
153
|
double t0 = getmillisecs();
|
|
134
|
-
quantizer->search(
|
|
154
|
+
quantizer->search(
|
|
155
|
+
n,
|
|
156
|
+
x,
|
|
157
|
+
nprobe_,
|
|
158
|
+
coarse_dis.get(),
|
|
159
|
+
idx.get(),
|
|
160
|
+
params ? params->quantizer_params : nullptr);
|
|
135
161
|
indexIVF_stats.quantization_time += getmillisecs() - t0;
|
|
136
162
|
|
|
137
163
|
t0 = getmillisecs();
|
|
138
|
-
invlists->prefetch_lists(idx.get(), n *
|
|
164
|
+
invlists->prefetch_lists(idx.get(), static_cast<int>(n * nprobe_));
|
|
139
165
|
|
|
140
166
|
search_preassigned(
|
|
141
|
-
n,
|
|
167
|
+
n,
|
|
168
|
+
x,
|
|
169
|
+
k,
|
|
170
|
+
idx.get(),
|
|
171
|
+
coarse_dis.get(),
|
|
172
|
+
distances,
|
|
173
|
+
labels,
|
|
174
|
+
false,
|
|
175
|
+
params);
|
|
142
176
|
indexIVF_stats.search_time += getmillisecs() - t0;
|
|
143
177
|
}
|
|
144
178
|
|
|
@@ -150,11 +184,11 @@ void IndexBinaryIVF::reconstruct(idx_t key, uint8_t* recons) const {
|
|
|
150
184
|
void IndexBinaryIVF::reconstruct_n(idx_t i0, idx_t ni, uint8_t* recons) const {
|
|
151
185
|
FAISS_THROW_IF_NOT(ni == 0 || (i0 >= 0 && i0 + ni <= ntotal));
|
|
152
186
|
|
|
153
|
-
for (
|
|
187
|
+
for (size_t list_no = 0; list_no < nlist; list_no++) {
|
|
154
188
|
size_t list_size = invlists->list_size(list_no);
|
|
155
189
|
const idx_t* idlist = invlists->get_ids(list_no);
|
|
156
190
|
|
|
157
|
-
for (
|
|
191
|
+
for (size_t offset = 0; offset < list_size; offset++) {
|
|
158
192
|
idx_t id = idlist[offset];
|
|
159
193
|
if (!(id >= i0 && id < i0 + ni)) {
|
|
160
194
|
continue;
|
|
@@ -185,7 +219,7 @@ void IndexBinaryIVF::search_and_reconstruct(
|
|
|
185
219
|
|
|
186
220
|
quantizer->search(n, x, nprobe_2, coarse_dis.get(), idx.get());
|
|
187
221
|
|
|
188
|
-
invlists->prefetch_lists(idx.get(), n * nprobe_2);
|
|
222
|
+
invlists->prefetch_lists(idx.get(), static_cast<int>(n * nprobe_2));
|
|
189
223
|
|
|
190
224
|
// search_preassigned() with `store_pairs` enabled to obtain the list_no
|
|
191
225
|
// and offset into `codes` for reconstruction
|
|
@@ -243,7 +277,8 @@ void IndexBinaryIVF::train(idx_t n, const uint8_t* x) {
|
|
|
243
277
|
printf("Training quantizer\n");
|
|
244
278
|
}
|
|
245
279
|
|
|
246
|
-
if (quantizer->is_trained &&
|
|
280
|
+
if (quantizer->is_trained &&
|
|
281
|
+
(static_cast<size_t>(quantizer->ntotal) == nlist)) {
|
|
247
282
|
if (verbose) {
|
|
248
283
|
printf("IVF quantizer does not need training.\n");
|
|
249
284
|
}
|
|
@@ -252,7 +287,7 @@ void IndexBinaryIVF::train(idx_t n, const uint8_t* x) {
|
|
|
252
287
|
printf("Training quantizer on %" PRId64 " vectors in %dD\n", n, d);
|
|
253
288
|
}
|
|
254
289
|
|
|
255
|
-
Clustering clus(d, nlist, cp);
|
|
290
|
+
Clustering clus(d, static_cast<int>(nlist), cp);
|
|
256
291
|
quantizer->reset();
|
|
257
292
|
|
|
258
293
|
IndexFlatL2 index_tmp(d);
|
|
@@ -304,7 +339,9 @@ void IndexBinaryIVF::merge_from(IndexBinary& otherIndex, idx_t add_id) {
|
|
|
304
339
|
}
|
|
305
340
|
|
|
306
341
|
void IndexBinaryIVF::replace_invlists(InvertedLists* il, bool own) {
|
|
307
|
-
FAISS_THROW_IF_NOT(
|
|
342
|
+
FAISS_THROW_IF_NOT(
|
|
343
|
+
il->nlist == nlist &&
|
|
344
|
+
il->code_size == static_cast<size_t>(code_size));
|
|
308
345
|
if (own_invlists) {
|
|
309
346
|
delete invlists;
|
|
310
347
|
}
|
|
@@ -312,68 +349,11 @@ void IndexBinaryIVF::replace_invlists(InvertedLists* il, bool own) {
|
|
|
312
349
|
own_invlists = own;
|
|
313
350
|
}
|
|
314
351
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
struct IVFBinaryScannerL2 : BinaryInvertedListScanner {
|
|
319
|
-
HammingComputer hc;
|
|
320
|
-
size_t code_size;
|
|
321
|
-
bool store_pairs;
|
|
322
|
-
|
|
323
|
-
IVFBinaryScannerL2(size_t code_size, bool store_pairs)
|
|
324
|
-
: code_size(code_size), store_pairs(store_pairs) {}
|
|
325
|
-
|
|
326
|
-
void set_query(const uint8_t* query_vector) override {
|
|
327
|
-
hc.set(query_vector, code_size);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
idx_t list_no;
|
|
331
|
-
void set_list(idx_t list_no_2, uint8_t /* coarse_dis */) override {
|
|
332
|
-
this->list_no = list_no_2;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
uint32_t distance_to_code(const uint8_t* code) const override {
|
|
336
|
-
return hc.hamming(code);
|
|
337
|
-
}
|
|
352
|
+
// IVFBinaryScannerL2, search_knn_hamming_count, BlockSearch,
|
|
353
|
+
// BlockSearchVariableK, search_knn_hamming_per_invlist are now in
|
|
354
|
+
// impl/binary_hamming/IndexBinaryIVF_impl.h (compiled per-ISA)
|
|
338
355
|
|
|
339
|
-
|
|
340
|
-
size_t n,
|
|
341
|
-
const uint8_t* __restrict codes,
|
|
342
|
-
const idx_t* __restrict ids,
|
|
343
|
-
int32_t* __restrict simi,
|
|
344
|
-
idx_t* __restrict idxi,
|
|
345
|
-
size_t k) const override {
|
|
346
|
-
using C = CMax<int32_t, idx_t>;
|
|
347
|
-
|
|
348
|
-
size_t nup = 0;
|
|
349
|
-
for (size_t j = 0; j < n; j++) {
|
|
350
|
-
uint32_t dis = hc.hamming(codes);
|
|
351
|
-
if (dis < simi[0]) {
|
|
352
|
-
idx_t id = store_pairs ? lo_build(list_no, j) : ids[j];
|
|
353
|
-
heap_replace_top<C>(k, simi, idxi, dis, id);
|
|
354
|
-
nup++;
|
|
355
|
-
}
|
|
356
|
-
codes += code_size;
|
|
357
|
-
}
|
|
358
|
-
return nup;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
void scan_codes_range(
|
|
362
|
-
size_t n,
|
|
363
|
-
const uint8_t* __restrict codes,
|
|
364
|
-
const idx_t* __restrict ids,
|
|
365
|
-
int radius,
|
|
366
|
-
RangeQueryResult& result) const override {
|
|
367
|
-
for (size_t j = 0; j < n; j++) {
|
|
368
|
-
uint32_t dis = hc.hamming(codes);
|
|
369
|
-
if (dis < radius) {
|
|
370
|
-
int64_t id = store_pairs ? lo_build(list_no, j) : ids[j];
|
|
371
|
-
result.add(dis, id);
|
|
372
|
-
}
|
|
373
|
-
codes += code_size;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
};
|
|
356
|
+
namespace {
|
|
377
357
|
|
|
378
358
|
void search_knn_hamming_heap(
|
|
379
359
|
const IndexBinaryIVF* ivf,
|
|
@@ -389,6 +369,10 @@ void search_knn_hamming_heap(
|
|
|
389
369
|
idx_t nprobe = params ? params->nprobe : ivf->nprobe;
|
|
390
370
|
nprobe = std::min((idx_t)ivf->nlist, nprobe);
|
|
391
371
|
idx_t max_codes = params ? params->max_codes : ivf->max_codes;
|
|
372
|
+
const idx_t unlimited_list_size = std::numeric_limits<idx_t>::max();
|
|
373
|
+
if (max_codes == 0) {
|
|
374
|
+
max_codes = unlimited_list_size;
|
|
375
|
+
}
|
|
392
376
|
MetricType metric_type = ivf->metric_type;
|
|
393
377
|
|
|
394
378
|
// almost verbatim copy from IndexIVF::search_preassigned
|
|
@@ -403,7 +387,7 @@ void search_knn_hamming_heap(
|
|
|
403
387
|
ivf->get_InvertedListScanner(store_pairs));
|
|
404
388
|
|
|
405
389
|
#pragma omp for
|
|
406
|
-
for (idx_t i = 0; i < n; i++) {
|
|
390
|
+
for (idx_t i = 0; i < static_cast<idx_t>(n); i++) {
|
|
407
391
|
const uint8_t* xi = x + i * ivf->code_size;
|
|
408
392
|
scanner->set_query(xi);
|
|
409
393
|
|
|
@@ -419,7 +403,7 @@ void search_knn_hamming_heap(
|
|
|
419
403
|
|
|
420
404
|
size_t nscan = 0;
|
|
421
405
|
|
|
422
|
-
for (
|
|
406
|
+
for (idx_t ik = 0; ik < nprobe; ik++) {
|
|
423
407
|
idx_t key = keysi[ik]; /* select the list */
|
|
424
408
|
if (key < 0) {
|
|
425
409
|
// not enough centroids for multiprobe
|
|
@@ -429,7 +413,7 @@ void search_knn_hamming_heap(
|
|
|
429
413
|
key < (idx_t)ivf->nlist,
|
|
430
414
|
"Invalid key=%" PRId64 " at ik=%zd nlist=%zd\n",
|
|
431
415
|
key,
|
|
432
|
-
ik,
|
|
416
|
+
static_cast<size_t>(ik),
|
|
433
417
|
ivf->nlist);
|
|
434
418
|
|
|
435
419
|
scanner->set_list(key, coarse_dis[i * nprobe + ik]);
|
|
@@ -437,6 +421,10 @@ void search_knn_hamming_heap(
|
|
|
437
421
|
nlistv++;
|
|
438
422
|
|
|
439
423
|
size_t list_size = ivf->invlists->list_size(key);
|
|
424
|
+
size_t list_size_max = static_cast<size_t>(max_codes) - nscan;
|
|
425
|
+
if (list_size > list_size_max) {
|
|
426
|
+
list_size = list_size_max;
|
|
427
|
+
}
|
|
440
428
|
InvertedLists::ScopedCodes scodes(ivf->invlists, key);
|
|
441
429
|
std::unique_ptr<InvertedLists::ScopedIds> sids;
|
|
442
430
|
const idx_t* ids = nullptr;
|
|
@@ -451,7 +439,7 @@ void search_knn_hamming_heap(
|
|
|
451
439
|
list_size, scodes.get(), ids, simi, idxi, k);
|
|
452
440
|
|
|
453
441
|
nscan += list_size;
|
|
454
|
-
if (
|
|
442
|
+
if (nscan >= static_cast<size_t>(max_codes)) {
|
|
455
443
|
break;
|
|
456
444
|
}
|
|
457
445
|
}
|
|
@@ -472,313 +460,17 @@ void search_knn_hamming_heap(
|
|
|
472
460
|
indexIVF_stats.nheap_updates += nheap;
|
|
473
461
|
}
|
|
474
462
|
|
|
475
|
-
template <class HammingComputer, bool store_pairs>
|
|
476
|
-
void search_knn_hamming_count(
|
|
477
|
-
const IndexBinaryIVF* ivf,
|
|
478
|
-
size_t nx,
|
|
479
|
-
const uint8_t* __restrict x,
|
|
480
|
-
const idx_t* __restrict keys,
|
|
481
|
-
int k,
|
|
482
|
-
int32_t* __restrict distances,
|
|
483
|
-
idx_t* __restrict labels,
|
|
484
|
-
const IVFSearchParameters* params) {
|
|
485
|
-
const int nBuckets = ivf->d + 1;
|
|
486
|
-
std::vector<int> all_counters(nx * nBuckets, 0);
|
|
487
|
-
std::unique_ptr<idx_t[]> all_ids_per_dis(new idx_t[nx * nBuckets * k]);
|
|
488
|
-
|
|
489
|
-
idx_t nprobe = params ? params->nprobe : ivf->nprobe;
|
|
490
|
-
nprobe = std::min((idx_t)ivf->nlist, nprobe);
|
|
491
|
-
idx_t max_codes = params ? params->max_codes : ivf->max_codes;
|
|
492
|
-
|
|
493
|
-
std::vector<HCounterState<HammingComputer>> cs;
|
|
494
|
-
for (size_t i = 0; i < nx; ++i) {
|
|
495
|
-
cs.push_back(
|
|
496
|
-
HCounterState<HammingComputer>(
|
|
497
|
-
all_counters.data() + i * nBuckets,
|
|
498
|
-
all_ids_per_dis.get() + i * nBuckets * k,
|
|
499
|
-
x + i * ivf->code_size,
|
|
500
|
-
ivf->d,
|
|
501
|
-
k));
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
size_t nlistv = 0, ndis = 0;
|
|
505
|
-
|
|
506
|
-
#pragma omp parallel for reduction(+ : nlistv, ndis)
|
|
507
|
-
for (int64_t i = 0; i < nx; i++) {
|
|
508
|
-
const idx_t* keysi = keys + i * nprobe;
|
|
509
|
-
HCounterState<HammingComputer>& csi = cs[i];
|
|
510
|
-
|
|
511
|
-
size_t nscan = 0;
|
|
512
|
-
|
|
513
|
-
for (size_t ik = 0; ik < nprobe; ik++) {
|
|
514
|
-
idx_t key = keysi[ik]; /* select the list */
|
|
515
|
-
if (key < 0) {
|
|
516
|
-
// not enough centroids for multiprobe
|
|
517
|
-
continue;
|
|
518
|
-
}
|
|
519
|
-
FAISS_THROW_IF_NOT_FMT(
|
|
520
|
-
key < (idx_t)ivf->nlist,
|
|
521
|
-
"Invalid key=%" PRId64 " at ik=%zd nlist=%zd\n",
|
|
522
|
-
key,
|
|
523
|
-
ik,
|
|
524
|
-
ivf->nlist);
|
|
525
|
-
|
|
526
|
-
nlistv++;
|
|
527
|
-
size_t list_size = ivf->invlists->list_size(key);
|
|
528
|
-
InvertedLists::ScopedCodes scodes(ivf->invlists, key);
|
|
529
|
-
const uint8_t* list_vecs = scodes.get();
|
|
530
|
-
const idx_t* ids =
|
|
531
|
-
store_pairs ? nullptr : ivf->invlists->get_ids(key);
|
|
532
|
-
|
|
533
|
-
for (size_t j = 0; j < list_size; j++) {
|
|
534
|
-
const uint8_t* yj = list_vecs + ivf->code_size * j;
|
|
535
|
-
|
|
536
|
-
idx_t id = store_pairs ? (key << 32 | j) : ids[j];
|
|
537
|
-
csi.update_counter(yj, id);
|
|
538
|
-
}
|
|
539
|
-
if (ids) {
|
|
540
|
-
ivf->invlists->release_ids(key, ids);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
nscan += list_size;
|
|
544
|
-
if (max_codes && nscan >= max_codes) {
|
|
545
|
-
break;
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
ndis += nscan;
|
|
549
|
-
|
|
550
|
-
int nres = 0;
|
|
551
|
-
for (int b = 0; b < nBuckets && nres < k; b++) {
|
|
552
|
-
for (int l = 0; l < csi.counters[b] && nres < k; l++) {
|
|
553
|
-
labels[i * k + nres] = csi.ids_per_dis[b * k + l];
|
|
554
|
-
distances[i * k + nres] = b;
|
|
555
|
-
nres++;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
while (nres < k) {
|
|
559
|
-
labels[i * k + nres] = -1;
|
|
560
|
-
distances[i * k + nres] = std::numeric_limits<int32_t>::max();
|
|
561
|
-
++nres;
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
indexIVF_stats.nq += nx;
|
|
566
|
-
indexIVF_stats.nlist += nlistv;
|
|
567
|
-
indexIVF_stats.ndis += ndis;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
/* Manages NQ queries at a time, stores results */
|
|
571
|
-
template <class HammingComputer, int NQ, int K>
|
|
572
|
-
struct BlockSearch {
|
|
573
|
-
HammingComputer hcs[NQ];
|
|
574
|
-
// heaps to update for each query
|
|
575
|
-
int32_t* distances[NQ];
|
|
576
|
-
idx_t* labels[NQ];
|
|
577
|
-
// curent top of heap
|
|
578
|
-
int32_t heap_tops[NQ];
|
|
579
|
-
|
|
580
|
-
BlockSearch(
|
|
581
|
-
size_t code_size,
|
|
582
|
-
const uint8_t* __restrict x,
|
|
583
|
-
const int32_t* __restrict keys,
|
|
584
|
-
int32_t* __restrict all_distances,
|
|
585
|
-
idx_t* __restrict all_labels) {
|
|
586
|
-
for (idx_t q = 0; q < NQ; q++) {
|
|
587
|
-
idx_t qno = keys[q];
|
|
588
|
-
hcs[q] = HammingComputer(x + qno * code_size, code_size);
|
|
589
|
-
distances[q] = all_distances + qno * K;
|
|
590
|
-
labels[q] = all_labels + qno * K;
|
|
591
|
-
heap_tops[q] = distances[q][0];
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
void add_bcode(const uint8_t* bcode, idx_t id) {
|
|
596
|
-
using C = CMax<int32_t, idx_t>;
|
|
597
|
-
for (int q = 0; q < NQ; q++) {
|
|
598
|
-
int dis = hcs[q].hamming(bcode);
|
|
599
|
-
if (dis < heap_tops[q]) {
|
|
600
|
-
heap_replace_top<C>(K, distances[q], labels[q], dis, id);
|
|
601
|
-
heap_tops[q] = distances[q][0];
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
};
|
|
606
|
-
|
|
607
|
-
template <class HammingComputer, int NQ>
|
|
608
|
-
struct BlockSearchVariableK {
|
|
609
|
-
int k;
|
|
610
|
-
HammingComputer hcs[NQ];
|
|
611
|
-
// heaps to update for each query
|
|
612
|
-
int32_t* distances[NQ];
|
|
613
|
-
idx_t* labels[NQ];
|
|
614
|
-
// curent top of heap
|
|
615
|
-
int32_t heap_tops[NQ];
|
|
616
|
-
|
|
617
|
-
BlockSearchVariableK(
|
|
618
|
-
size_t code_size,
|
|
619
|
-
int k,
|
|
620
|
-
const uint8_t* __restrict x,
|
|
621
|
-
const int32_t* __restrict keys,
|
|
622
|
-
int32_t* __restrict all_distances,
|
|
623
|
-
idx_t* __restrict all_labels)
|
|
624
|
-
: k(k) {
|
|
625
|
-
for (idx_t q = 0; q < NQ; q++) {
|
|
626
|
-
idx_t qno = keys[q];
|
|
627
|
-
hcs[q] = HammingComputer(x + qno * code_size, code_size);
|
|
628
|
-
distances[q] = all_distances + qno * k;
|
|
629
|
-
labels[q] = all_labels + qno * k;
|
|
630
|
-
heap_tops[q] = distances[q][0];
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
void add_bcode(const uint8_t* bcode, idx_t id) {
|
|
635
|
-
using C = CMax<int32_t, idx_t>;
|
|
636
|
-
for (int q = 0; q < NQ; q++) {
|
|
637
|
-
int dis = hcs[q].hamming(bcode);
|
|
638
|
-
if (dis < heap_tops[q]) {
|
|
639
|
-
heap_replace_top<C>(k, distances[q], labels[q], dis, id);
|
|
640
|
-
heap_tops[q] = distances[q][0];
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
};
|
|
645
|
-
|
|
646
|
-
template <class HammingComputer>
|
|
647
|
-
void search_knn_hamming_per_invlist(
|
|
648
|
-
const IndexBinaryIVF* ivf,
|
|
649
|
-
size_t n,
|
|
650
|
-
const uint8_t* __restrict x,
|
|
651
|
-
idx_t k,
|
|
652
|
-
const idx_t* __restrict keys_in,
|
|
653
|
-
const int32_t* __restrict coarse_dis,
|
|
654
|
-
int32_t* __restrict distances,
|
|
655
|
-
idx_t* __restrict labels,
|
|
656
|
-
bool store_pairs,
|
|
657
|
-
const IVFSearchParameters* params) {
|
|
658
|
-
idx_t nprobe = params ? params->nprobe : ivf->nprobe;
|
|
659
|
-
nprobe = std::min((idx_t)ivf->nlist, nprobe);
|
|
660
|
-
idx_t max_codes = params ? params->max_codes : ivf->max_codes;
|
|
661
|
-
FAISS_THROW_IF_NOT(max_codes == 0);
|
|
662
|
-
FAISS_THROW_IF_NOT(!store_pairs);
|
|
663
|
-
|
|
664
|
-
// reorder buckets
|
|
665
|
-
std::vector<int64_t> lims(n + 1);
|
|
666
|
-
int32_t* keys = new int32_t[n * nprobe];
|
|
667
|
-
std::unique_ptr<int32_t[]> delete_keys(keys);
|
|
668
|
-
for (idx_t i = 0; i < n * nprobe; i++) {
|
|
669
|
-
keys[i] = keys_in[i];
|
|
670
|
-
}
|
|
671
|
-
matrix_bucket_sort_inplace(n, nprobe, keys, ivf->nlist, lims.data(), 0);
|
|
672
|
-
|
|
673
|
-
using C = CMax<int32_t, idx_t>;
|
|
674
|
-
heap_heapify<C>(n * k, distances, labels);
|
|
675
|
-
const size_t code_size = ivf->code_size;
|
|
676
|
-
|
|
677
|
-
for (idx_t l = 0; l < ivf->nlist; l++) {
|
|
678
|
-
idx_t l0 = lims[l], nq = lims[l + 1] - l0;
|
|
679
|
-
|
|
680
|
-
InvertedLists::ScopedCodes scodes(ivf->invlists, l);
|
|
681
|
-
InvertedLists::ScopedIds sidx(ivf->invlists, l);
|
|
682
|
-
idx_t nb = ivf->invlists->list_size(l);
|
|
683
|
-
const uint8_t* bcodes = scodes.get();
|
|
684
|
-
const idx_t* ids = sidx.get();
|
|
685
|
-
|
|
686
|
-
idx_t i = 0;
|
|
687
|
-
|
|
688
|
-
// process as much as possible by blocks
|
|
689
|
-
constexpr int BS = 4;
|
|
690
|
-
|
|
691
|
-
if (k == 1) {
|
|
692
|
-
for (; i + BS <= nq; i += BS) {
|
|
693
|
-
BlockSearch<HammingComputer, BS, 1> bc(
|
|
694
|
-
code_size, x, keys + l0 + i, distances, labels);
|
|
695
|
-
for (idx_t j = 0; j < nb; j++) {
|
|
696
|
-
bc.add_bcode(bcodes + j * code_size, ids[j]);
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
} else if (k == 2) {
|
|
700
|
-
for (; i + BS <= nq; i += BS) {
|
|
701
|
-
BlockSearch<HammingComputer, BS, 2> bc(
|
|
702
|
-
code_size, x, keys + l0 + i, distances, labels);
|
|
703
|
-
for (idx_t j = 0; j < nb; j++) {
|
|
704
|
-
bc.add_bcode(bcodes + j * code_size, ids[j]);
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
} else if (k == 4) {
|
|
708
|
-
for (; i + BS <= nq; i += BS) {
|
|
709
|
-
BlockSearch<HammingComputer, BS, 4> bc(
|
|
710
|
-
code_size, x, keys + l0 + i, distances, labels);
|
|
711
|
-
for (idx_t j = 0; j < nb; j++) {
|
|
712
|
-
bc.add_bcode(bcodes + j * code_size, ids[j]);
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
} else {
|
|
716
|
-
for (; i + BS <= nq; i += BS) {
|
|
717
|
-
BlockSearchVariableK<HammingComputer, BS> bc(
|
|
718
|
-
code_size, k, x, keys + l0 + i, distances, labels);
|
|
719
|
-
for (idx_t j = 0; j < nb; j++) {
|
|
720
|
-
bc.add_bcode(bcodes + j * code_size, ids[j]);
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
// leftovers
|
|
726
|
-
for (; i < nq; i++) {
|
|
727
|
-
idx_t qno = keys[l0 + i];
|
|
728
|
-
HammingComputer hc(x + qno * code_size, code_size);
|
|
729
|
-
idx_t* __restrict idxi = labels + qno * k;
|
|
730
|
-
int32_t* __restrict simi = distances + qno * k;
|
|
731
|
-
int32_t simi0 = simi[0];
|
|
732
|
-
for (idx_t j = 0; j < nb; j++) {
|
|
733
|
-
int dis = hc.hamming(bcodes + j * code_size);
|
|
734
|
-
|
|
735
|
-
if (dis < simi0) {
|
|
736
|
-
idx_t id = store_pairs ? lo_build(l, j) : ids[j];
|
|
737
|
-
heap_replace_top<C>(k, simi, idxi, dis, id);
|
|
738
|
-
simi0 = simi[0];
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
for (idx_t i = 0; i < n; i++) {
|
|
744
|
-
heap_reorder<C>(k, distances + i * k, labels + i * k);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
struct Run_search_knn_hamming_per_invlist {
|
|
749
|
-
using T = void;
|
|
750
|
-
|
|
751
|
-
template <class HammingComputer, class... Types>
|
|
752
|
-
void f(Types... args) {
|
|
753
|
-
search_knn_hamming_per_invlist<HammingComputer>(args...);
|
|
754
|
-
}
|
|
755
|
-
};
|
|
756
|
-
|
|
757
|
-
template <bool store_pairs>
|
|
758
|
-
struct Run_search_knn_hamming_count {
|
|
759
|
-
using T = void;
|
|
760
|
-
|
|
761
|
-
template <class HammingComputer, class... Types>
|
|
762
|
-
void f(Types... args) {
|
|
763
|
-
search_knn_hamming_count<HammingComputer, store_pairs>(args...);
|
|
764
|
-
}
|
|
765
|
-
};
|
|
766
|
-
|
|
767
|
-
struct BuildScanner {
|
|
768
|
-
using T = BinaryInvertedListScanner*;
|
|
769
|
-
|
|
770
|
-
template <class HammingComputer>
|
|
771
|
-
T f(size_t code_size, bool store_pairs) {
|
|
772
|
-
return new IVFBinaryScannerL2<HammingComputer>(code_size, store_pairs);
|
|
773
|
-
}
|
|
774
|
-
};
|
|
775
|
-
|
|
776
463
|
} // anonymous namespace
|
|
777
464
|
|
|
465
|
+
// The remaining template code (search_knn_hamming_count,
|
|
466
|
+
// search_knn_hamming_per_invlist, etc.) has been moved to
|
|
467
|
+
// impl/binary_hamming/IndexBinaryIVF_impl.h
|
|
468
|
+
|
|
778
469
|
BinaryInvertedListScanner* IndexBinaryIVF::get_InvertedListScanner(
|
|
779
470
|
bool store_pairs) const {
|
|
780
|
-
|
|
781
|
-
|
|
471
|
+
return with_simd_level([&]<SIMDLevel SL>() {
|
|
472
|
+
return make_binary_ivf_scanner_fixSL<SL>(code_size, store_pairs);
|
|
473
|
+
});
|
|
782
474
|
}
|
|
783
475
|
|
|
784
476
|
void IndexBinaryIVF::search_preassigned(
|
|
@@ -792,23 +484,37 @@ void IndexBinaryIVF::search_preassigned(
|
|
|
792
484
|
bool store_pairs,
|
|
793
485
|
const IVFSearchParameters* params) const {
|
|
794
486
|
if (per_invlist_search) {
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
487
|
+
with_simd_level([&]<SIMDLevel SL>() {
|
|
488
|
+
search_knn_hamming_per_invlist_fixSL<SL>(
|
|
489
|
+
code_size,
|
|
490
|
+
this,
|
|
491
|
+
n,
|
|
492
|
+
x,
|
|
493
|
+
k,
|
|
494
|
+
cidx,
|
|
495
|
+
cdis,
|
|
496
|
+
dis,
|
|
497
|
+
idx,
|
|
498
|
+
store_pairs,
|
|
499
|
+
params);
|
|
500
|
+
});
|
|
801
501
|
} else if (use_heap) {
|
|
802
502
|
search_knn_hamming_heap(
|
|
803
503
|
this, n, x, k, cidx, cdis, dis, idx, store_pairs, params);
|
|
804
|
-
} else
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
504
|
+
} else {
|
|
505
|
+
with_simd_level([&]<SIMDLevel SL>() {
|
|
506
|
+
search_knn_hamming_count_fixSL<SL>(
|
|
507
|
+
code_size,
|
|
508
|
+
store_pairs,
|
|
509
|
+
this,
|
|
510
|
+
n,
|
|
511
|
+
x,
|
|
512
|
+
cidx,
|
|
513
|
+
k,
|
|
514
|
+
dis,
|
|
515
|
+
idx,
|
|
516
|
+
params);
|
|
517
|
+
});
|
|
812
518
|
}
|
|
813
519
|
}
|
|
814
520
|
|
|
@@ -829,7 +535,7 @@ void IndexBinaryIVF::range_search(
|
|
|
829
535
|
indexIVF_stats.quantization_time += getmillisecs() - t0;
|
|
830
536
|
|
|
831
537
|
t0 = getmillisecs();
|
|
832
|
-
invlists->prefetch_lists(idx.get(), n * nprobe_2);
|
|
538
|
+
invlists->prefetch_lists(idx.get(), static_cast<int>(n * nprobe_2));
|
|
833
539
|
|
|
834
540
|
range_search_preassigned(n, x, radius, idx.get(), coarse_dis.get(), res);
|
|
835
541
|
|
|
@@ -841,7 +547,7 @@ void IndexBinaryIVF::range_search_preassigned(
|
|
|
841
547
|
const uint8_t* __restrict x,
|
|
842
548
|
int radius,
|
|
843
549
|
const idx_t* __restrict assign,
|
|
844
|
-
const int32_t* __restrict centroid_dis
|
|
550
|
+
const int32_t* __restrict /* centroid_dis */,
|
|
845
551
|
RangeSearchResult* __restrict res) const {
|
|
846
552
|
const size_t nprobe_2 = std::min(nlist, this->nprobe);
|
|
847
553
|
bool store_pairs = false;
|