faiss 0.6.0 → 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 +4 -0
- data/ext/faiss/extconf.rb +2 -1
- data/ext/faiss/{index_rb.cpp → index.cpp} +1 -1
- data/ext/faiss/index_binary.cpp +1 -1
- data/ext/faiss/kmeans.cpp +1 -1
- data/ext/faiss/pca_matrix.cpp +1 -1
- data/ext/faiss/product_quantizer.cpp +1 -1
- data/ext/faiss/{utils_rb.cpp → utils.cpp} +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +93 -80
- data/vendor/faiss/faiss/Clustering.cpp +39 -240
- data/vendor/faiss/faiss/Clustering.h +6 -0
- data/vendor/faiss/faiss/IVFlib.cpp +41 -21
- data/vendor/faiss/faiss/Index.cpp +6 -5
- data/vendor/faiss/faiss/Index.h +5 -5
- data/vendor/faiss/faiss/Index2Layer.cpp +37 -53
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +49 -37
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +36 -34
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +4 -1
- data/vendor/faiss/faiss/IndexBinary.cpp +5 -3
- data/vendor/faiss/faiss/IndexBinary.h +4 -4
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +1 -1
- data/vendor/faiss/faiss/IndexBinaryFlat.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -4
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +84 -92
- 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 +87 -415
- data/vendor/faiss/faiss/IndexFastScan.cpp +72 -109
- data/vendor/faiss/faiss/IndexFastScan.h +25 -23
- data/vendor/faiss/faiss/IndexFlat.cpp +27 -20
- data/vendor/faiss/faiss/IndexFlat.h +21 -18
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +42 -19
- data/vendor/faiss/faiss/IndexHNSW.cpp +283 -145
- data/vendor/faiss/faiss/IndexHNSW.h +16 -2
- data/vendor/faiss/faiss/IndexIDMap.cpp +25 -21
- data/vendor/faiss/faiss/IndexIDMap.h +9 -7
- data/vendor/faiss/faiss/IndexIVF.cpp +465 -362
- data/vendor/faiss/faiss/IndexIVF.h +33 -12
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +77 -74
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +96 -93
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +4 -1
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +357 -238
- data/vendor/faiss/faiss/IndexIVFFastScan.h +42 -41
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +36 -68
- data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +53 -30
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +71 -843
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +151 -121
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +21 -17
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +26 -39
- data/vendor/faiss/faiss/IndexIVFRaBitQ.h +2 -1
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +475 -476
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +248 -93
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +41 -127
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
- data/vendor/faiss/faiss/IndexLSH.cpp +36 -19
- data/vendor/faiss/faiss/IndexLattice.cpp +13 -13
- data/vendor/faiss/faiss/IndexNNDescent.cpp +36 -21
- data/vendor/faiss/faiss/IndexNNDescent.h +2 -2
- data/vendor/faiss/faiss/IndexNSG.cpp +39 -23
- data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +31 -11
- data/vendor/faiss/faiss/IndexPQ.cpp +128 -221
- data/vendor/faiss/faiss/IndexPQ.h +3 -2
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +20 -14
- data/vendor/faiss/faiss/IndexPQFastScan.h +3 -0
- data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -18
- data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +11 -36
- data/vendor/faiss/faiss/IndexRaBitQ.h +2 -1
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +41 -277
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +183 -27
- data/vendor/faiss/faiss/IndexRefine.cpp +30 -25
- data/vendor/faiss/faiss/IndexRefine.h +4 -4
- data/vendor/faiss/faiss/IndexReplicas.cpp +6 -6
- data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +15 -14
- data/vendor/faiss/faiss/IndexRowwiseMinMax.h +1 -1
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +82 -14
- data/vendor/faiss/faiss/IndexShards.cpp +10 -9
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
- data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
- data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
- data/vendor/faiss/faiss/MetaIndexes.h +1 -1
- data/vendor/faiss/faiss/MetricType.h +14 -7
- data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
- data/vendor/faiss/faiss/SuperKMeans.h +97 -0
- data/vendor/faiss/faiss/VectorTransform.cpp +237 -149
- data/vendor/faiss/faiss/VectorTransform.h +16 -16
- data/vendor/faiss/faiss/build.cpp +23 -0
- data/vendor/faiss/faiss/build.h +15 -0
- data/vendor/faiss/faiss/clone_index.cpp +48 -47
- data/vendor/faiss/faiss/cppcontrib/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/factory_tools.cpp +5 -0
- 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 +29 -25
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -0
- data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
- data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
- data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +16 -16
- data/vendor/faiss/faiss/impl/CodePacker.cpp +3 -3
- data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +1 -1
- data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
- data/vendor/faiss/faiss/impl/FaissAssert.h +6 -3
- data/vendor/faiss/faiss/impl/FaissException.h +50 -3
- data/vendor/faiss/faiss/impl/HNSW.cpp +92 -317
- data/vendor/faiss/faiss/impl/HNSW.h +13 -34
- data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
- data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
- data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +82 -77
- data/vendor/faiss/faiss/impl/NNDescent.cpp +62 -25
- data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
- data/vendor/faiss/faiss/impl/NSG.cpp +38 -21
- data/vendor/faiss/faiss/impl/NSG.h +4 -4
- data/vendor/faiss/faiss/impl/Panorama.cpp +23 -6
- data/vendor/faiss/faiss/impl/Panorama.h +258 -87
- data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
- data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +46 -32
- data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
- data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +30 -23
- data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +55 -49
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +65 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +296 -283
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +26 -23
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ResultHandler.h +99 -75
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +52 -4
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +27 -1
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
- data/vendor/faiss/faiss/impl/VisitedTable.h +7 -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 +8 -3
- data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
- data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
- data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
- data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
- data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
- data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +268 -0
- data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +169 -2
- data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
- data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
- data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -356
- data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
- data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
- data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +282 -134
- data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
- data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +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 +1132 -45
- data/vendor/faiss/faiss/impl/index_read_utils.h +1 -1
- data/vendor/faiss/faiss/impl/index_write.cpp +95 -13
- 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 +37 -23
- data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
- data/vendor/faiss/faiss/impl/mapped_io.cpp +6 -6
- data/vendor/faiss/faiss/impl/platform_macros.h +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/pq_code_distance/{pq_code_distance-avx2.cpp → pq_code_distance-avx2.h} +9 -13
- data/vendor/faiss/faiss/impl/pq_code_distance/{pq_code_distance-avx512.cpp → pq_code_distance-avx512.h} +9 -57
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +29 -111
- 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 +238 -5
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +5 -7
- data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +68 -0
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +311 -477
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
- data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +1 -1
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +3 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +102 -11
- data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +27 -1
- data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +3 -3
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +148 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +167 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +59 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +163 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +311 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +192 -8
- data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +12 -0
- data/vendor/faiss/faiss/impl/simd_dispatch.h +100 -66
- data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +264 -172
- data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
- data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +270 -218
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
- data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
- data/vendor/faiss/faiss/impl/svs_io.h +8 -2
- data/vendor/faiss/faiss/index_factory.cpp +86 -18
- data/vendor/faiss/faiss/index_io.h +24 -0
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +66 -16
- 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 +13 -13
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
- data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +25 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +18 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +12 -3
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +7 -2
- data/vendor/faiss/faiss/utils/Heap.cpp +10 -10
- data/vendor/faiss/faiss/utils/NeuralNet.cpp +47 -36
- data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
- data/vendor/faiss/faiss/utils/distances.cpp +390 -560
- data/vendor/faiss/faiss/utils/distances.h +20 -1
- data/vendor/faiss/faiss/utils/distances_dispatch.h +117 -37
- data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
- data/vendor/faiss/faiss/utils/distances_simd.cpp +5 -177
- data/vendor/faiss/faiss/utils/extra_distances.cpp +9 -8
- data/vendor/faiss/faiss/utils/extra_distances.h +32 -6
- data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
- data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
- data/vendor/faiss/faiss/utils/hamming.h +92 -2
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +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 +2 -2
- data/vendor/faiss/faiss/utils/prefetch.h +2 -2
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +30 -30
- data/vendor/faiss/faiss/utils/quantize_lut.h +1 -1
- data/vendor/faiss/faiss/utils/rabitq_simd.h +57 -536
- data/vendor/faiss/faiss/utils/random.cpp +6 -6
- data/vendor/faiss/faiss/utils/simd_impl/IVFFlatScanner-inl.h +51 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +5 -1
- data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +213 -4
- data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +163 -10
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +250 -4
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +7 -4
- data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +189 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_simdlib256.h +195 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +2 -1
- data/vendor/faiss/faiss/utils/{distances_fused/simdlib_based.h → simd_impl/exhaustive_L2sqr_blas_cmax.h} +5 -10
- data/vendor/faiss/faiss/utils/simd_impl/hamming_impl.h +481 -0
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +14 -0
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +14 -0
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +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 +17 -5
- data/vendor/faiss/faiss/utils/simd_levels.h +93 -1
- data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
- data/vendor/faiss/faiss/utils/utils.cpp +5 -5
- data/vendor/faiss/faiss/utils/utils.h +3 -3
- metadata +119 -34
- data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
- data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -224
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -230
- data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
- data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
- data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
- data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -235
- data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
- data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
- data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -449
- data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
- data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
- data/vendor/faiss/faiss/utils/simdlib.h +0 -42
- data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -365
- /data/ext/faiss/{utils_rb.h → utils.h} +0 -0
|
@@ -0,0 +1,549 @@
|
|
|
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
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#ifndef THE_SIMD_LEVEL
|
|
11
|
+
#error "THE_SIMD_LEVEL must be defined before including IVFPQScanner_impl.h"
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
#include <faiss/IndexIVFPQ.h>
|
|
15
|
+
#include <faiss/impl/IDSelector.h>
|
|
16
|
+
#include <faiss/impl/ResultHandler.h>
|
|
17
|
+
#include <faiss/impl/pq_code_distance/IVFPQ_QueryTables.h>
|
|
18
|
+
#include <faiss/impl/pq_code_distance/pq_code_distance-inl.h>
|
|
19
|
+
#include <faiss/impl/simd_dispatch.h>
|
|
20
|
+
#include <faiss/invlists/DirectMap.h>
|
|
21
|
+
#include <faiss/utils/distances_dispatch.h>
|
|
22
|
+
#include <faiss/utils/hamming.h>
|
|
23
|
+
|
|
24
|
+
namespace faiss {
|
|
25
|
+
namespace pq_code_distance {
|
|
26
|
+
|
|
27
|
+
template <class C, bool use_sel>
|
|
28
|
+
struct WrappedSearchResult {
|
|
29
|
+
ResultHandler& res;
|
|
30
|
+
size_t nup = 0;
|
|
31
|
+
idx_t list_no;
|
|
32
|
+
|
|
33
|
+
const idx_t* ids;
|
|
34
|
+
const IDSelector* sel;
|
|
35
|
+
|
|
36
|
+
WrappedSearchResult(
|
|
37
|
+
idx_t list_no_in,
|
|
38
|
+
const idx_t* ids_in,
|
|
39
|
+
const IDSelector* sel_in,
|
|
40
|
+
ResultHandler& res_in)
|
|
41
|
+
: res(res_in), list_no(list_no_in), ids(ids_in), sel(sel_in) {}
|
|
42
|
+
|
|
43
|
+
inline bool skip_entry(idx_t j) {
|
|
44
|
+
return use_sel && !sel->is_member(ids[j]);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
inline void add(idx_t j, float dis) {
|
|
48
|
+
// Reached only for codes that passed skip_entry — i.e. distance
|
|
49
|
+
// was actually computed for this code (post-filter).
|
|
50
|
+
res.stats.scan_cnt++;
|
|
51
|
+
if (C::cmp(res.threshold, dis)) {
|
|
52
|
+
idx_t id = ids ? ids[j] : lo_build(this->list_no, j);
|
|
53
|
+
if (res.add_result(dis, id)) {
|
|
54
|
+
res.stats.nheap_updates++;
|
|
55
|
+
nup++;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/*****************************************************
|
|
62
|
+
* Scaning the codes.
|
|
63
|
+
* The scanning functions call their favorite precompute_*
|
|
64
|
+
* function to precompute the tables they need.
|
|
65
|
+
*****************************************************/
|
|
66
|
+
template <typename IDType, MetricType METRIC_TYPE, class PQCodeDist>
|
|
67
|
+
struct IVFPQScannerT : QueryTables {
|
|
68
|
+
using PQDecoder = typename PQCodeDist::PQDecoder;
|
|
69
|
+
const uint8_t* list_codes = nullptr;
|
|
70
|
+
const IDType* list_ids;
|
|
71
|
+
size_t list_size = 0;
|
|
72
|
+
|
|
73
|
+
IVFPQScannerT(
|
|
74
|
+
const IndexIVFPQ& ivfpq_in,
|
|
75
|
+
const IVFSearchParameters* params_in)
|
|
76
|
+
: QueryTables(ivfpq_in, params_in) {
|
|
77
|
+
FAISS_THROW_IF_NOT(METRIC_TYPE == metric_type);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/*****************************************************
|
|
81
|
+
* Scaning the codes: simple PQ scan.
|
|
82
|
+
*****************************************************/
|
|
83
|
+
|
|
84
|
+
// This is the baseline version of scan_list_with_tables().
|
|
85
|
+
// It demonstrates what this function actually does.
|
|
86
|
+
//
|
|
87
|
+
// /// version of the scan where we use precomputed tables.
|
|
88
|
+
// template <class SearchResultType>
|
|
89
|
+
// void scan_list_with_table(
|
|
90
|
+
// size_t ncode,
|
|
91
|
+
// const uint8_t* codes,
|
|
92
|
+
// SearchResultType& res) const {
|
|
93
|
+
//
|
|
94
|
+
// for (size_t j = 0; j < ncode; j++, codes += pq.code_size) {
|
|
95
|
+
// if (res.skip_entry(j)) {
|
|
96
|
+
// continue;
|
|
97
|
+
// }
|
|
98
|
+
// float dis = dis0 + PQCodeDist::distance_single_code(
|
|
99
|
+
// pq, sim_table, codes);
|
|
100
|
+
// res.add(j, dis);
|
|
101
|
+
// }
|
|
102
|
+
// }
|
|
103
|
+
|
|
104
|
+
// This is the modified version of scan_list_with_tables().
|
|
105
|
+
// It was observed that doing manual unrolling of the loop that
|
|
106
|
+
// utilizes distance_single_code() speeds up the computations.
|
|
107
|
+
|
|
108
|
+
/// version of the scan where we use precomputed tables.
|
|
109
|
+
template <class SearchResultType>
|
|
110
|
+
void scan_list_with_table(
|
|
111
|
+
size_t ncode,
|
|
112
|
+
const uint8_t* codes,
|
|
113
|
+
SearchResultType& res) const {
|
|
114
|
+
int counter = 0;
|
|
115
|
+
|
|
116
|
+
size_t saved_j[4] = {0, 0, 0, 0};
|
|
117
|
+
for (size_t j = 0; j < ncode; j++) {
|
|
118
|
+
if (res.skip_entry(j)) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
saved_j[0] = (counter == 0) ? j : saved_j[0];
|
|
123
|
+
saved_j[1] = (counter == 1) ? j : saved_j[1];
|
|
124
|
+
saved_j[2] = (counter == 2) ? j : saved_j[2];
|
|
125
|
+
saved_j[3] = (counter == 3) ? j : saved_j[3];
|
|
126
|
+
|
|
127
|
+
counter += 1;
|
|
128
|
+
if (counter == 4) {
|
|
129
|
+
float distance_0 = 0;
|
|
130
|
+
float distance_1 = 0;
|
|
131
|
+
float distance_2 = 0;
|
|
132
|
+
float distance_3 = 0;
|
|
133
|
+
PQCodeDist::distance_four_codes(
|
|
134
|
+
pq.M,
|
|
135
|
+
pq.nbits,
|
|
136
|
+
sim_table,
|
|
137
|
+
codes + saved_j[0] * pq.code_size,
|
|
138
|
+
codes + saved_j[1] * pq.code_size,
|
|
139
|
+
codes + saved_j[2] * pq.code_size,
|
|
140
|
+
codes + saved_j[3] * pq.code_size,
|
|
141
|
+
distance_0,
|
|
142
|
+
distance_1,
|
|
143
|
+
distance_2,
|
|
144
|
+
distance_3);
|
|
145
|
+
|
|
146
|
+
res.add(saved_j[0], dis0 + distance_0);
|
|
147
|
+
res.add(saved_j[1], dis0 + distance_1);
|
|
148
|
+
res.add(saved_j[2], dis0 + distance_2);
|
|
149
|
+
res.add(saved_j[3], dis0 + distance_3);
|
|
150
|
+
counter = 0;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (counter >= 1) {
|
|
155
|
+
float dis = dis0 +
|
|
156
|
+
PQCodeDist::distance_single_code(
|
|
157
|
+
pq.M,
|
|
158
|
+
pq.nbits,
|
|
159
|
+
sim_table,
|
|
160
|
+
codes + saved_j[0] * pq.code_size);
|
|
161
|
+
res.add(saved_j[0], dis);
|
|
162
|
+
}
|
|
163
|
+
if (counter >= 2) {
|
|
164
|
+
float dis = dis0 +
|
|
165
|
+
PQCodeDist::distance_single_code(
|
|
166
|
+
pq.M,
|
|
167
|
+
pq.nbits,
|
|
168
|
+
sim_table,
|
|
169
|
+
codes + saved_j[1] * pq.code_size);
|
|
170
|
+
res.add(saved_j[1], dis);
|
|
171
|
+
}
|
|
172
|
+
if (counter >= 3) {
|
|
173
|
+
float dis = dis0 +
|
|
174
|
+
PQCodeDist::distance_single_code(
|
|
175
|
+
pq.M,
|
|
176
|
+
pq.nbits,
|
|
177
|
+
sim_table,
|
|
178
|
+
codes + saved_j[2] * pq.code_size);
|
|
179
|
+
res.add(saved_j[2], dis);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/// tables are not precomputed, but pointers are provided to the
|
|
184
|
+
/// relevant X_c|x_r tables
|
|
185
|
+
template <class SearchResultType>
|
|
186
|
+
void scan_list_with_pointer(
|
|
187
|
+
size_t ncode,
|
|
188
|
+
const uint8_t* codes,
|
|
189
|
+
SearchResultType& res) const {
|
|
190
|
+
for (size_t j = 0; j < ncode; j++, codes += pq.code_size) {
|
|
191
|
+
if (res.skip_entry(j)) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
PQDecoder decoder(codes, pq.nbits);
|
|
195
|
+
float dis = dis0;
|
|
196
|
+
const float* tab = sim_table_2;
|
|
197
|
+
|
|
198
|
+
for (size_t m = 0; m < pq.M; m++) {
|
|
199
|
+
int ci = decoder.decode();
|
|
200
|
+
dis += sim_table_ptrs[m][ci] - 2 * tab[ci];
|
|
201
|
+
tab += pq.ksub;
|
|
202
|
+
}
|
|
203
|
+
res.add(j, dis);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/// nothing is precomputed: access residuals on-the-fly
|
|
208
|
+
template <class SearchResultType>
|
|
209
|
+
void scan_on_the_fly_dist(
|
|
210
|
+
size_t ncode,
|
|
211
|
+
const uint8_t* codes,
|
|
212
|
+
SearchResultType& res) const {
|
|
213
|
+
const float* dvec;
|
|
214
|
+
float local_dis0 = 0;
|
|
215
|
+
if (by_residual) {
|
|
216
|
+
if (METRIC_TYPE == METRIC_INNER_PRODUCT) {
|
|
217
|
+
ivfpq.quantizer->reconstruct(key, residual_vec);
|
|
218
|
+
local_dis0 = fvec_inner_product_dispatch(residual_vec, qi, d);
|
|
219
|
+
} else {
|
|
220
|
+
ivfpq.quantizer->compute_residual(qi, residual_vec, key);
|
|
221
|
+
}
|
|
222
|
+
dvec = residual_vec;
|
|
223
|
+
} else {
|
|
224
|
+
dvec = qi;
|
|
225
|
+
local_dis0 = 0;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
for (size_t j = 0; j < ncode; j++, codes += pq.code_size) {
|
|
229
|
+
if (res.skip_entry(j)) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
pq.decode(codes, decoded_vec);
|
|
233
|
+
|
|
234
|
+
float dis;
|
|
235
|
+
if (METRIC_TYPE == METRIC_INNER_PRODUCT) {
|
|
236
|
+
dis = local_dis0 +
|
|
237
|
+
fvec_inner_product_dispatch(decoded_vec, qi, d);
|
|
238
|
+
} else {
|
|
239
|
+
dis = fvec_L2sqr_dispatch(decoded_vec, dvec, d);
|
|
240
|
+
}
|
|
241
|
+
res.add(j, dis);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/*****************************************************
|
|
246
|
+
* Scanning codes with polysemous filtering
|
|
247
|
+
*****************************************************/
|
|
248
|
+
|
|
249
|
+
// This is the baseline version of scan_list_polysemous_hc().
|
|
250
|
+
// It demonstrates what this function actually does.
|
|
251
|
+
|
|
252
|
+
// template <class HammingComputer, class SearchResultType>
|
|
253
|
+
// void scan_list_polysemous_hc(
|
|
254
|
+
// size_t ncode,
|
|
255
|
+
// const uint8_t* codes,
|
|
256
|
+
// SearchResultType& res) const {
|
|
257
|
+
// int ht = ivfpq.polysemous_ht;
|
|
258
|
+
// size_t n_hamming_pass = 0, nup = 0;
|
|
259
|
+
//
|
|
260
|
+
// int code_size = pq.code_size;
|
|
261
|
+
//
|
|
262
|
+
// HammingComputer hc(q_code.data(), code_size);
|
|
263
|
+
//
|
|
264
|
+
// for (size_t j = 0; j < ncode; j++, codes += code_size) {
|
|
265
|
+
// if (res.skip_entry(j)) {
|
|
266
|
+
// continue;
|
|
267
|
+
// }
|
|
268
|
+
// const uint8_t* b_code = codes;
|
|
269
|
+
// int hd = hc.hamming(b_code);
|
|
270
|
+
// if (hd < ht) {
|
|
271
|
+
// n_hamming_pass++;
|
|
272
|
+
//
|
|
273
|
+
// float dis =
|
|
274
|
+
// dis0 +
|
|
275
|
+
// PQCodeDist::distance_single_code(
|
|
276
|
+
// pq, sim_table, codes);
|
|
277
|
+
//
|
|
278
|
+
// res.add(j, dis);
|
|
279
|
+
// }
|
|
280
|
+
// }
|
|
281
|
+
// #pragma omp critical
|
|
282
|
+
// { indexIVFPQ_stats.n_hamming_pass += n_hamming_pass; }
|
|
283
|
+
// }
|
|
284
|
+
|
|
285
|
+
// This is the modified version of scan_list_with_tables().
|
|
286
|
+
// It was observed that doing manual unrolling of the loop that
|
|
287
|
+
// utilizes distance_single_code() speeds up the computations.
|
|
288
|
+
|
|
289
|
+
template <class HammingComputer, class SearchResultType>
|
|
290
|
+
void scan_list_polysemous_hc(
|
|
291
|
+
size_t ncode,
|
|
292
|
+
const uint8_t* codes,
|
|
293
|
+
SearchResultType& res) const {
|
|
294
|
+
int ht = ivfpq.polysemous_ht;
|
|
295
|
+
size_t n_hamming_pass = 0;
|
|
296
|
+
|
|
297
|
+
int code_size = static_cast<int>(pq.code_size);
|
|
298
|
+
|
|
299
|
+
size_t saved_j[8];
|
|
300
|
+
int counter = 0;
|
|
301
|
+
|
|
302
|
+
HammingComputer hc(q_code.data(), code_size);
|
|
303
|
+
|
|
304
|
+
for (size_t j = 0; j < (ncode / 4) * 4; j += 4) {
|
|
305
|
+
const uint8_t* b_code = codes + j * code_size;
|
|
306
|
+
|
|
307
|
+
// Unrolling is a key. Basically, doing multiple popcount
|
|
308
|
+
// operations one after another speeds things up.
|
|
309
|
+
|
|
310
|
+
// 9999999 is just an arbitrary large number
|
|
311
|
+
int hd0 = (res.skip_entry(j + 0))
|
|
312
|
+
? 99999999
|
|
313
|
+
: hc.hamming(b_code + 0 * code_size);
|
|
314
|
+
int hd1 = (res.skip_entry(j + 1))
|
|
315
|
+
? 99999999
|
|
316
|
+
: hc.hamming(b_code + 1 * code_size);
|
|
317
|
+
int hd2 = (res.skip_entry(j + 2))
|
|
318
|
+
? 99999999
|
|
319
|
+
: hc.hamming(b_code + 2 * code_size);
|
|
320
|
+
int hd3 = (res.skip_entry(j + 3))
|
|
321
|
+
? 99999999
|
|
322
|
+
: hc.hamming(b_code + 3 * code_size);
|
|
323
|
+
|
|
324
|
+
saved_j[counter] = j + 0;
|
|
325
|
+
counter = (hd0 < ht) ? (counter + 1) : counter;
|
|
326
|
+
saved_j[counter] = j + 1;
|
|
327
|
+
counter = (hd1 < ht) ? (counter + 1) : counter;
|
|
328
|
+
saved_j[counter] = j + 2;
|
|
329
|
+
counter = (hd2 < ht) ? (counter + 1) : counter;
|
|
330
|
+
saved_j[counter] = j + 3;
|
|
331
|
+
counter = (hd3 < ht) ? (counter + 1) : counter;
|
|
332
|
+
|
|
333
|
+
if (counter >= 4) {
|
|
334
|
+
// process four codes at the same time
|
|
335
|
+
n_hamming_pass += 4;
|
|
336
|
+
|
|
337
|
+
float distance_0 = dis0;
|
|
338
|
+
float distance_1 = dis0;
|
|
339
|
+
float distance_2 = dis0;
|
|
340
|
+
float distance_3 = dis0;
|
|
341
|
+
PQCodeDist::distance_four_codes(
|
|
342
|
+
pq.M,
|
|
343
|
+
pq.nbits,
|
|
344
|
+
sim_table,
|
|
345
|
+
codes + saved_j[0] * pq.code_size,
|
|
346
|
+
codes + saved_j[1] * pq.code_size,
|
|
347
|
+
codes + saved_j[2] * pq.code_size,
|
|
348
|
+
codes + saved_j[3] * pq.code_size,
|
|
349
|
+
distance_0,
|
|
350
|
+
distance_1,
|
|
351
|
+
distance_2,
|
|
352
|
+
distance_3);
|
|
353
|
+
|
|
354
|
+
res.add(saved_j[0], dis0 + distance_0);
|
|
355
|
+
res.add(saved_j[1], dis0 + distance_1);
|
|
356
|
+
res.add(saved_j[2], dis0 + distance_2);
|
|
357
|
+
res.add(saved_j[3], dis0 + distance_3);
|
|
358
|
+
|
|
359
|
+
//
|
|
360
|
+
counter -= 4;
|
|
361
|
+
saved_j[0] = saved_j[4];
|
|
362
|
+
saved_j[1] = saved_j[5];
|
|
363
|
+
saved_j[2] = saved_j[6];
|
|
364
|
+
saved_j[3] = saved_j[7];
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
for (int kk = 0; kk < counter; kk++) {
|
|
369
|
+
n_hamming_pass++;
|
|
370
|
+
|
|
371
|
+
float dis = dis0 +
|
|
372
|
+
PQCodeDist::distance_single_code(
|
|
373
|
+
pq.M,
|
|
374
|
+
pq.nbits,
|
|
375
|
+
sim_table,
|
|
376
|
+
codes + saved_j[kk] * pq.code_size);
|
|
377
|
+
|
|
378
|
+
res.add(saved_j[kk], dis);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// process leftovers
|
|
382
|
+
for (size_t j = (ncode / 4) * 4; j < ncode; j++) {
|
|
383
|
+
if (res.skip_entry(j)) {
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
const uint8_t* b_code = codes + j * code_size;
|
|
387
|
+
int hd = hc.hamming(b_code);
|
|
388
|
+
if (hd < ht) {
|
|
389
|
+
n_hamming_pass++;
|
|
390
|
+
|
|
391
|
+
float dis = dis0 +
|
|
392
|
+
PQCodeDist::distance_single_code(
|
|
393
|
+
pq.M,
|
|
394
|
+
pq.nbits,
|
|
395
|
+
sim_table,
|
|
396
|
+
codes + j * code_size);
|
|
397
|
+
|
|
398
|
+
res.add(j, dis);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
#pragma omp critical
|
|
403
|
+
{
|
|
404
|
+
indexIVFPQ_stats.n_hamming_pass += n_hamming_pass;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
template <class SearchResultType>
|
|
409
|
+
void scan_list_polysemous(
|
|
410
|
+
size_t ncode,
|
|
411
|
+
const uint8_t* codes,
|
|
412
|
+
SearchResultType& res) const {
|
|
413
|
+
with_HammingComputer<PQCodeDist::simd_level>(
|
|
414
|
+
pq.code_size, [&]<class HammingComputer>() {
|
|
415
|
+
this->scan_list_polysemous_hc<
|
|
416
|
+
HammingComputer,
|
|
417
|
+
SearchResultType>(ncode, codes, res);
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
/* We put as many parameters as possible in template. Hopefully the
|
|
423
|
+
* gain in runtime is worth the code bloat.
|
|
424
|
+
*
|
|
425
|
+
* C is the comparator < or >, it is directly related to METRIC_TYPE.
|
|
426
|
+
*
|
|
427
|
+
* precompute_mode is how much we precompute (2 = precompute distance tables,
|
|
428
|
+
* 1 = precompute pointers to distances, 0 = compute distances one by one).
|
|
429
|
+
* Currently only 2 is supported
|
|
430
|
+
*
|
|
431
|
+
* use_sel: store or ignore the IDSelector
|
|
432
|
+
*/
|
|
433
|
+
template <MetricType METRIC_TYPE, class C, class PQCodeDist, bool use_sel>
|
|
434
|
+
struct IVFPQScanner : IVFPQScannerT<idx_t, METRIC_TYPE, PQCodeDist>,
|
|
435
|
+
InvertedListScanner {
|
|
436
|
+
using InvertedListScanner::scan_codes;
|
|
437
|
+
int precompute_mode;
|
|
438
|
+
const IDSelector* sel;
|
|
439
|
+
|
|
440
|
+
IVFPQScanner(
|
|
441
|
+
const IndexIVFPQ& ivfpq_in,
|
|
442
|
+
bool store_pairs_in,
|
|
443
|
+
int precompute_mode_in,
|
|
444
|
+
const IDSelector* sel_in)
|
|
445
|
+
: IVFPQScannerT<idx_t, METRIC_TYPE, PQCodeDist>(ivfpq_in, nullptr),
|
|
446
|
+
precompute_mode(precompute_mode_in),
|
|
447
|
+
sel(sel_in) {
|
|
448
|
+
this->store_pairs = store_pairs_in;
|
|
449
|
+
this->keep_max = is_similarity_metric(METRIC_TYPE);
|
|
450
|
+
this->code_size = this->pq.code_size;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
void set_query(const float* query) override {
|
|
454
|
+
this->init_query(query);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
void set_list(idx_t list_no_in, float coarse_dis_in) override {
|
|
458
|
+
this->list_no = list_no_in;
|
|
459
|
+
this->init_list(list_no_in, coarse_dis_in, precompute_mode);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
float distance_to_code(const uint8_t* code) const override {
|
|
463
|
+
FAISS_THROW_IF_NOT(precompute_mode == 2);
|
|
464
|
+
float dis = this->dis0 +
|
|
465
|
+
PQCodeDist::distance_single_code(
|
|
466
|
+
this->pq.M, this->pq.nbits, this->sim_table, code);
|
|
467
|
+
return dis;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
size_t scan_codes(
|
|
471
|
+
size_t ncode,
|
|
472
|
+
const uint8_t* codes,
|
|
473
|
+
const idx_t* ids,
|
|
474
|
+
ResultHandler& handler) const override {
|
|
475
|
+
WrappedSearchResult<C, use_sel> res(
|
|
476
|
+
this->key,
|
|
477
|
+
this->store_pairs ? nullptr : ids,
|
|
478
|
+
this->sel,
|
|
479
|
+
handler);
|
|
480
|
+
|
|
481
|
+
if (this->polysemous_ht > 0) {
|
|
482
|
+
FAISS_THROW_IF_NOT(precompute_mode == 2);
|
|
483
|
+
this->scan_list_polysemous(ncode, codes, res);
|
|
484
|
+
} else if (precompute_mode == 2) {
|
|
485
|
+
this->scan_list_with_table(ncode, codes, res);
|
|
486
|
+
} else if (precompute_mode == 1) {
|
|
487
|
+
this->scan_list_with_pointer(ncode, codes, res);
|
|
488
|
+
} else if (precompute_mode == 0) {
|
|
489
|
+
this->scan_on_the_fly_dist(ncode, codes, res);
|
|
490
|
+
} else {
|
|
491
|
+
FAISS_THROW_MSG("bad precomp mode");
|
|
492
|
+
}
|
|
493
|
+
return res.nup;
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
template <SIMDLevel SL>
|
|
498
|
+
InvertedListScanner* make_IVFPQInvertedListScanner(
|
|
499
|
+
const IndexIVFPQ& ivfpq,
|
|
500
|
+
bool store_pairs,
|
|
501
|
+
const IDSelector* sel);
|
|
502
|
+
|
|
503
|
+
// NOLINTNEXTLINE(facebook-hte-MisplacedTemplateSpecialization)
|
|
504
|
+
template <>
|
|
505
|
+
InvertedListScanner* make_IVFPQInvertedListScanner<THE_SIMD_LEVEL>(
|
|
506
|
+
const IndexIVFPQ& ivfpq,
|
|
507
|
+
bool store_pairs,
|
|
508
|
+
const IDSelector* sel) {
|
|
509
|
+
auto make = [&]<class PQCodeDist, bool use_sel>() -> InvertedListScanner* {
|
|
510
|
+
if (ivfpq.metric_type == METRIC_INNER_PRODUCT) {
|
|
511
|
+
return new IVFPQScanner<
|
|
512
|
+
METRIC_INNER_PRODUCT,
|
|
513
|
+
CMin<float, idx_t>,
|
|
514
|
+
PQCodeDist,
|
|
515
|
+
use_sel>(ivfpq, store_pairs, 2, sel);
|
|
516
|
+
} else if (ivfpq.metric_type == METRIC_L2) {
|
|
517
|
+
return new IVFPQScanner<
|
|
518
|
+
METRIC_L2,
|
|
519
|
+
CMax<float, idx_t>,
|
|
520
|
+
PQCodeDist,
|
|
521
|
+
use_sel>(ivfpq, store_pairs, 2, sel);
|
|
522
|
+
} else {
|
|
523
|
+
FAISS_THROW_MSG("unsupported metric type");
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
auto with_decoder = [&]<bool use_sel>() -> InvertedListScanner* {
|
|
528
|
+
if (ivfpq.pq.nbits == 8) {
|
|
529
|
+
return make.template
|
|
530
|
+
operator()<PQCodeDistance<PQDecoder8, THE_SIMD_LEVEL>, use_sel>();
|
|
531
|
+
} else if (ivfpq.pq.nbits == 16) {
|
|
532
|
+
return make.template
|
|
533
|
+
operator()<PQCodeDistance<PQDecoder16, THE_SIMD_LEVEL>, use_sel>();
|
|
534
|
+
} else {
|
|
535
|
+
return make.template operator()<
|
|
536
|
+
PQCodeDistance<PQDecoderGeneric, THE_SIMD_LEVEL>,
|
|
537
|
+
use_sel>();
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
if (sel) {
|
|
542
|
+
return with_decoder.template operator()<true>();
|
|
543
|
+
} else {
|
|
544
|
+
return with_decoder.template operator()<false>();
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
} // namespace pq_code_distance
|
|
549
|
+
} // namespace faiss
|