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
|
@@ -19,20 +19,29 @@
|
|
|
19
19
|
#include <faiss/impl/FaissAssert.h>
|
|
20
20
|
#include <faiss/utils/hamming.h>
|
|
21
21
|
|
|
22
|
-
#include <faiss/impl/pq_code_distance/pq_code_distance-
|
|
22
|
+
#include <faiss/impl/pq_code_distance/pq_code_distance-generic.h>
|
|
23
23
|
#include <faiss/impl/simd_dispatch.h>
|
|
24
24
|
|
|
25
|
+
// Scalar (NONE) fallback for dynamic dispatch
|
|
26
|
+
#define THE_SIMD_LEVEL SIMDLevel::NONE
|
|
27
|
+
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
28
|
+
#include <faiss/impl/pq_code_distance/PQDistanceComputer_impl.h>
|
|
29
|
+
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
30
|
+
#include <faiss/impl/binary_hamming/IndexPQ_impl.h>
|
|
31
|
+
#include <faiss/utils/hamming_distance/hamming_computer-generic.h>
|
|
32
|
+
#undef THE_SIMD_LEVEL
|
|
33
|
+
|
|
25
34
|
namespace faiss {
|
|
26
35
|
|
|
27
36
|
/*********************************************************
|
|
28
37
|
* IndexPQ implementation
|
|
29
38
|
********************************************************/
|
|
30
39
|
|
|
31
|
-
IndexPQ::IndexPQ(int
|
|
32
|
-
: IndexFlatCodes(0,
|
|
40
|
+
IndexPQ::IndexPQ(int d_in, size_t M, size_t nbits, MetricType metric)
|
|
41
|
+
: IndexFlatCodes(0, d_in, metric), pq(d_in, M, nbits) {
|
|
33
42
|
is_trained = false;
|
|
34
43
|
do_polysemous_training = false;
|
|
35
|
-
polysemous_ht = nbits * M + 1;
|
|
44
|
+
polysemous_ht = static_cast<int>(nbits * M) + 1;
|
|
36
45
|
search_type = ST_PQ;
|
|
37
46
|
encode_signs = false;
|
|
38
47
|
code_size = pq.code_size;
|
|
@@ -42,7 +51,7 @@ IndexPQ::IndexPQ() {
|
|
|
42
51
|
metric_type = METRIC_L2;
|
|
43
52
|
is_trained = false;
|
|
44
53
|
do_polysemous_training = false;
|
|
45
|
-
polysemous_ht = pq.nbits * pq.M + 1;
|
|
54
|
+
polysemous_ht = static_cast<int>(pq.nbits * pq.M) + 1;
|
|
46
55
|
search_type = ST_PQ;
|
|
47
56
|
encode_signs = false;
|
|
48
57
|
}
|
|
@@ -53,8 +62,9 @@ void IndexPQ::train(idx_t n, const float* x) {
|
|
|
53
62
|
} else {
|
|
54
63
|
idx_t ntrain_perm = polysemous_training.ntrain_permutation;
|
|
55
64
|
|
|
56
|
-
if (ntrain_perm > n / 4)
|
|
65
|
+
if (ntrain_perm > n / 4) {
|
|
57
66
|
ntrain_perm = n / 4;
|
|
67
|
+
}
|
|
58
68
|
if (verbose) {
|
|
59
69
|
printf("PQ training on %" PRId64 " points, remains %" PRId64
|
|
60
70
|
" points: "
|
|
@@ -71,88 +81,10 @@ void IndexPQ::train(idx_t n, const float* x) {
|
|
|
71
81
|
is_trained = true;
|
|
72
82
|
}
|
|
73
83
|
|
|
74
|
-
namespace {
|
|
75
|
-
|
|
76
|
-
template <class PQCodeDist>
|
|
77
|
-
struct PQDistanceComputer : FlatCodesDistanceComputer {
|
|
78
|
-
using PQDecoder = typename PQCodeDist::PQDecoder;
|
|
79
|
-
size_t d;
|
|
80
|
-
MetricType metric;
|
|
81
|
-
idx_t nb;
|
|
82
|
-
const ProductQuantizer& pq;
|
|
83
|
-
const float* sdc;
|
|
84
|
-
std::vector<float> precomputed_table;
|
|
85
|
-
size_t ndis;
|
|
86
|
-
const float* q;
|
|
87
|
-
|
|
88
|
-
float distance_to_code(const uint8_t* code) final {
|
|
89
|
-
ndis++;
|
|
90
|
-
|
|
91
|
-
float dis = PQCodeDist::distance_single_code(
|
|
92
|
-
pq.M, pq.nbits, precomputed_table.data(), code);
|
|
93
|
-
return dis;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
float symmetric_dis(idx_t i, idx_t j) override {
|
|
97
|
-
FAISS_THROW_IF_NOT(sdc);
|
|
98
|
-
const float* sdci = sdc;
|
|
99
|
-
float accu = 0;
|
|
100
|
-
PQDecoder codei(codes + i * code_size, pq.nbits);
|
|
101
|
-
PQDecoder codej(codes + j * code_size, pq.nbits);
|
|
102
|
-
|
|
103
|
-
for (int l = 0; l < pq.M; l++) {
|
|
104
|
-
accu += sdci[codei.decode() + (codej.decode() << codei.nbits)];
|
|
105
|
-
sdci += uint64_t(1) << (2 * codei.nbits);
|
|
106
|
-
}
|
|
107
|
-
ndis++;
|
|
108
|
-
return accu;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
explicit PQDistanceComputer(const IndexPQ& storage)
|
|
112
|
-
: FlatCodesDistanceComputer(
|
|
113
|
-
storage.codes.data(),
|
|
114
|
-
storage.code_size),
|
|
115
|
-
pq(storage.pq),
|
|
116
|
-
q(nullptr) {
|
|
117
|
-
precomputed_table.resize(pq.M * pq.ksub);
|
|
118
|
-
nb = storage.ntotal;
|
|
119
|
-
d = storage.d;
|
|
120
|
-
metric = storage.metric_type;
|
|
121
|
-
if (pq.sdc_table.size() == pq.ksub * pq.ksub * pq.M) {
|
|
122
|
-
sdc = pq.sdc_table.data();
|
|
123
|
-
} else {
|
|
124
|
-
sdc = nullptr;
|
|
125
|
-
}
|
|
126
|
-
ndis = 0;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
void set_query(const float* x) override {
|
|
130
|
-
q = x;
|
|
131
|
-
if (metric == METRIC_L2) {
|
|
132
|
-
pq.compute_distance_table(x, precomputed_table.data());
|
|
133
|
-
} else {
|
|
134
|
-
pq.compute_inner_prod_table(x, precomputed_table.data());
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
template <SIMDLevel SL>
|
|
140
|
-
FlatCodesDistanceComputer* get_FlatCodesDistanceComputer1(
|
|
141
|
-
const IndexPQ& index) {
|
|
142
|
-
if (index.pq.nbits == 8) {
|
|
143
|
-
return new PQDistanceComputer<PQCodeDistance<PQDecoder8, SL>>(index);
|
|
144
|
-
} else if (index.pq.nbits == 16) {
|
|
145
|
-
return new PQDistanceComputer<PQCodeDistance<PQDecoder16, SL>>(index);
|
|
146
|
-
} else {
|
|
147
|
-
return new PQDistanceComputer<PQCodeDistance<PQDecoderGeneric, SL>>(
|
|
148
|
-
index);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
} // namespace
|
|
153
|
-
|
|
154
84
|
FlatCodesDistanceComputer* IndexPQ::get_FlatCodesDistanceComputer() const {
|
|
155
|
-
|
|
85
|
+
return with_simd_level([&]<SIMDLevel SL>() {
|
|
86
|
+
return pq_code_distance::get_PQFlatCodesDistanceComputer<SL>(*this);
|
|
87
|
+
});
|
|
156
88
|
}
|
|
157
89
|
|
|
158
90
|
/*****************************************
|
|
@@ -215,14 +147,16 @@ void IndexPQ::search(
|
|
|
215
147
|
if (!encode_signs) {
|
|
216
148
|
pq.compute_codes(x, q_codes.get(), n);
|
|
217
149
|
} else {
|
|
218
|
-
FAISS_THROW_IF_NOT(d == pq.nbits * pq.M);
|
|
150
|
+
FAISS_THROW_IF_NOT(static_cast<size_t>(d) == pq.nbits * pq.M);
|
|
219
151
|
memset(q_codes.get(), 0, n * pq.code_size);
|
|
220
|
-
for (
|
|
152
|
+
for (idx_t i = 0; i < n; i++) {
|
|
221
153
|
const float* xi = x + i * d;
|
|
222
154
|
uint8_t* code = q_codes.get() + i * pq.code_size;
|
|
223
|
-
for (
|
|
224
|
-
if (xi[j] > 0)
|
|
155
|
+
for (size_t j = 0; j < static_cast<size_t>(d); j++) {
|
|
156
|
+
if (xi[j] > 0) {
|
|
225
157
|
code[j >> 3] |= 1 << (j & 7);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
226
160
|
}
|
|
227
161
|
}
|
|
228
162
|
|
|
@@ -258,8 +192,9 @@ void IndexPQ::search(
|
|
|
258
192
|
}
|
|
259
193
|
|
|
260
194
|
// convert distances to floats
|
|
261
|
-
for (
|
|
195
|
+
for (idx_t i = 0; i < k * n; i++) {
|
|
262
196
|
distances[i] = idistances[i];
|
|
197
|
+
}
|
|
263
198
|
}
|
|
264
199
|
|
|
265
200
|
indexPQ_stats.nq += n;
|
|
@@ -273,59 +208,8 @@ void IndexPQStats::reset() {
|
|
|
273
208
|
|
|
274
209
|
IndexPQStats indexPQ_stats;
|
|
275
210
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
template <class HammingComputer>
|
|
279
|
-
size_t polysemous_inner_loop(
|
|
280
|
-
const IndexPQ* index,
|
|
281
|
-
const float* dis_table_qi,
|
|
282
|
-
const uint8_t* q_code,
|
|
283
|
-
size_t k,
|
|
284
|
-
float* heap_dis,
|
|
285
|
-
int64_t* heap_ids,
|
|
286
|
-
int ht) {
|
|
287
|
-
int M = index->pq.M;
|
|
288
|
-
int code_size = index->pq.code_size;
|
|
289
|
-
int ksub = index->pq.ksub;
|
|
290
|
-
size_t ntotal = index->ntotal;
|
|
291
|
-
|
|
292
|
-
const uint8_t* b_code = index->codes.data();
|
|
293
|
-
|
|
294
|
-
size_t n_pass_i = 0;
|
|
295
|
-
|
|
296
|
-
HammingComputer hc(q_code, code_size);
|
|
297
|
-
|
|
298
|
-
for (int64_t bi = 0; bi < ntotal; bi++) {
|
|
299
|
-
int hd = hc.hamming(b_code);
|
|
300
|
-
|
|
301
|
-
if (hd < ht) {
|
|
302
|
-
n_pass_i++;
|
|
303
|
-
|
|
304
|
-
float dis = 0;
|
|
305
|
-
const float* dis_table = dis_table_qi;
|
|
306
|
-
for (int m = 0; m < M; m++) {
|
|
307
|
-
dis += dis_table[b_code[m]];
|
|
308
|
-
dis_table += ksub;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (dis < heap_dis[0]) {
|
|
312
|
-
maxheap_replace_top(k, heap_dis, heap_ids, dis, bi);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
b_code += code_size;
|
|
316
|
-
}
|
|
317
|
-
return n_pass_i;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
struct Run_polysemous_inner_loop {
|
|
321
|
-
using T = size_t;
|
|
322
|
-
template <class HammingComputer, class... Types>
|
|
323
|
-
size_t f(Types... args) {
|
|
324
|
-
return polysemous_inner_loop<HammingComputer>(args...);
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
} // anonymous namespace
|
|
211
|
+
// polysemous_inner_loop template code is now in
|
|
212
|
+
// impl/binary_hamming/IndexPQ_impl.h (compiled per-ISA)
|
|
329
213
|
|
|
330
214
|
void IndexPQ::search_core_polysemous(
|
|
331
215
|
idx_t n,
|
|
@@ -339,7 +223,7 @@ void IndexPQ::search_core_polysemous(
|
|
|
339
223
|
FAISS_THROW_IF_NOT(pq.nbits == 8);
|
|
340
224
|
|
|
341
225
|
if (param_polysemous_ht == 0) {
|
|
342
|
-
param_polysemous_ht = pq.nbits * pq.M + 1;
|
|
226
|
+
param_polysemous_ht = static_cast<int>(pq.nbits * pq.M) + 1;
|
|
343
227
|
}
|
|
344
228
|
|
|
345
229
|
// PQ distance tables
|
|
@@ -375,37 +259,39 @@ void IndexPQ::search_core_polysemous(
|
|
|
375
259
|
maxheap_heapify(k, heap_dis, heap_ids);
|
|
376
260
|
|
|
377
261
|
if (!generalized_hamming) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
262
|
+
n_pass += with_simd_level([&]<SIMDLevel SL>() {
|
|
263
|
+
return polysemous_inner_loop_fixSL<SL>(
|
|
264
|
+
pq.code_size,
|
|
265
|
+
this,
|
|
266
|
+
dis_table_qi,
|
|
267
|
+
q_code,
|
|
268
|
+
k,
|
|
269
|
+
heap_dis,
|
|
270
|
+
heap_ids,
|
|
271
|
+
param_polysemous_ht);
|
|
272
|
+
});
|
|
389
273
|
|
|
390
274
|
} else { // generalized hamming
|
|
391
275
|
switch (pq.code_size) {
|
|
392
|
-
#define DISPATCH(cs)
|
|
393
|
-
case cs:
|
|
394
|
-
n_pass += polysemous_inner_loop<
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
276
|
+
#define DISPATCH(cs) \
|
|
277
|
+
case cs: \
|
|
278
|
+
n_pass += polysemous_inner_loop< \
|
|
279
|
+
GenHammingComputer##cs##_tpl<SIMDLevel::NONE>>( \
|
|
280
|
+
this, \
|
|
281
|
+
dis_table_qi, \
|
|
282
|
+
q_code, \
|
|
283
|
+
k, \
|
|
284
|
+
heap_dis, \
|
|
285
|
+
heap_ids, \
|
|
286
|
+
param_polysemous_ht); \
|
|
402
287
|
break;
|
|
403
288
|
DISPATCH(8)
|
|
404
289
|
DISPATCH(16)
|
|
405
290
|
DISPATCH(32)
|
|
406
291
|
default:
|
|
407
292
|
if (pq.code_size % 8 == 0) {
|
|
408
|
-
n_pass += polysemous_inner_loop<
|
|
293
|
+
n_pass += polysemous_inner_loop<
|
|
294
|
+
GenHammingComputerM8_tpl<SIMDLevel::NONE>>(
|
|
409
295
|
this,
|
|
410
296
|
dis_table_qi,
|
|
411
297
|
q_code,
|
|
@@ -481,7 +367,7 @@ void IndexPQ::hamming_distance_histogram(
|
|
|
481
367
|
nb = ntotal;
|
|
482
368
|
b_codes = codes.data();
|
|
483
369
|
}
|
|
484
|
-
int nbits = pq.M * pq.nbits;
|
|
370
|
+
int nbits = static_cast<int>(pq.M * pq.nbits);
|
|
485
371
|
memset(hist, 0, sizeof(*hist) * (nbits + 1));
|
|
486
372
|
size_t bs = 256;
|
|
487
373
|
|
|
@@ -493,8 +379,9 @@ void IndexPQ::hamming_distance_histogram(
|
|
|
493
379
|
for (idx_t q0 = 0; q0 < n; q0 += bs) {
|
|
494
380
|
// printf ("dis stats: %zd/%zd\n", q0, n);
|
|
495
381
|
size_t q1 = q0 + bs;
|
|
496
|
-
if (q1 > n)
|
|
382
|
+
if (q1 > static_cast<size_t>(n)) {
|
|
497
383
|
q1 = n;
|
|
384
|
+
}
|
|
498
385
|
|
|
499
386
|
hammings(
|
|
500
387
|
q_codes.get() + q0 * pq.code_size,
|
|
@@ -504,13 +391,15 @@ void IndexPQ::hamming_distance_histogram(
|
|
|
504
391
|
pq.code_size,
|
|
505
392
|
distances.get());
|
|
506
393
|
|
|
507
|
-
for (size_t i = 0; i < nb * (q1 - q0); i++)
|
|
394
|
+
for (size_t i = 0; i < nb * (q1 - q0); i++) {
|
|
508
395
|
histi[distances[i]]++;
|
|
396
|
+
}
|
|
509
397
|
}
|
|
510
398
|
#pragma omp critical
|
|
511
399
|
{
|
|
512
|
-
for (int i = 0; i <= nbits; i++)
|
|
400
|
+
for (int i = 0; i <= nbits; i++) {
|
|
513
401
|
hist[i] += histi[i];
|
|
402
|
+
}
|
|
514
403
|
}
|
|
515
404
|
}
|
|
516
405
|
}
|
|
@@ -526,7 +415,7 @@ struct PreSortedArray {
|
|
|
526
415
|
const T* x;
|
|
527
416
|
int N;
|
|
528
417
|
|
|
529
|
-
explicit PreSortedArray(int
|
|
418
|
+
explicit PreSortedArray(int N_in) : N(N_in) {}
|
|
530
419
|
void init(const T* x_2) {
|
|
531
420
|
this->x = x_2;
|
|
532
421
|
}
|
|
@@ -563,15 +452,17 @@ struct SortedArray {
|
|
|
563
452
|
int N;
|
|
564
453
|
std::vector<int> perm;
|
|
565
454
|
|
|
566
|
-
explicit SortedArray(int
|
|
567
|
-
this->N =
|
|
568
|
-
perm.resize(
|
|
455
|
+
explicit SortedArray(int N_in) {
|
|
456
|
+
this->N = N_in;
|
|
457
|
+
perm.resize(N_in);
|
|
569
458
|
}
|
|
570
459
|
|
|
571
460
|
void init(const T* x_2) {
|
|
572
461
|
this->x = x_2;
|
|
573
|
-
|
|
462
|
+
FAISS_THROW_IF_NOT(!perm.empty());
|
|
463
|
+
for (int n = 0; n < N; n++) {
|
|
574
464
|
perm[n] = n;
|
|
465
|
+
}
|
|
575
466
|
ArgSort<T> cmp = {x_2};
|
|
576
467
|
std::sort(perm.begin(), perm.end(), cmp);
|
|
577
468
|
}
|
|
@@ -638,22 +529,24 @@ struct SemiSortedArray {
|
|
|
638
529
|
using HC = CMax<T, int>;
|
|
639
530
|
std::vector<int> perm;
|
|
640
531
|
|
|
641
|
-
int k; // k elements are sorted
|
|
532
|
+
int k = 0; // k elements are sorted
|
|
642
533
|
|
|
643
534
|
int initial_k, k_factor;
|
|
644
535
|
|
|
645
|
-
explicit SemiSortedArray(int
|
|
646
|
-
this->N =
|
|
647
|
-
perm.resize(
|
|
648
|
-
perm.resize(
|
|
536
|
+
explicit SemiSortedArray(int N_in) {
|
|
537
|
+
this->N = N_in;
|
|
538
|
+
perm.resize(N_in);
|
|
539
|
+
perm.resize(N_in);
|
|
649
540
|
initial_k = 3;
|
|
650
541
|
k_factor = 4;
|
|
651
542
|
}
|
|
652
543
|
|
|
653
544
|
void init(const T* x_2) {
|
|
654
545
|
this->x = x_2;
|
|
655
|
-
|
|
546
|
+
FAISS_THROW_IF_NOT(!perm.empty());
|
|
547
|
+
for (int n = 0; n < N; n++) {
|
|
656
548
|
perm[n] = n;
|
|
549
|
+
}
|
|
657
550
|
k = 0;
|
|
658
551
|
grow(initial_k);
|
|
659
552
|
}
|
|
@@ -687,7 +580,7 @@ struct SemiSortedArray {
|
|
|
687
580
|
|
|
688
581
|
// remap orders counted from smallest to indices in array
|
|
689
582
|
int get_ord(int n) {
|
|
690
|
-
|
|
583
|
+
FAISS_THROW_IF_NOT(n < k);
|
|
691
584
|
return perm[n];
|
|
692
585
|
}
|
|
693
586
|
};
|
|
@@ -730,7 +623,8 @@ struct MinSumK {
|
|
|
730
623
|
* terms involved in the sum.
|
|
731
624
|
*/
|
|
732
625
|
using HC = CMin<T, int64_t>;
|
|
733
|
-
size_t heap_capacity
|
|
626
|
+
size_t heap_capacity = 0;
|
|
627
|
+
size_t heap_size = 0;
|
|
734
628
|
T* bh_val;
|
|
735
629
|
int64_t* bh_ids;
|
|
736
630
|
|
|
@@ -742,9 +636,10 @@ struct MinSumK {
|
|
|
742
636
|
// that were seen before.
|
|
743
637
|
std::vector<uint8_t> seen;
|
|
744
638
|
|
|
745
|
-
MinSumK(int
|
|
746
|
-
|
|
747
|
-
|
|
639
|
+
MinSumK(int K_in, int M_in, int nbit_in, int N_in)
|
|
640
|
+
: K(K_in), M(M_in), nbit(nbit_in), N(N_in) {
|
|
641
|
+
heap_capacity = K_in * M_in;
|
|
642
|
+
FAISS_THROW_IF_NOT(N_in <= (1 << nbit_in));
|
|
748
643
|
|
|
749
644
|
// we'll do k steps, each step pushes at most M vals
|
|
750
645
|
bh_val = new T[heap_capacity];
|
|
@@ -755,8 +650,9 @@ struct MinSumK {
|
|
|
755
650
|
seen.resize((n_ids + 7) / 8);
|
|
756
651
|
}
|
|
757
652
|
|
|
758
|
-
for (int m = 0; m < M; m++)
|
|
653
|
+
for (int m = 0; m < M; m++) {
|
|
759
654
|
ssx.push_back(SSA(N));
|
|
655
|
+
}
|
|
760
656
|
}
|
|
761
657
|
|
|
762
658
|
int64_t weight(int i) {
|
|
@@ -768,8 +664,10 @@ struct MinSumK {
|
|
|
768
664
|
}
|
|
769
665
|
|
|
770
666
|
void mark_seen(int64_t i) {
|
|
771
|
-
if (use_seen)
|
|
667
|
+
if (use_seen) {
|
|
668
|
+
FAISS_THROW_IF_NOT(!seen.empty());
|
|
772
669
|
seen[i >> 3] |= 1 << (i & 7);
|
|
670
|
+
}
|
|
773
671
|
}
|
|
774
672
|
|
|
775
673
|
void run(const T* x, int64_t ldx, T* sums, int64_t* terms) {
|
|
@@ -802,11 +700,11 @@ struct MinSumK {
|
|
|
802
700
|
// pop smallest value from heap
|
|
803
701
|
if (use_seen) { // skip already seen elements
|
|
804
702
|
while (is_seen(bh_ids[0])) {
|
|
805
|
-
|
|
703
|
+
FAISS_THROW_IF_NOT(heap_size > 0);
|
|
806
704
|
heap_pop<HC>(heap_size--, bh_val, bh_ids);
|
|
807
705
|
}
|
|
808
706
|
}
|
|
809
|
-
|
|
707
|
+
FAISS_THROW_IF_NOT(heap_size > 0);
|
|
810
708
|
|
|
811
709
|
T sum = sums[k] = bh_val[0];
|
|
812
710
|
int64_t ti = terms[k] = bh_ids[0];
|
|
@@ -825,8 +723,9 @@ struct MinSumK {
|
|
|
825
723
|
for (int m = 0; m < M; m++) {
|
|
826
724
|
int64_t n = ii & (((int64_t)1 << nbit) - 1);
|
|
827
725
|
ii >>= nbit;
|
|
828
|
-
if (n + 1 >= N)
|
|
726
|
+
if (n + 1 >= N) {
|
|
829
727
|
continue;
|
|
728
|
+
}
|
|
830
729
|
|
|
831
730
|
enqueue_follower(ti, m, n, sum);
|
|
832
731
|
}
|
|
@@ -869,8 +768,8 @@ struct MinSumK {
|
|
|
869
768
|
|
|
870
769
|
} // anonymous namespace
|
|
871
770
|
|
|
872
|
-
MultiIndexQuantizer::MultiIndexQuantizer(int
|
|
873
|
-
: Index(
|
|
771
|
+
MultiIndexQuantizer::MultiIndexQuantizer(int d_in, size_t M, size_t nbits)
|
|
772
|
+
: Index(d_in, METRIC_L2), pq(d_in, M, nbits) {
|
|
874
773
|
is_trained = false;
|
|
875
774
|
pq.verbose = verbose;
|
|
876
775
|
}
|
|
@@ -881,8 +780,9 @@ void MultiIndexQuantizer::train(idx_t n, const float* x) {
|
|
|
881
780
|
is_trained = true;
|
|
882
781
|
// count virtual elements in index
|
|
883
782
|
ntotal = 1;
|
|
884
|
-
for (
|
|
783
|
+
for (size_t m = 0; m < pq.M; m++) {
|
|
885
784
|
ntotal *= pq.ksub;
|
|
785
|
+
}
|
|
886
786
|
}
|
|
887
787
|
|
|
888
788
|
// block size used in MultiIndexQuantizer::search
|
|
@@ -927,16 +827,16 @@ void MultiIndexQuantizer::search(
|
|
|
927
827
|
// simple version that just finds the min in each table
|
|
928
828
|
|
|
929
829
|
#pragma omp parallel for
|
|
930
|
-
for (
|
|
830
|
+
for (idx_t i = 0; i < n; i++) {
|
|
931
831
|
const float* dis_table = dis_tables.get() + i * pq.ksub * pq.M;
|
|
932
832
|
float dis = 0;
|
|
933
833
|
idx_t label = 0;
|
|
934
834
|
|
|
935
|
-
for (
|
|
835
|
+
for (size_t s = 0; s < pq.M; s++) {
|
|
936
836
|
float vmin = HUGE_VALF;
|
|
937
837
|
idx_t lmin = -1;
|
|
938
838
|
|
|
939
|
-
for (
|
|
839
|
+
for (size_t j = 0; j < pq.ksub; j++) {
|
|
940
840
|
if (dis_table[j] < vmin) {
|
|
941
841
|
vmin = dis_table[j];
|
|
942
842
|
lmin = j;
|
|
@@ -955,9 +855,12 @@ void MultiIndexQuantizer::search(
|
|
|
955
855
|
#pragma omp parallel if (n > 1)
|
|
956
856
|
{
|
|
957
857
|
MinSumK<float, SemiSortedArray<float>, false> msk(
|
|
958
|
-
k,
|
|
858
|
+
static_cast<int>(k),
|
|
859
|
+
static_cast<int>(pq.M),
|
|
860
|
+
static_cast<int>(pq.nbits),
|
|
861
|
+
static_cast<int>(pq.ksub));
|
|
959
862
|
#pragma omp for
|
|
960
|
-
for (
|
|
863
|
+
for (idx_t i = 0; i < n; i++) {
|
|
961
864
|
msk.run(dis_tables.get() + i * pq.ksub * pq.M,
|
|
962
865
|
pq.ksub,
|
|
963
866
|
distances + i * k,
|
|
@@ -969,7 +872,7 @@ void MultiIndexQuantizer::search(
|
|
|
969
872
|
|
|
970
873
|
void MultiIndexQuantizer::reconstruct(idx_t key, float* recons) const {
|
|
971
874
|
int64_t jj = key;
|
|
972
|
-
for (
|
|
875
|
+
for (size_t m = 0; m < pq.M; m++) {
|
|
973
876
|
int64_t n = jj & (((int64_t)1 << pq.nbits) - 1);
|
|
974
877
|
jj >>= pq.nbits;
|
|
975
878
|
memcpy(recons, pq.get_centroids(m, n), sizeof(recons[0]) * pq.dsub);
|
|
@@ -994,15 +897,15 @@ void MultiIndexQuantizer::reset() {
|
|
|
994
897
|
******************************************/
|
|
995
898
|
|
|
996
899
|
MultiIndexQuantizer2::MultiIndexQuantizer2(
|
|
997
|
-
int
|
|
900
|
+
int d_in,
|
|
998
901
|
size_t M,
|
|
999
902
|
size_t nbits,
|
|
1000
903
|
Index** indexes)
|
|
1001
|
-
: MultiIndexQuantizer(
|
|
904
|
+
: MultiIndexQuantizer(d_in, M, nbits) {
|
|
1002
905
|
assign_indexes.resize(M);
|
|
1003
|
-
for (
|
|
906
|
+
for (size_t i = 0; i < M; i++) {
|
|
1004
907
|
FAISS_THROW_IF_NOT_MSG(
|
|
1005
|
-
indexes[i]->d == pq.dsub,
|
|
908
|
+
static_cast<size_t>(indexes[i]->d) == pq.dsub,
|
|
1006
909
|
"Provided sub-index has incorrect size");
|
|
1007
910
|
assign_indexes[i] = indexes[i];
|
|
1008
911
|
}
|
|
@@ -1010,13 +913,14 @@ MultiIndexQuantizer2::MultiIndexQuantizer2(
|
|
|
1010
913
|
}
|
|
1011
914
|
|
|
1012
915
|
MultiIndexQuantizer2::MultiIndexQuantizer2(
|
|
1013
|
-
int
|
|
916
|
+
int d_in,
|
|
1014
917
|
size_t nbits,
|
|
1015
918
|
Index* assign_index_0,
|
|
1016
919
|
Index* assign_index_1)
|
|
1017
|
-
: MultiIndexQuantizer(
|
|
920
|
+
: MultiIndexQuantizer(d_in, 2, nbits) {
|
|
1018
921
|
FAISS_THROW_IF_NOT_MSG(
|
|
1019
|
-
assign_index_0->d == pq.dsub &&
|
|
922
|
+
static_cast<size_t>(assign_index_0->d) == pq.dsub &&
|
|
923
|
+
static_cast<size_t>(assign_index_1->d) == pq.dsub,
|
|
1020
924
|
"Provided sub-index has incorrect size");
|
|
1021
925
|
assign_indexes.resize(2);
|
|
1022
926
|
assign_indexes[0] = assign_index_0;
|
|
@@ -1027,7 +931,7 @@ MultiIndexQuantizer2::MultiIndexQuantizer2(
|
|
|
1027
931
|
void MultiIndexQuantizer2::train(idx_t n, const float* x) {
|
|
1028
932
|
MultiIndexQuantizer::train(n, x);
|
|
1029
933
|
// add centroids to sub-indexes
|
|
1030
|
-
for (
|
|
934
|
+
for (size_t i = 0; i < pq.M; i++) {
|
|
1031
935
|
assign_indexes[i]->add(pq.ksub, pq.get_centroids(i, 0));
|
|
1032
936
|
}
|
|
1033
937
|
}
|
|
@@ -1046,7 +950,7 @@ void MultiIndexQuantizer2::search(
|
|
|
1046
950
|
return;
|
|
1047
951
|
}
|
|
1048
952
|
|
|
1049
|
-
int k2 = std::min(K, int64_t(pq.ksub));
|
|
953
|
+
int k2 = static_cast<int>(std::min(K, int64_t(pq.ksub)));
|
|
1050
954
|
FAISS_THROW_IF_NOT(k2);
|
|
1051
955
|
|
|
1052
956
|
int64_t M = pq.M;
|
|
@@ -1057,10 +961,10 @@ void MultiIndexQuantizer2::search(
|
|
|
1057
961
|
std::vector<float> sub_dis(n * M * k2);
|
|
1058
962
|
std::vector<float> xsub(n * dsub);
|
|
1059
963
|
|
|
1060
|
-
for (
|
|
964
|
+
for (int64_t m = 0; m < M; m++) {
|
|
1061
965
|
float* xdest = xsub.data();
|
|
1062
966
|
const float* xsrc = x + m * dsub;
|
|
1063
|
-
for (
|
|
967
|
+
for (idx_t j = 0; j < n; j++) {
|
|
1064
968
|
memcpy(xdest, xsrc, dsub * sizeof(xdest[0]));
|
|
1065
969
|
xsrc += d;
|
|
1066
970
|
xdest += dsub;
|
|
@@ -1072,13 +976,13 @@ void MultiIndexQuantizer2::search(
|
|
|
1072
976
|
|
|
1073
977
|
if (K == 1) {
|
|
1074
978
|
// simple version that just finds the min in each table
|
|
1075
|
-
|
|
979
|
+
FAISS_THROW_IF_NOT(k2 == 1);
|
|
1076
980
|
|
|
1077
|
-
for (
|
|
981
|
+
for (idx_t i = 0; i < n; i++) {
|
|
1078
982
|
float dis = 0;
|
|
1079
983
|
idx_t label = 0;
|
|
1080
984
|
|
|
1081
|
-
for (
|
|
985
|
+
for (int64_t m = 0; m < M; m++) {
|
|
1082
986
|
float vmin = sub_dis[i + m * n];
|
|
1083
987
|
idx_t lmin = sub_ids[i + m * n];
|
|
1084
988
|
dis += vmin;
|
|
@@ -1092,9 +996,12 @@ void MultiIndexQuantizer2::search(
|
|
|
1092
996
|
#pragma omp parallel if (n > 1)
|
|
1093
997
|
{
|
|
1094
998
|
MinSumK<float, PreSortedArray<float>, false> msk(
|
|
1095
|
-
K,
|
|
999
|
+
static_cast<int>(K),
|
|
1000
|
+
static_cast<int>(pq.M),
|
|
1001
|
+
static_cast<int>(pq.nbits),
|
|
1002
|
+
k2);
|
|
1096
1003
|
#pragma omp for
|
|
1097
|
-
for (
|
|
1004
|
+
for (idx_t i = 0; i < n; i++) {
|
|
1098
1005
|
idx_t* li = labels + i * K;
|
|
1099
1006
|
msk.run(&sub_dis[i * k2], k2 * n, distances + i * K, li);
|
|
1100
1007
|
|
|
@@ -1104,12 +1011,12 @@ void MultiIndexQuantizer2::search(
|
|
|
1104
1011
|
int64_t ld_idmap = k2 * n;
|
|
1105
1012
|
int64_t mask1 = ksub - (int64_t)1;
|
|
1106
1013
|
|
|
1107
|
-
for (
|
|
1014
|
+
for (idx_t k = 0; k < K; k++) {
|
|
1108
1015
|
const idx_t* idmap = idmap0;
|
|
1109
1016
|
int64_t vin = li[k];
|
|
1110
1017
|
int64_t vout = 0;
|
|
1111
|
-
|
|
1112
|
-
for (
|
|
1018
|
+
size_t bs = 0;
|
|
1019
|
+
for (int64_t m = 0; m < M; m++) {
|
|
1113
1020
|
int64_t s = vin & mask1;
|
|
1114
1021
|
vin >>= pq.nbits;
|
|
1115
1022
|
vout |= idmap[s] << bs;
|
|
@@ -121,7 +121,8 @@ struct IndexPQStats {
|
|
|
121
121
|
size_t nq; // nb of queries run
|
|
122
122
|
size_t ncode; // nb of codes visited
|
|
123
123
|
|
|
124
|
-
size_t n_hamming_pass; // nb of passed Hamming distance tests (for
|
|
124
|
+
size_t n_hamming_pass = 0; // nb of passed Hamming distance tests (for
|
|
125
|
+
// polysemy)
|
|
125
126
|
|
|
126
127
|
IndexPQStats() {
|
|
127
128
|
reset();
|
|
@@ -169,7 +170,7 @@ FAISS_API extern int multi_index_quantizer_search_bs;
|
|
|
169
170
|
struct MultiIndexQuantizer2 : MultiIndexQuantizer {
|
|
170
171
|
/// M Indexes on d / M dimensions
|
|
171
172
|
std::vector<Index*> assign_indexes;
|
|
172
|
-
bool own_fields;
|
|
173
|
+
bool own_fields = false;
|
|
173
174
|
|
|
174
175
|
MultiIndexQuantizer2(int d, size_t M, size_t nbits, Index** indexes);
|
|
175
176
|
|