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
|
@@ -11,15 +11,14 @@
|
|
|
11
11
|
#include <faiss/VectorTransform.h>
|
|
12
12
|
#include <faiss/impl/AuxIndexStructures.h>
|
|
13
13
|
|
|
14
|
-
#include <chrono>
|
|
15
14
|
#include <cinttypes>
|
|
16
15
|
#include <cmath>
|
|
17
16
|
#include <cstdio>
|
|
18
17
|
#include <cstring>
|
|
19
|
-
|
|
20
|
-
#include <omp.h>
|
|
18
|
+
#include <limits>
|
|
21
19
|
|
|
22
20
|
#include <faiss/IndexFlat.h>
|
|
21
|
+
#include <faiss/impl/ClusteringHelpers.h>
|
|
23
22
|
#include <faiss/impl/FaissAssert.h>
|
|
24
23
|
#include <faiss/impl/kmeans1d.h>
|
|
25
24
|
#include <faiss/utils/distances.h>
|
|
@@ -28,10 +27,10 @@
|
|
|
28
27
|
|
|
29
28
|
namespace faiss {
|
|
30
29
|
|
|
31
|
-
Clustering::Clustering(int
|
|
30
|
+
Clustering::Clustering(int d_, int k_) : d(d_), k(k_) {}
|
|
32
31
|
|
|
33
|
-
Clustering::Clustering(int
|
|
34
|
-
: ClusteringParameters(cp), d(
|
|
32
|
+
Clustering::Clustering(int d_, int k_, const ClusteringParameters& cp)
|
|
33
|
+
: ClusteringParameters(cp), d(d_), k(k_) {}
|
|
35
34
|
|
|
36
35
|
void Clustering::post_process_centroids() {
|
|
37
36
|
if (spherical) {
|
|
@@ -58,213 +57,6 @@ void Clustering::train(
|
|
|
58
57
|
weights);
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
namespace {
|
|
62
|
-
|
|
63
|
-
uint64_t get_actual_rng_seed(const int seed) {
|
|
64
|
-
return (seed >= 0)
|
|
65
|
-
? seed
|
|
66
|
-
: static_cast<uint64_t>(std::chrono::high_resolution_clock::now()
|
|
67
|
-
.time_since_epoch()
|
|
68
|
-
.count());
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
idx_t subsample_training_set(
|
|
72
|
-
const Clustering& clus,
|
|
73
|
-
idx_t nx,
|
|
74
|
-
const uint8_t* x,
|
|
75
|
-
size_t line_size,
|
|
76
|
-
const float* weights,
|
|
77
|
-
uint8_t** x_out,
|
|
78
|
-
float** weights_out) {
|
|
79
|
-
if (clus.verbose) {
|
|
80
|
-
printf("Sampling a subset of %zd / %" PRId64 " for training\n",
|
|
81
|
-
clus.k * clus.max_points_per_centroid,
|
|
82
|
-
nx);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const uint64_t actual_seed = get_actual_rng_seed(clus.seed);
|
|
86
|
-
|
|
87
|
-
std::vector<int> perm;
|
|
88
|
-
if (clus.use_faster_subsampling) {
|
|
89
|
-
// use subsampling with splitmix64 rng
|
|
90
|
-
SplitMix64RandomGenerator rng(actual_seed);
|
|
91
|
-
|
|
92
|
-
const idx_t new_nx = clus.k * clus.max_points_per_centroid;
|
|
93
|
-
perm.resize(new_nx);
|
|
94
|
-
for (idx_t i = 0; i < new_nx; i++) {
|
|
95
|
-
perm[i] = rng.rand_int(nx);
|
|
96
|
-
}
|
|
97
|
-
} else {
|
|
98
|
-
// use subsampling with a default std rng
|
|
99
|
-
perm.resize(nx);
|
|
100
|
-
rand_perm(perm.data(), nx, actual_seed);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
nx = clus.k * clus.max_points_per_centroid;
|
|
104
|
-
uint8_t* x_new = new uint8_t[nx * line_size];
|
|
105
|
-
*x_out = x_new;
|
|
106
|
-
|
|
107
|
-
// might be worth omp-ing as well
|
|
108
|
-
for (idx_t i = 0; i < nx; i++) {
|
|
109
|
-
memcpy(x_new + i * line_size, x + perm[i] * line_size, line_size);
|
|
110
|
-
}
|
|
111
|
-
if (weights) {
|
|
112
|
-
float* weights_new = new float[nx];
|
|
113
|
-
for (idx_t i = 0; i < nx; i++) {
|
|
114
|
-
weights_new[i] = weights[perm[i]];
|
|
115
|
-
}
|
|
116
|
-
*weights_out = weights_new;
|
|
117
|
-
} else {
|
|
118
|
-
*weights_out = nullptr;
|
|
119
|
-
}
|
|
120
|
-
return nx;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/** compute centroids as (weighted) sum of training points
|
|
124
|
-
*
|
|
125
|
-
* @param x training vectors, size n * code_size (from codec)
|
|
126
|
-
* @param codec how to decode the vectors (if NULL then cast to float*)
|
|
127
|
-
* @param weights per-training vector weight, size n (or NULL)
|
|
128
|
-
* @param assign nearest centroid for each training vector, size n
|
|
129
|
-
* @param k_frozen do not update the k_frozen first centroids
|
|
130
|
-
* @param centroids centroid vectors (output only), size k * d
|
|
131
|
-
* @param hassign histogram of assignments per centroid (size k),
|
|
132
|
-
* should be 0 on input
|
|
133
|
-
*
|
|
134
|
-
*/
|
|
135
|
-
|
|
136
|
-
void compute_centroids(
|
|
137
|
-
size_t d,
|
|
138
|
-
size_t k,
|
|
139
|
-
size_t n,
|
|
140
|
-
size_t k_frozen,
|
|
141
|
-
const uint8_t* x,
|
|
142
|
-
const Index* codec,
|
|
143
|
-
const int64_t* assign,
|
|
144
|
-
const float* weights,
|
|
145
|
-
float* hassign,
|
|
146
|
-
float* centroids) {
|
|
147
|
-
k -= k_frozen;
|
|
148
|
-
centroids += k_frozen * d;
|
|
149
|
-
|
|
150
|
-
memset(centroids, 0, sizeof(*centroids) * d * k);
|
|
151
|
-
|
|
152
|
-
size_t line_size = codec ? codec->sa_code_size() : d * sizeof(float);
|
|
153
|
-
|
|
154
|
-
#pragma omp parallel
|
|
155
|
-
{
|
|
156
|
-
int nt = omp_get_num_threads();
|
|
157
|
-
int rank = omp_get_thread_num();
|
|
158
|
-
|
|
159
|
-
// this thread is taking care of centroids c0:c1
|
|
160
|
-
size_t c0 = (k * rank) / nt;
|
|
161
|
-
size_t c1 = (k * (rank + 1)) / nt;
|
|
162
|
-
std::vector<float> decode_buffer(d);
|
|
163
|
-
|
|
164
|
-
for (size_t i = 0; i < n; i++) {
|
|
165
|
-
int64_t ci = assign[i];
|
|
166
|
-
assert(ci >= 0 && ci < k + k_frozen);
|
|
167
|
-
ci -= k_frozen;
|
|
168
|
-
if (ci >= c0 && ci < c1) {
|
|
169
|
-
float* c = centroids + ci * d;
|
|
170
|
-
const float* xi;
|
|
171
|
-
if (!codec) {
|
|
172
|
-
xi = reinterpret_cast<const float*>(x + i * line_size);
|
|
173
|
-
} else {
|
|
174
|
-
float* xif = decode_buffer.data();
|
|
175
|
-
codec->sa_decode(1, x + i * line_size, xif);
|
|
176
|
-
xi = xif;
|
|
177
|
-
}
|
|
178
|
-
if (weights) {
|
|
179
|
-
float w = weights[i];
|
|
180
|
-
hassign[ci] += w;
|
|
181
|
-
for (size_t j = 0; j < d; j++) {
|
|
182
|
-
c[j] += xi[j] * w;
|
|
183
|
-
}
|
|
184
|
-
} else {
|
|
185
|
-
hassign[ci] += 1.0;
|
|
186
|
-
for (size_t j = 0; j < d; j++) {
|
|
187
|
-
c[j] += xi[j];
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
#pragma omp parallel for
|
|
195
|
-
for (idx_t ci = 0; ci < k; ci++) {
|
|
196
|
-
if (hassign[ci] == 0) {
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
float norm = 1 / hassign[ci];
|
|
200
|
-
float* c = centroids + ci * d;
|
|
201
|
-
for (size_t j = 0; j < d; j++) {
|
|
202
|
-
c[j] *= norm;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// a bit above machine epsilon for float16
|
|
208
|
-
#define EPS (1 / 1024.)
|
|
209
|
-
|
|
210
|
-
/** Handle empty clusters by splitting larger ones.
|
|
211
|
-
*
|
|
212
|
-
* It works by slightly changing the centroids to make 2 clusters from
|
|
213
|
-
* a single one. Takes the same arguments as compute_centroids.
|
|
214
|
-
*
|
|
215
|
-
* @return nb of splitting operations (larger is worse)
|
|
216
|
-
*/
|
|
217
|
-
int split_clusters(
|
|
218
|
-
size_t d,
|
|
219
|
-
size_t k,
|
|
220
|
-
size_t n,
|
|
221
|
-
size_t k_frozen,
|
|
222
|
-
float* hassign,
|
|
223
|
-
float* centroids) {
|
|
224
|
-
k -= k_frozen;
|
|
225
|
-
centroids += k_frozen * d;
|
|
226
|
-
|
|
227
|
-
/* Take care of void clusters */
|
|
228
|
-
size_t nsplit = 0;
|
|
229
|
-
RandomGenerator rng(1234);
|
|
230
|
-
for (size_t ci = 0; ci < k; ci++) {
|
|
231
|
-
if (hassign[ci] == 0) { /* need to redefine a centroid */
|
|
232
|
-
size_t cj;
|
|
233
|
-
for (cj = 0; true; cj = (cj + 1) % k) {
|
|
234
|
-
/* probability to pick this cluster for split */
|
|
235
|
-
float p = (hassign[cj] - 1.0) / (float)(n - k);
|
|
236
|
-
float r = rng.rand_float();
|
|
237
|
-
if (r < p) {
|
|
238
|
-
break; /* found our cluster to be split */
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
memcpy(centroids + ci * d,
|
|
242
|
-
centroids + cj * d,
|
|
243
|
-
sizeof(*centroids) * d);
|
|
244
|
-
|
|
245
|
-
/* small symmetric perturbation */
|
|
246
|
-
for (size_t j = 0; j < d; j++) {
|
|
247
|
-
if (j % 2 == 0) {
|
|
248
|
-
centroids[ci * d + j] *= 1 + EPS;
|
|
249
|
-
centroids[cj * d + j] *= 1 - EPS;
|
|
250
|
-
} else {
|
|
251
|
-
centroids[ci * d + j] *= 1 - EPS;
|
|
252
|
-
centroids[cj * d + j] *= 1 + EPS;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/* assume even split of the cluster */
|
|
257
|
-
hassign[ci] = hassign[cj] / 2;
|
|
258
|
-
hassign[cj] -= hassign[ci];
|
|
259
|
-
nsplit++;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return nsplit;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
} // namespace
|
|
267
|
-
|
|
268
60
|
void Clustering::train_encoded(
|
|
269
61
|
idx_t nx,
|
|
270
62
|
const uint8_t* x_in,
|
|
@@ -272,7 +64,7 @@ void Clustering::train_encoded(
|
|
|
272
64
|
Index& index,
|
|
273
65
|
const float* weights) {
|
|
274
66
|
FAISS_THROW_IF_NOT_FMT(
|
|
275
|
-
nx >= k,
|
|
67
|
+
nx >= static_cast<idx_t>(k),
|
|
276
68
|
"Number of training points (%" PRId64
|
|
277
69
|
") should be at least "
|
|
278
70
|
"as large as number of clusters (%zd)",
|
|
@@ -280,13 +72,13 @@ void Clustering::train_encoded(
|
|
|
280
72
|
k);
|
|
281
73
|
|
|
282
74
|
FAISS_THROW_IF_NOT_FMT(
|
|
283
|
-
(!codec || codec->d == d),
|
|
75
|
+
(!codec || static_cast<size_t>(codec->d) == d),
|
|
284
76
|
"Codec dimension %d not the same as data dimension %d",
|
|
285
77
|
int(codec->d),
|
|
286
78
|
int(d));
|
|
287
79
|
|
|
288
80
|
FAISS_THROW_IF_NOT_FMT(
|
|
289
|
-
index.d == d,
|
|
81
|
+
static_cast<size_t>(index.d) == d,
|
|
290
82
|
"Index dimension %d not the same as data dimension %d",
|
|
291
83
|
int(index.d),
|
|
292
84
|
int(d));
|
|
@@ -309,16 +101,16 @@ void Clustering::train_encoded(
|
|
|
309
101
|
std::unique_ptr<float[]> del3;
|
|
310
102
|
size_t line_size = codec ? codec->sa_code_size() : sizeof(float) * d;
|
|
311
103
|
|
|
312
|
-
if (nx > k * max_points_per_centroid) {
|
|
104
|
+
if (static_cast<size_t>(nx) > k * max_points_per_centroid) {
|
|
313
105
|
uint8_t* x_new;
|
|
314
106
|
float* weights_new;
|
|
315
|
-
nx = subsample_training_set(
|
|
107
|
+
nx = detail::subsample_training_set(
|
|
316
108
|
*this, nx, x, line_size, weights, &x_new, &weights_new);
|
|
317
109
|
del1.reset(x_new);
|
|
318
110
|
x = x_new;
|
|
319
111
|
del3.reset(weights_new);
|
|
320
112
|
weights = weights_new;
|
|
321
|
-
} else if (nx < k * min_points_per_centroid) {
|
|
113
|
+
} else if (static_cast<size_t>(nx) < k * min_points_per_centroid) {
|
|
322
114
|
fprintf(stderr,
|
|
323
115
|
"WARNING clustering %" PRId64
|
|
324
116
|
" points to %zd centroids: "
|
|
@@ -328,7 +120,7 @@ void Clustering::train_encoded(
|
|
|
328
120
|
idx_t(k) * min_points_per_centroid);
|
|
329
121
|
}
|
|
330
122
|
|
|
331
|
-
if (nx == k) {
|
|
123
|
+
if (static_cast<size_t>(nx) == k) {
|
|
332
124
|
// this is a corner case, just copy training set to clusters
|
|
333
125
|
if (verbose) {
|
|
334
126
|
printf("Number of training points (%" PRId64
|
|
@@ -397,7 +189,7 @@ void Clustering::train_encoded(
|
|
|
397
189
|
t0 = getmillisecs();
|
|
398
190
|
|
|
399
191
|
// initialize seed
|
|
400
|
-
const uint64_t actual_seed = get_actual_rng_seed(seed);
|
|
192
|
+
const uint64_t actual_seed = detail::get_actual_rng_seed(seed);
|
|
401
193
|
|
|
402
194
|
// temporary buffer to decode vectors during the optimization
|
|
403
195
|
std::vector<float> decode_buffer(codec ? d * decode_block_size : 0);
|
|
@@ -486,9 +278,10 @@ void Clustering::train_encoded(
|
|
|
486
278
|
} else {
|
|
487
279
|
// search by blocks of decode_block_size vectors
|
|
488
280
|
size_t code_size = codec->sa_code_size();
|
|
489
|
-
for (size_t i0 = 0; i0 < nx;
|
|
281
|
+
for (size_t i0 = 0; i0 < static_cast<size_t>(nx);
|
|
282
|
+
i0 += decode_block_size) {
|
|
490
283
|
size_t i1 = i0 + decode_block_size;
|
|
491
|
-
if (i1 > nx) {
|
|
284
|
+
if (i1 > static_cast<size_t>(nx)) {
|
|
492
285
|
i1 = nx;
|
|
493
286
|
}
|
|
494
287
|
codec->sa_decode(
|
|
@@ -507,7 +300,7 @@ void Clustering::train_encoded(
|
|
|
507
300
|
|
|
508
301
|
// accumulate objective
|
|
509
302
|
obj = 0;
|
|
510
|
-
for (
|
|
303
|
+
for (idx_t j = 0; j < nx; j++) {
|
|
511
304
|
obj += dis[j];
|
|
512
305
|
}
|
|
513
306
|
|
|
@@ -515,7 +308,7 @@ void Clustering::train_encoded(
|
|
|
515
308
|
std::vector<float> hassign(k);
|
|
516
309
|
|
|
517
310
|
size_t k_frozen = frozen_centroids ? n_input_centroids : 0;
|
|
518
|
-
compute_centroids(
|
|
311
|
+
detail::compute_centroids(
|
|
519
312
|
d,
|
|
520
313
|
k,
|
|
521
314
|
nx,
|
|
@@ -527,7 +320,7 @@ void Clustering::train_encoded(
|
|
|
527
320
|
hassign.data(),
|
|
528
321
|
centroids.data());
|
|
529
322
|
|
|
530
|
-
int nsplit = split_clusters(
|
|
323
|
+
int nsplit = detail::split_clusters(
|
|
531
324
|
d, k, nx, k_frozen, hassign.data(), centroids.data());
|
|
532
325
|
|
|
533
326
|
// collect statistics
|
|
@@ -535,7 +328,7 @@ void Clustering::train_encoded(
|
|
|
535
328
|
obj,
|
|
536
329
|
(getmillisecs() - t0) / 1000.0,
|
|
537
330
|
t_search_tot / 1000,
|
|
538
|
-
imbalance_factor(nx, k, assign.get()),
|
|
331
|
+
imbalance_factor(nx, static_cast<int>(k), assign.get()),
|
|
539
332
|
nsplit};
|
|
540
333
|
iteration_stats.push_back(stats);
|
|
541
334
|
|
|
@@ -569,7 +362,12 @@ void Clustering::train_encoded(
|
|
|
569
362
|
if (i > 0) {
|
|
570
363
|
float prev_obj =
|
|
571
364
|
iteration_stats[iteration_stats.size() - 2].obj;
|
|
572
|
-
|
|
365
|
+
|
|
366
|
+
double change = (prev_obj == 0)
|
|
367
|
+
? std::numeric_limits<double>::max()
|
|
368
|
+
: std::abs(prev_obj - obj) / std::abs(prev_obj);
|
|
369
|
+
|
|
370
|
+
if (change >= 0 && change <= early_stop_threshold) {
|
|
573
371
|
if (verbose) {
|
|
574
372
|
printf("\n Converged at iteration %d: "
|
|
575
373
|
"objective did not change\n",
|
|
@@ -604,19 +402,19 @@ void Clustering::train_encoded(
|
|
|
604
402
|
}
|
|
605
403
|
}
|
|
606
404
|
|
|
607
|
-
Clustering1D::Clustering1D(int
|
|
405
|
+
Clustering1D::Clustering1D(int k_) : Clustering(1, k_) {}
|
|
608
406
|
|
|
609
|
-
Clustering1D::Clustering1D(int
|
|
610
|
-
: Clustering(1,
|
|
407
|
+
Clustering1D::Clustering1D(int k_, const ClusteringParameters& cp)
|
|
408
|
+
: Clustering(1, k_, cp) {}
|
|
611
409
|
|
|
612
410
|
void Clustering1D::train_exact(idx_t n, const float* x) {
|
|
613
411
|
const float* xt = x;
|
|
614
412
|
|
|
615
413
|
std::unique_ptr<uint8_t[]> del;
|
|
616
|
-
if (n > k * max_points_per_centroid) {
|
|
414
|
+
if (static_cast<size_t>(n) > k * max_points_per_centroid) {
|
|
617
415
|
uint8_t* x_new;
|
|
618
416
|
float* weights_new;
|
|
619
|
-
n = subsample_training_set(
|
|
417
|
+
n = detail::subsample_training_set(
|
|
620
418
|
*this,
|
|
621
419
|
n,
|
|
622
420
|
(uint8_t*)x,
|
|
@@ -641,7 +439,7 @@ float kmeans_clustering(
|
|
|
641
439
|
size_t k,
|
|
642
440
|
const float* x,
|
|
643
441
|
float* centroids) {
|
|
644
|
-
Clustering clus(d, k);
|
|
442
|
+
Clustering clus(static_cast<int>(d), static_cast<int>(k));
|
|
645
443
|
clus.verbose = d * n * k > (size_t(1) << 30);
|
|
646
444
|
// display logs if > 1Gflop per iteration
|
|
647
445
|
IndexFlatL2 index(d);
|
|
@@ -664,13 +462,14 @@ Index* ProgressiveDimIndexFactory::operator()(int dim) {
|
|
|
664
462
|
return new IndexFlatL2(dim);
|
|
665
463
|
}
|
|
666
464
|
|
|
667
|
-
ProgressiveDimClustering::ProgressiveDimClustering(int
|
|
465
|
+
ProgressiveDimClustering::ProgressiveDimClustering(int d_, int k_)
|
|
466
|
+
: d(d_), k(k_) {}
|
|
668
467
|
|
|
669
468
|
ProgressiveDimClustering::ProgressiveDimClustering(
|
|
670
|
-
int
|
|
671
|
-
int
|
|
469
|
+
int d_,
|
|
470
|
+
int k_,
|
|
672
471
|
const ProgressiveDimClusteringParameters& cp)
|
|
673
|
-
: ProgressiveDimClusteringParameters(cp), d(
|
|
472
|
+
: ProgressiveDimClusteringParameters(cp), d(d_), k(k_) {}
|
|
674
473
|
|
|
675
474
|
namespace {
|
|
676
475
|
|
|
@@ -691,7 +490,7 @@ void ProgressiveDimClustering::train(
|
|
|
691
490
|
ProgressiveDimIndexFactory& factory) {
|
|
692
491
|
int d_prev = 0;
|
|
693
492
|
|
|
694
|
-
PCAMatrix pca(d, d);
|
|
493
|
+
PCAMatrix pca(static_cast<int>(d), static_cast<int>(d));
|
|
695
494
|
|
|
696
495
|
std::vector<float> xbuf;
|
|
697
496
|
if (apply_pca) {
|
|
@@ -716,7 +515,7 @@ void ProgressiveDimClustering::train(
|
|
|
716
515
|
}
|
|
717
516
|
std::unique_ptr<Index> clustering_index(factory(di));
|
|
718
517
|
|
|
719
|
-
Clustering clus(di, k, *this);
|
|
518
|
+
Clustering clus(di, static_cast<int>(k), *this);
|
|
720
519
|
if (d_prev > 0) {
|
|
721
520
|
// copy warm-start centroids (padded with 0s)
|
|
722
521
|
clus.centroids.resize(k * di);
|
|
@@ -69,6 +69,12 @@ struct ClusteringParameters {
|
|
|
69
69
|
/// Only used when init_method = AFK_MC2.
|
|
70
70
|
/// Longer chains give better approximation but are slower.
|
|
71
71
|
uint16_t afkmc2_chain_length = 50;
|
|
72
|
+
|
|
73
|
+
/// Early stop threshold, the range is [0, 1].
|
|
74
|
+
/// The value of 0 implies a default Faiss behavior,
|
|
75
|
+
/// so the training process stops only if an error
|
|
76
|
+
/// is unchanged from the previous iteration.
|
|
77
|
+
double early_stop_threshold = 0.0;
|
|
72
78
|
};
|
|
73
79
|
|
|
74
80
|
struct ClusteringIterationStats {
|
|
@@ -37,7 +37,7 @@ void check_compatible_for_merge(const Index* index0, const Index* index1) {
|
|
|
37
37
|
FAISS_THROW_IF_NOT_MSG(pt1, "both indexes should be pretransforms");
|
|
38
38
|
|
|
39
39
|
FAISS_THROW_IF_NOT(pt0->chain.size() == pt1->chain.size());
|
|
40
|
-
for (
|
|
40
|
+
for (size_t i = 0; i < pt0->chain.size(); i++) {
|
|
41
41
|
FAISS_THROW_IF_NOT(typeid(pt0->chain[i]) == typeid(pt1->chain[i]));
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -125,7 +125,7 @@ void search_centroid(
|
|
|
125
125
|
index = index_pre->index;
|
|
126
126
|
}
|
|
127
127
|
faiss::IndexIVF* index_ivf = dynamic_cast<faiss::IndexIVF*>(index);
|
|
128
|
-
|
|
128
|
+
FAISS_THROW_IF_NOT_MSG(index_ivf, "could not extract IVF index");
|
|
129
129
|
index_ivf->quantizer->assign(n, x, centroid_ids);
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -146,7 +146,7 @@ void search_and_return_centroids(
|
|
|
146
146
|
index = index_pre->index;
|
|
147
147
|
}
|
|
148
148
|
faiss::IndexIVF* index_ivf = dynamic_cast<faiss::IndexIVF*>(index);
|
|
149
|
-
|
|
149
|
+
FAISS_THROW_IF_NOT_MSG(index_ivf, "could not extract IVF index");
|
|
150
150
|
|
|
151
151
|
size_t nprobe = index_ivf->nprobe;
|
|
152
152
|
std::vector<idx_t> cent_nos(n * nprobe);
|
|
@@ -180,9 +180,9 @@ void search_and_return_centroids(
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
SlidingIndexWindow::SlidingIndexWindow(Index*
|
|
183
|
+
SlidingIndexWindow::SlidingIndexWindow(Index* index_) : index(index_) {
|
|
184
184
|
n_slice = 0;
|
|
185
|
-
IndexIVF* index_ivf = const_cast<IndexIVF*>(extract_index_ivf(
|
|
185
|
+
IndexIVF* index_ivf = const_cast<IndexIVF*>(extract_index_ivf(index_));
|
|
186
186
|
ils = dynamic_cast<ArrayInvertedLists*>(index_ivf->invlists);
|
|
187
187
|
FAISS_THROW_IF_NOT_MSG(
|
|
188
188
|
ils, "only supports indexes with ArrayInvertedLists");
|
|
@@ -249,7 +249,7 @@ void SlidingIndexWindow::step(const Index* sub_index, bool remove_oldest) {
|
|
|
249
249
|
IndexIVF* index_ivf = extract_index_ivf(index);
|
|
250
250
|
|
|
251
251
|
if (remove_oldest && ils2) {
|
|
252
|
-
for (
|
|
252
|
+
for (size_t i = 0; i < nlist; i++) {
|
|
253
253
|
std::vector<size_t>& sizesi = sizes[i];
|
|
254
254
|
size_t amount_to_remove = sizesi[0];
|
|
255
255
|
index_ivf->ntotal += ils2->ids[i].size() - amount_to_remove;
|
|
@@ -265,7 +265,7 @@ void SlidingIndexWindow::step(const Index* sub_index, bool remove_oldest) {
|
|
|
265
265
|
sizesi[n_slice - 1] = ils->ids[i].size();
|
|
266
266
|
}
|
|
267
267
|
} else if (ils2) {
|
|
268
|
-
for (
|
|
268
|
+
for (size_t i = 0; i < nlist; i++) {
|
|
269
269
|
index_ivf->ntotal += ils2->ids[i].size();
|
|
270
270
|
shift_and_add(ils->ids[i], 0, ils2->ids[i]);
|
|
271
271
|
shift_and_add(ils->codes[i], 0, ils2->codes[i]);
|
|
@@ -273,7 +273,7 @@ void SlidingIndexWindow::step(const Index* sub_index, bool remove_oldest) {
|
|
|
273
273
|
}
|
|
274
274
|
n_slice++;
|
|
275
275
|
} else if (remove_oldest) {
|
|
276
|
-
for (
|
|
276
|
+
for (size_t i = 0; i < nlist; i++) {
|
|
277
277
|
size_t amount_to_remove = sizes[i][0];
|
|
278
278
|
index_ivf->ntotal -= amount_to_remove;
|
|
279
279
|
remove_from_begin(ils->ids[i], amount_to_remove);
|
|
@@ -296,7 +296,8 @@ void SlidingIndexWindow::step(const Index* sub_index, bool remove_oldest) {
|
|
|
296
296
|
ArrayInvertedLists* get_invlist_range(const Index* index, long i0, long i1) {
|
|
297
297
|
const IndexIVF* ivf = extract_index_ivf(index);
|
|
298
298
|
|
|
299
|
-
FAISS_THROW_IF_NOT(
|
|
299
|
+
FAISS_THROW_IF_NOT(
|
|
300
|
+
0 <= i0 && i0 <= i1 && static_cast<size_t>(i1) <= ivf->nlist);
|
|
300
301
|
|
|
301
302
|
const InvertedLists* src = ivf->invlists;
|
|
302
303
|
|
|
@@ -319,12 +320,14 @@ void set_invlist_range(
|
|
|
319
320
|
ArrayInvertedLists* src) {
|
|
320
321
|
IndexIVF* ivf = extract_index_ivf(index);
|
|
321
322
|
|
|
322
|
-
FAISS_THROW_IF_NOT(
|
|
323
|
+
FAISS_THROW_IF_NOT(
|
|
324
|
+
0 <= i0 && i0 <= i1 && static_cast<size_t>(i1) <= ivf->nlist);
|
|
323
325
|
|
|
324
326
|
ArrayInvertedLists* dst = dynamic_cast<ArrayInvertedLists*>(ivf->invlists);
|
|
325
327
|
FAISS_THROW_IF_NOT_MSG(dst, "only ArrayInvertedLists supported");
|
|
326
328
|
FAISS_THROW_IF_NOT(
|
|
327
|
-
src->nlist == i1 - i0 &&
|
|
329
|
+
src->nlist == static_cast<size_t>(i1 - i0) &&
|
|
330
|
+
dst->code_size == src->code_size);
|
|
328
331
|
|
|
329
332
|
size_t ntotal = index->ntotal;
|
|
330
333
|
for (long i = i0; i < i1; i++) {
|
|
@@ -342,7 +345,7 @@ static size_t count_ndis(
|
|
|
342
345
|
const idx_t* Iq) {
|
|
343
346
|
size_t nb_dis = 0;
|
|
344
347
|
const InvertedLists* il = index_ivf->invlists;
|
|
345
|
-
for (
|
|
348
|
+
for (size_t i = 0; i < n_list_scan; i++) {
|
|
346
349
|
if (Iq[i] >= 0) {
|
|
347
350
|
nb_dis += il->list_size(Iq[i]);
|
|
348
351
|
}
|
|
@@ -457,12 +460,12 @@ void range_search_with_parameters(
|
|
|
457
460
|
IndexIVFResidualQuantizer* ivf_residual_from_quantizer(
|
|
458
461
|
const ResidualQuantizer& rq,
|
|
459
462
|
int nlevel) {
|
|
460
|
-
FAISS_THROW_IF_NOT(nlevel > 0 && nlevel + 1 < rq.M);
|
|
463
|
+
FAISS_THROW_IF_NOT(nlevel > 0 && static_cast<size_t>(nlevel + 1) < rq.M);
|
|
461
464
|
|
|
462
465
|
std::vector<size_t> nbits(nlevel);
|
|
463
466
|
std::copy(rq.nbits.begin(), rq.nbits.begin() + nlevel, nbits.begin());
|
|
464
467
|
std::unique_ptr<ResidualCoarseQuantizer> rcq(
|
|
465
|
-
new ResidualCoarseQuantizer(rq.d, nbits));
|
|
468
|
+
new ResidualCoarseQuantizer(static_cast<int>(rq.d), nbits));
|
|
466
469
|
|
|
467
470
|
// set the coarse quantizer from the 2 first quantizers
|
|
468
471
|
rcq->rq.initialize_from(rq);
|
|
@@ -477,7 +480,7 @@ IndexIVFResidualQuantizer* ivf_residual_from_quantizer(
|
|
|
477
480
|
|
|
478
481
|
// build a IVFResidualQuantizer from that
|
|
479
482
|
std::vector<size_t> nbits_refined;
|
|
480
|
-
for (
|
|
483
|
+
for (size_t i = nlevel; i < rq.M; i++) {
|
|
481
484
|
nbits_refined.push_back(rq.nbits[i]);
|
|
482
485
|
}
|
|
483
486
|
std::unique_ptr<IndexIVFResidualQuantizer> index(
|
|
@@ -489,7 +492,8 @@ IndexIVFResidualQuantizer* ivf_residual_from_quantizer(
|
|
|
489
492
|
faiss::METRIC_L2,
|
|
490
493
|
rq.search_type));
|
|
491
494
|
index->own_fields = true;
|
|
492
|
-
|
|
495
|
+
// Ownership transferred to index via own_fields = true
|
|
496
|
+
(void)rcq.release();
|
|
493
497
|
index->by_residual = true;
|
|
494
498
|
index->rq.initialize_from(rq, nlevel);
|
|
495
499
|
index->is_trained = true;
|
|
@@ -522,17 +526,17 @@ void ivf_residual_add_from_flat_codes(
|
|
|
522
526
|
int rank = omp_get_thread_num();
|
|
523
527
|
|
|
524
528
|
#pragma omp for
|
|
525
|
-
for (idx_t i = 0; i < nb; i++) {
|
|
529
|
+
for (idx_t i = 0; i < static_cast<idx_t>(nb); i++) {
|
|
526
530
|
const uint8_t* code = &raw_codes[i * code_size];
|
|
527
531
|
BitstringReader rd(code, code_size);
|
|
528
|
-
idx_t list_no = rd.read(rcq->rq.tot_bits);
|
|
532
|
+
idx_t list_no = rd.read(static_cast<int>(rcq->rq.tot_bits));
|
|
529
533
|
|
|
530
534
|
if (list_no % nt ==
|
|
531
535
|
rank) { // each thread takes care of 1/nt of the invlists
|
|
532
536
|
// copy AQ indexes one by one
|
|
533
537
|
BitstringWriter wr(tmp_code.data(), tmp_code.size());
|
|
534
|
-
for (
|
|
535
|
-
int nbit = rq.nbits[j];
|
|
538
|
+
for (size_t j = 0; j < rq.M; j++) {
|
|
539
|
+
int nbit = static_cast<int>(rq.nbits[j]);
|
|
536
540
|
wr.write(rd.read(nbit), nbit);
|
|
537
541
|
}
|
|
538
542
|
// we need to recompute the norm
|
|
@@ -540,7 +544,9 @@ void ivf_residual_add_from_flat_codes(
|
|
|
540
544
|
// ok
|
|
541
545
|
index->rq.decode(tmp_code.data(), tmp.data(), 1);
|
|
542
546
|
float norm = fvec_norm_L2sqr<SL>(tmp.data(), rq.d);
|
|
543
|
-
wr.write(
|
|
547
|
+
wr.write(
|
|
548
|
+
rq.encode_norm(norm),
|
|
549
|
+
static_cast<int>(rq.norm_bits));
|
|
544
550
|
|
|
545
551
|
// add code to the inverted list
|
|
546
552
|
invlists.add_entry(list_no, i, tmp_code.data());
|
|
@@ -598,7 +604,14 @@ void handle_ivf(
|
|
|
598
604
|
sharded_centroids[i].data());
|
|
599
605
|
}
|
|
600
606
|
char fname[256];
|
|
607
|
+
#if defined(__GNUC__) || defined(__clang__)
|
|
608
|
+
#pragma GCC diagnostic push
|
|
609
|
+
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
|
610
|
+
#endif
|
|
601
611
|
snprintf(fname, 256, filename_template.c_str(), i);
|
|
612
|
+
#if defined(__GNUC__) || defined(__clang__)
|
|
613
|
+
#pragma GCC diagnostic pop
|
|
614
|
+
#endif
|
|
602
615
|
faiss::write_index(sharded_index, fname);
|
|
603
616
|
delete sharded_index;
|
|
604
617
|
}
|
|
@@ -649,7 +662,14 @@ void handle_binary_ivf(
|
|
|
649
662
|
sharded_centroids[i].data());
|
|
650
663
|
}
|
|
651
664
|
char fname[256];
|
|
665
|
+
#if defined(__GNUC__) || defined(__clang__)
|
|
666
|
+
#pragma GCC diagnostic push
|
|
667
|
+
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
|
668
|
+
#endif
|
|
652
669
|
snprintf(fname, 256, filename_template.c_str(), i);
|
|
670
|
+
#if defined(__GNUC__) || defined(__clang__)
|
|
671
|
+
#pragma GCC diagnostic pop
|
|
672
|
+
#endif
|
|
653
673
|
faiss::write_index_binary(sharded_index, fname);
|
|
654
674
|
delete sharded_index;
|
|
655
675
|
}
|
|
@@ -24,7 +24,7 @@ void Index::train(idx_t /*n*/, const float* /*x*/) {
|
|
|
24
24
|
// does nothing by default
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
void Index::
|
|
27
|
+
void Index::train_with_queries(
|
|
28
28
|
idx_t /*n*/,
|
|
29
29
|
const float* /*x*/,
|
|
30
30
|
idx_t /*n_train_q*/,
|
|
@@ -55,7 +55,7 @@ void Index::add_with_ids(
|
|
|
55
55
|
|
|
56
56
|
size_t Index::remove_ids(const IDSelector& /*sel*/) {
|
|
57
57
|
FAISS_THROW_MSG("remove_ids not implemented for this type of index");
|
|
58
|
-
return -1;
|
|
58
|
+
return static_cast<size_t>(-1);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
void Index::reconstruct(idx_t, float*) const {
|
|
@@ -129,7 +129,7 @@ void Index::search1(const float*, ResultHandler&, SearchParameters*) const {
|
|
|
129
129
|
|
|
130
130
|
void Index::compute_residual(const float* x, float* residual, idx_t key) const {
|
|
131
131
|
reconstruct(key, residual);
|
|
132
|
-
for (
|
|
132
|
+
for (int i = 0; i < d; i++) {
|
|
133
133
|
residual[i] = x[i] - residual[i];
|
|
134
134
|
}
|
|
135
135
|
}
|
|
@@ -168,9 +168,10 @@ struct GenericDistanceComputer : DistanceComputer {
|
|
|
168
168
|
size_t d;
|
|
169
169
|
const Index& storage;
|
|
170
170
|
std::vector<float> buf;
|
|
171
|
-
const float* q;
|
|
171
|
+
const float* q = nullptr;
|
|
172
172
|
|
|
173
|
-
explicit GenericDistanceComputer(const Index&
|
|
173
|
+
explicit GenericDistanceComputer(const Index& storage_in)
|
|
174
|
+
: storage(storage_in) {
|
|
174
175
|
d = storage.d;
|
|
175
176
|
buf.resize(d * 2);
|
|
176
177
|
}
|