faiss 0.5.3 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/ext/faiss/ext.cpp +1 -1
- data/ext/faiss/extconf.rb +4 -4
- data/ext/faiss/index.cpp +63 -45
- data/ext/faiss/index_binary.cpp +37 -27
- data/ext/faiss/kmeans.cpp +9 -8
- data/ext/faiss/pca_matrix.cpp +9 -7
- data/ext/faiss/product_quantizer.cpp +13 -11
- data/ext/faiss/utils.cpp +4 -2
- data/ext/faiss/utils.h +4 -0
- data/lib/faiss/version.rb +1 -1
- data/lib/faiss.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +214 -82
- data/vendor/faiss/faiss/AutoTune.h +14 -1
- data/vendor/faiss/faiss/Clustering.cpp +97 -249
- data/vendor/faiss/faiss/Clustering.h +18 -0
- data/vendor/faiss/faiss/IVFlib.cpp +67 -44
- data/vendor/faiss/faiss/Index.cpp +25 -12
- data/vendor/faiss/faiss/Index.h +26 -4
- data/vendor/faiss/faiss/Index2Layer.cpp +37 -53
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +68 -61
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +36 -34
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +4 -1
- data/vendor/faiss/faiss/IndexBinary.cpp +6 -3
- data/vendor/faiss/faiss/IndexBinary.h +4 -4
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +1 -1
- data/vendor/faiss/faiss/IndexBinaryFlat.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -4
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +92 -95
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +9 -3
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +45 -236
- data/vendor/faiss/faiss/IndexBinaryHash.h +6 -6
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +120 -414
- data/vendor/faiss/faiss/IndexFastScan.cpp +105 -129
- data/vendor/faiss/faiss/IndexFastScan.h +35 -24
- data/vendor/faiss/faiss/IndexFlat.cpp +216 -152
- data/vendor/faiss/faiss/IndexFlat.h +32 -14
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +88 -41
- data/vendor/faiss/faiss/IndexFlatCodes.h +7 -1
- data/vendor/faiss/faiss/IndexHNSW.cpp +299 -187
- data/vendor/faiss/faiss/IndexHNSW.h +30 -14
- data/vendor/faiss/faiss/IndexIDMap.cpp +26 -22
- data/vendor/faiss/faiss/IndexIDMap.h +9 -7
- data/vendor/faiss/faiss/IndexIVF.cpp +535 -405
- data/vendor/faiss/faiss/IndexIVF.h +47 -16
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +77 -74
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +105 -99
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +6 -3
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +379 -249
- data/vendor/faiss/faiss/IndexIVFFastScan.h +65 -60
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +41 -124
- data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +89 -138
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +77 -907
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +184 -122
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +23 -18
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +59 -60
- data/vendor/faiss/faiss/IndexIVFRaBitQ.h +4 -3
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +564 -416
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +269 -111
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +41 -127
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
- data/vendor/faiss/faiss/IndexLSH.cpp +44 -25
- data/vendor/faiss/faiss/IndexLattice.cpp +41 -36
- data/vendor/faiss/faiss/IndexNNDescent.cpp +37 -21
- data/vendor/faiss/faiss/IndexNNDescent.h +2 -2
- data/vendor/faiss/faiss/IndexNSG.cpp +40 -23
- data/vendor/faiss/faiss/IndexNSG.h +0 -2
- data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +32 -12
- data/vendor/faiss/faiss/IndexPQ.cpp +129 -213
- data/vendor/faiss/faiss/IndexPQ.h +3 -2
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +20 -14
- data/vendor/faiss/faiss/IndexPQFastScan.h +3 -0
- data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -18
- data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +31 -43
- data/vendor/faiss/faiss/IndexRaBitQ.h +4 -3
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +135 -317
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +192 -34
- data/vendor/faiss/faiss/IndexRefine.cpp +30 -55
- data/vendor/faiss/faiss/IndexRefine.h +4 -4
- data/vendor/faiss/faiss/IndexReplicas.cpp +6 -6
- data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +15 -14
- data/vendor/faiss/faiss/IndexRowwiseMinMax.h +1 -1
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +82 -14
- data/vendor/faiss/faiss/IndexShards.cpp +13 -13
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +21 -15
- data/vendor/faiss/faiss/MatrixStats.cpp +5 -4
- data/vendor/faiss/faiss/MetaIndexes.cpp +19 -17
- data/vendor/faiss/faiss/MetaIndexes.h +1 -1
- data/vendor/faiss/faiss/MetricType.h +29 -6
- data/vendor/faiss/faiss/SuperKMeans.cpp +656 -0
- data/vendor/faiss/faiss/SuperKMeans.h +97 -0
- data/vendor/faiss/faiss/VectorTransform.cpp +349 -141
- data/vendor/faiss/faiss/VectorTransform.h +39 -16
- data/vendor/faiss/faiss/build.cpp +23 -0
- data/vendor/faiss/faiss/build.h +15 -0
- data/vendor/faiss/faiss/clone_index.cpp +55 -51
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +47 -47
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +11 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +38 -38
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +11 -0
- data/vendor/faiss/faiss/{cppcontrib/factory_tools.cpp → factory_tools.cpp} +6 -1
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +1 -1
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
- data/vendor/faiss/faiss/gpu/GpuResources.h +1 -1
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +9 -9
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +4 -3
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +46 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +56 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +78 -1
- data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +72 -0
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +23 -0
- data/vendor/faiss/faiss/gpu/utils/CuvsFilterConvert.h +1 -1
- data/vendor/faiss/faiss/gpu/utils/CuvsUtils.h +21 -10
- data/vendor/faiss/faiss/gpu_metal/GpuIndexFlat.h +22 -0
- data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +35 -0
- data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +51 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
- data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +66 -0
- data/vendor/faiss/faiss/gpu_metal/MetalResources.h +79 -0
- data/vendor/faiss/faiss/gpu_metal/StandardMetalResources.h +35 -0
- data/vendor/faiss/faiss/impl/AdSampling.cpp +103 -0
- data/vendor/faiss/faiss/impl/AdSampling.h +35 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +64 -34
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -0
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +10 -9
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +3 -28
- data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +244 -0
- data/vendor/faiss/faiss/impl/ClusteringHelpers.h +94 -0
- data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +367 -0
- data/vendor/faiss/faiss/impl/ClusteringInitialization.h +107 -0
- data/vendor/faiss/faiss/impl/CodePacker.cpp +7 -3
- data/vendor/faiss/faiss/impl/CodePacker.h +11 -3
- data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +83 -0
- data/vendor/faiss/faiss/impl/CodePackerRaBitQ.h +47 -0
- data/vendor/faiss/faiss/impl/DistanceComputer.h +8 -8
- data/vendor/faiss/faiss/impl/FaissAssert.h +64 -3
- data/vendor/faiss/faiss/impl/FaissException.h +50 -3
- data/vendor/faiss/faiss/impl/HNSW.cpp +117 -351
- data/vendor/faiss/faiss/impl/HNSW.h +21 -40
- data/vendor/faiss/faiss/impl/IDSelector.cpp +15 -11
- data/vendor/faiss/faiss/impl/IDSelector.h +8 -8
- data/vendor/faiss/faiss/impl/InvertedListScannerStats.h +26 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +114 -102
- data/vendor/faiss/faiss/impl/NNDescent.cpp +63 -26
- data/vendor/faiss/faiss/impl/NNDescent.h +6 -2
- data/vendor/faiss/faiss/impl/NSG.cpp +44 -26
- data/vendor/faiss/faiss/impl/NSG.h +20 -10
- data/vendor/faiss/faiss/impl/Panorama.cpp +76 -52
- data/vendor/faiss/faiss/impl/Panorama.h +265 -78
- data/vendor/faiss/faiss/impl/PdxLayout.cpp +93 -0
- data/vendor/faiss/faiss/impl/PdxLayout.h +41 -0
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +62 -37
- data/vendor/faiss/faiss/impl/PolysemousTraining.h +3 -3
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +35 -35
- data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +21 -16
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +99 -80
- data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +135 -37
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +148 -21
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +298 -301
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +3 -10
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +15 -41
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.h +0 -4
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +40 -32
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ResultHandler.h +218 -113
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +119 -2362
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +27 -3
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
- data/vendor/faiss/faiss/impl/VisitedTable.cpp +42 -0
- data/vendor/faiss/faiss/impl/VisitedTable.h +76 -0
- data/vendor/faiss/faiss/impl/approx_topk/approx_topk.h +276 -0
- data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +68 -0
- data/vendor/faiss/faiss/{utils → impl}/approx_topk/generic.h +15 -8
- data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +68 -0
- data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab-inl.h +169 -0
- data/vendor/faiss/faiss/impl/approx_topk/rq_beam_search_tab.h +117 -0
- data/vendor/faiss/faiss/impl/approx_topk/simdlib256-inl.h +146 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h +73 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +270 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +460 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h +159 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexPQ_impl.h +92 -0
- data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +26 -0
- data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +26 -0
- data/vendor/faiss/faiss/impl/binary_hamming/dispatch.h +143 -0
- data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +26 -0
- data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +26 -0
- data/vendor/faiss/faiss/impl/expanded_scanners.h +163 -0
- data/vendor/faiss/faiss/impl/{FastScanDistancePostProcessing.h → fast_scan/FastScanDistancePostProcessing.h} +13 -6
- data/vendor/faiss/faiss/impl/{LookupTableScaler.h → fast_scan/LookupTableScaler.h} +16 -5
- data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +237 -0
- data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +185 -0
- data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +229 -0
- data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +268 -0
- data/vendor/faiss/faiss/impl/{pq4_fast_scan.cpp → fast_scan/fast_scan.cpp} +176 -4
- data/vendor/faiss/faiss/impl/fast_scan/fast_scan.h +341 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +36 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +40 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +120 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +104 -0
- data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +213 -0
- data/vendor/faiss/faiss/impl/{pq4_fast_scan_search_qbs.cpp → fast_scan/kernels_simd512.h} +26 -348
- data/vendor/faiss/faiss/impl/fast_scan/rabitq_dispatching.h +90 -0
- data/vendor/faiss/faiss/impl/fast_scan/rabitq_result_handler.h +108 -0
- data/vendor/faiss/faiss/impl/{simd_result_handlers.h → fast_scan/simd_result_handlers.h} +290 -142
- data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +54 -0
- data/vendor/faiss/faiss/impl/hnsw/LockVector.h +64 -0
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +91 -0
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -0
- data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +104 -0
- data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +111 -0
- data/vendor/faiss/faiss/impl/index_read.cpp +1950 -505
- data/vendor/faiss/faiss/impl/index_read_utils.h +1 -2
- data/vendor/faiss/faiss/impl/index_write.cpp +112 -21
- data/vendor/faiss/faiss/impl/io.cpp +6 -6
- data/vendor/faiss/faiss/impl/io_macros.h +33 -16
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +10 -10
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +81 -40
- data/vendor/faiss/faiss/impl/lattice_Zn.h +6 -6
- data/vendor/faiss/faiss/impl/mapped_io.cpp +15 -8
- data/vendor/faiss/faiss/impl/platform_macros.h +11 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +549 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +245 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.h +105 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +106 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +21 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +21 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +21 -0
- data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx2.h → pq_code_distance/pq_code_distance-avx2.h} +43 -220
- data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx512.h → pq_code_distance/pq_code_distance-avx512.h} +25 -112
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +59 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +96 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +256 -0
- data/vendor/faiss/faiss/impl/{code_distance/code_distance-sve.h → pq_code_distance/pq_code_distance-sve.cpp} +57 -146
- data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +68 -0
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +320 -483
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
- data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +121 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +137 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +371 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +190 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +94 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +603 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +597 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +388 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +630 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +311 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +387 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +54 -0
- data/vendor/faiss/faiss/impl/simd_dispatch.h +173 -0
- data/vendor/faiss/faiss/impl/simdlib/simdlib.h +57 -0
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_avx2.h +274 -171
- data/vendor/faiss/faiss/impl/simdlib/simdlib_avx512.h +414 -0
- data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +44 -0
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_emulated.h +231 -166
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_neon.h +275 -217
- data/vendor/faiss/faiss/{utils → impl/simdlib}/simdlib_ppc64.h +201 -160
- data/vendor/faiss/faiss/impl/svs_io.cpp +12 -3
- data/vendor/faiss/faiss/impl/svs_io.h +8 -2
- data/vendor/faiss/faiss/index_factory.cpp +115 -28
- data/vendor/faiss/faiss/index_io.h +53 -3
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +73 -20
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +24 -14
- data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +157 -73
- data/vendor/faiss/faiss/invlists/InvertedLists.h +86 -23
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +4 -4
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +14 -14
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +9 -19
- data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +2 -2
- data/vendor/faiss/faiss/svs/IndexSVSFlat.h +2 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +350 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVF.h +128 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.cpp +40 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLVQ.h +43 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +225 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.h +71 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +25 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +19 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +19 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +14 -0
- data/vendor/faiss/faiss/utils/Heap.cpp +56 -10
- data/vendor/faiss/faiss/utils/Heap.h +21 -0
- data/vendor/faiss/faiss/utils/NeuralNet.cpp +54 -40
- data/vendor/faiss/faiss/utils/NeuralNet.h +1 -1
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +10 -4
- data/vendor/faiss/faiss/utils/distances.cpp +507 -559
- data/vendor/faiss/faiss/utils/distances.h +118 -1
- data/vendor/faiss/faiss/utils/distances_dispatch.h +250 -0
- data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +8 -7
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +33 -14
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +12 -1
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +16 -293
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +57 -0
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +290 -0
- data/vendor/faiss/faiss/utils/distances_simd.cpp +72 -3681
- data/vendor/faiss/faiss/utils/extra_distances.cpp +60 -102
- data/vendor/faiss/faiss/utils/extra_distances.h +79 -7
- data/vendor/faiss/faiss/utils/hamming-inl.h +13 -11
- data/vendor/faiss/faiss/utils/hamming.cpp +66 -517
- data/vendor/faiss/faiss/utils/hamming.h +92 -2
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +287 -10
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +15 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx2.h +142 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +234 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-generic.h +368 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +322 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-rvv.h +39 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer.h +146 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +481 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +15 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +15 -0
- data/vendor/faiss/faiss/utils/partitioning.cpp +66 -987
- data/vendor/faiss/faiss/utils/partitioning.h +31 -0
- data/vendor/faiss/faiss/utils/popcount.h +29 -0
- data/vendor/faiss/faiss/utils/pq_code_distance.h +251 -0
- data/vendor/faiss/faiss/utils/prefetch.h +2 -2
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +30 -30
- data/vendor/faiss/faiss/utils/quantize_lut.h +1 -1
- data/vendor/faiss/faiss/utils/rabitq_simd.h +124 -343
- data/vendor/faiss/faiss/utils/random.cpp +6 -6
- data/vendor/faiss/faiss/utils/simd_impl/IVFFlatScanner-inl.h +51 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +154 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +777 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +306 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +1431 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +1095 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +189 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_simdlib256.h +195 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +392 -0
- data/vendor/faiss/faiss/utils/{distances_fused/simdlib_based.h → simd_impl/exhaustive_L2sqr_blas_cmax.h} +5 -10
- data/vendor/faiss/faiss/utils/simd_impl/hamming_impl.h +481 -0
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +14 -0
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +14 -0
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +1085 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +355 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +477 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +55 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +55 -0
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +32 -0
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +43 -0
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +57 -0
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +45 -0
- data/vendor/faiss/faiss/utils/simd_levels.cpp +334 -0
- data/vendor/faiss/faiss/utils/simd_levels.h +183 -0
- data/vendor/faiss/faiss/utils/sorting.cpp +48 -36
- data/vendor/faiss/faiss/utils/utils.cpp +21 -14
- data/vendor/faiss/faiss/utils/utils.h +3 -3
- metadata +156 -42
- data/vendor/faiss/faiss/impl/RaBitQStats.cpp +0 -29
- data/vendor/faiss/faiss/impl/RaBitQStats.h +0 -56
- data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +0 -81
- data/vendor/faiss/faiss/impl/code_distance/code_distance.h +0 -186
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +0 -216
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +0 -224
- data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +0 -84
- data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +0 -196
- data/vendor/faiss/faiss/utils/approx_topk/mode.h +0 -34
- data/vendor/faiss/faiss/utils/distances_fused/avx512.h +0 -36
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +0 -228
- data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +0 -462
- data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +0 -490
- data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -450
- data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +0 -87
- data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +0 -524
- data/vendor/faiss/faiss/utils/simdlib.h +0 -42
- data/vendor/faiss/faiss/utils/simdlib_avx512.h +0 -296
- /data/vendor/faiss/faiss/{cppcontrib/factory_tools.h → factory_tools.h} +0 -0
|
@@ -19,7 +19,17 @@
|
|
|
19
19
|
#include <faiss/impl/FaissAssert.h>
|
|
20
20
|
#include <faiss/utils/hamming.h>
|
|
21
21
|
|
|
22
|
-
#include <faiss/impl/
|
|
22
|
+
#include <faiss/impl/pq_code_distance/pq_code_distance-generic.h>
|
|
23
|
+
#include <faiss/impl/simd_dispatch.h>
|
|
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
|
|
23
33
|
|
|
24
34
|
namespace faiss {
|
|
25
35
|
|
|
@@ -27,11 +37,11 @@ namespace faiss {
|
|
|
27
37
|
* IndexPQ implementation
|
|
28
38
|
********************************************************/
|
|
29
39
|
|
|
30
|
-
IndexPQ::IndexPQ(int
|
|
31
|
-
: 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) {
|
|
32
42
|
is_trained = false;
|
|
33
43
|
do_polysemous_training = false;
|
|
34
|
-
polysemous_ht = nbits * M + 1;
|
|
44
|
+
polysemous_ht = static_cast<int>(nbits * M) + 1;
|
|
35
45
|
search_type = ST_PQ;
|
|
36
46
|
encode_signs = false;
|
|
37
47
|
code_size = pq.code_size;
|
|
@@ -41,7 +51,7 @@ IndexPQ::IndexPQ() {
|
|
|
41
51
|
metric_type = METRIC_L2;
|
|
42
52
|
is_trained = false;
|
|
43
53
|
do_polysemous_training = false;
|
|
44
|
-
polysemous_ht = pq.nbits * pq.M + 1;
|
|
54
|
+
polysemous_ht = static_cast<int>(pq.nbits * pq.M) + 1;
|
|
45
55
|
search_type = ST_PQ;
|
|
46
56
|
encode_signs = false;
|
|
47
57
|
}
|
|
@@ -52,8 +62,9 @@ void IndexPQ::train(idx_t n, const float* x) {
|
|
|
52
62
|
} else {
|
|
53
63
|
idx_t ntrain_perm = polysemous_training.ntrain_permutation;
|
|
54
64
|
|
|
55
|
-
if (ntrain_perm > n / 4)
|
|
65
|
+
if (ntrain_perm > n / 4) {
|
|
56
66
|
ntrain_perm = n / 4;
|
|
67
|
+
}
|
|
57
68
|
if (verbose) {
|
|
58
69
|
printf("PQ training on %" PRId64 " points, remains %" PRId64
|
|
59
70
|
" points: "
|
|
@@ -70,80 +81,10 @@ void IndexPQ::train(idx_t n, const float* x) {
|
|
|
70
81
|
is_trained = true;
|
|
71
82
|
}
|
|
72
83
|
|
|
73
|
-
namespace {
|
|
74
|
-
|
|
75
|
-
template <class PQDecoder>
|
|
76
|
-
struct PQDistanceComputer : FlatCodesDistanceComputer {
|
|
77
|
-
size_t d;
|
|
78
|
-
MetricType metric;
|
|
79
|
-
idx_t nb;
|
|
80
|
-
const ProductQuantizer& pq;
|
|
81
|
-
const float* sdc;
|
|
82
|
-
std::vector<float> precomputed_table;
|
|
83
|
-
size_t ndis;
|
|
84
|
-
const float* q;
|
|
85
|
-
|
|
86
|
-
float distance_to_code(const uint8_t* code) final {
|
|
87
|
-
ndis++;
|
|
88
|
-
|
|
89
|
-
float dis = distance_single_code<PQDecoder>(
|
|
90
|
-
pq.M, pq.nbits, precomputed_table.data(), code);
|
|
91
|
-
return dis;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
float symmetric_dis(idx_t i, idx_t j) override {
|
|
95
|
-
FAISS_THROW_IF_NOT(sdc);
|
|
96
|
-
const float* sdci = sdc;
|
|
97
|
-
float accu = 0;
|
|
98
|
-
PQDecoder codei(codes + i * code_size, pq.nbits);
|
|
99
|
-
PQDecoder codej(codes + j * code_size, pq.nbits);
|
|
100
|
-
|
|
101
|
-
for (int l = 0; l < pq.M; l++) {
|
|
102
|
-
accu += sdci[codei.decode() + (codej.decode() << codei.nbits)];
|
|
103
|
-
sdci += uint64_t(1) << (2 * codei.nbits);
|
|
104
|
-
}
|
|
105
|
-
ndis++;
|
|
106
|
-
return accu;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
explicit PQDistanceComputer(const IndexPQ& storage)
|
|
110
|
-
: FlatCodesDistanceComputer(
|
|
111
|
-
storage.codes.data(),
|
|
112
|
-
storage.code_size),
|
|
113
|
-
pq(storage.pq),
|
|
114
|
-
q(nullptr) {
|
|
115
|
-
precomputed_table.resize(pq.M * pq.ksub);
|
|
116
|
-
nb = storage.ntotal;
|
|
117
|
-
d = storage.d;
|
|
118
|
-
metric = storage.metric_type;
|
|
119
|
-
if (pq.sdc_table.size() == pq.ksub * pq.ksub * pq.M) {
|
|
120
|
-
sdc = pq.sdc_table.data();
|
|
121
|
-
} else {
|
|
122
|
-
sdc = nullptr;
|
|
123
|
-
}
|
|
124
|
-
ndis = 0;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
void set_query(const float* x) override {
|
|
128
|
-
q = x;
|
|
129
|
-
if (metric == METRIC_L2) {
|
|
130
|
-
pq.compute_distance_table(x, precomputed_table.data());
|
|
131
|
-
} else {
|
|
132
|
-
pq.compute_inner_prod_table(x, precomputed_table.data());
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
} // namespace
|
|
138
|
-
|
|
139
84
|
FlatCodesDistanceComputer* IndexPQ::get_FlatCodesDistanceComputer() const {
|
|
140
|
-
|
|
141
|
-
return
|
|
142
|
-
}
|
|
143
|
-
return new PQDistanceComputer<PQDecoder16>(*this);
|
|
144
|
-
} else {
|
|
145
|
-
return new PQDistanceComputer<PQDecoderGeneric>(*this);
|
|
146
|
-
}
|
|
85
|
+
return with_simd_level([&]<SIMDLevel SL>() {
|
|
86
|
+
return pq_code_distance::get_PQFlatCodesDistanceComputer<SL>(*this);
|
|
87
|
+
});
|
|
147
88
|
}
|
|
148
89
|
|
|
149
90
|
/*****************************************
|
|
@@ -206,14 +147,16 @@ void IndexPQ::search(
|
|
|
206
147
|
if (!encode_signs) {
|
|
207
148
|
pq.compute_codes(x, q_codes.get(), n);
|
|
208
149
|
} else {
|
|
209
|
-
FAISS_THROW_IF_NOT(d == pq.nbits * pq.M);
|
|
150
|
+
FAISS_THROW_IF_NOT(static_cast<size_t>(d) == pq.nbits * pq.M);
|
|
210
151
|
memset(q_codes.get(), 0, n * pq.code_size);
|
|
211
|
-
for (
|
|
152
|
+
for (idx_t i = 0; i < n; i++) {
|
|
212
153
|
const float* xi = x + i * d;
|
|
213
154
|
uint8_t* code = q_codes.get() + i * pq.code_size;
|
|
214
|
-
for (
|
|
215
|
-
if (xi[j] > 0)
|
|
155
|
+
for (size_t j = 0; j < static_cast<size_t>(d); j++) {
|
|
156
|
+
if (xi[j] > 0) {
|
|
216
157
|
code[j >> 3] |= 1 << (j & 7);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
217
160
|
}
|
|
218
161
|
}
|
|
219
162
|
|
|
@@ -249,8 +192,9 @@ void IndexPQ::search(
|
|
|
249
192
|
}
|
|
250
193
|
|
|
251
194
|
// convert distances to floats
|
|
252
|
-
for (
|
|
195
|
+
for (idx_t i = 0; i < k * n; i++) {
|
|
253
196
|
distances[i] = idistances[i];
|
|
197
|
+
}
|
|
254
198
|
}
|
|
255
199
|
|
|
256
200
|
indexPQ_stats.nq += n;
|
|
@@ -264,59 +208,8 @@ void IndexPQStats::reset() {
|
|
|
264
208
|
|
|
265
209
|
IndexPQStats indexPQ_stats;
|
|
266
210
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
template <class HammingComputer>
|
|
270
|
-
size_t polysemous_inner_loop(
|
|
271
|
-
const IndexPQ* index,
|
|
272
|
-
const float* dis_table_qi,
|
|
273
|
-
const uint8_t* q_code,
|
|
274
|
-
size_t k,
|
|
275
|
-
float* heap_dis,
|
|
276
|
-
int64_t* heap_ids,
|
|
277
|
-
int ht) {
|
|
278
|
-
int M = index->pq.M;
|
|
279
|
-
int code_size = index->pq.code_size;
|
|
280
|
-
int ksub = index->pq.ksub;
|
|
281
|
-
size_t ntotal = index->ntotal;
|
|
282
|
-
|
|
283
|
-
const uint8_t* b_code = index->codes.data();
|
|
284
|
-
|
|
285
|
-
size_t n_pass_i = 0;
|
|
286
|
-
|
|
287
|
-
HammingComputer hc(q_code, code_size);
|
|
288
|
-
|
|
289
|
-
for (int64_t bi = 0; bi < ntotal; bi++) {
|
|
290
|
-
int hd = hc.hamming(b_code);
|
|
291
|
-
|
|
292
|
-
if (hd < ht) {
|
|
293
|
-
n_pass_i++;
|
|
294
|
-
|
|
295
|
-
float dis = 0;
|
|
296
|
-
const float* dis_table = dis_table_qi;
|
|
297
|
-
for (int m = 0; m < M; m++) {
|
|
298
|
-
dis += dis_table[b_code[m]];
|
|
299
|
-
dis_table += ksub;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
if (dis < heap_dis[0]) {
|
|
303
|
-
maxheap_replace_top(k, heap_dis, heap_ids, dis, bi);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
b_code += code_size;
|
|
307
|
-
}
|
|
308
|
-
return n_pass_i;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
struct Run_polysemous_inner_loop {
|
|
312
|
-
using T = size_t;
|
|
313
|
-
template <class HammingComputer, class... Types>
|
|
314
|
-
size_t f(Types... args) {
|
|
315
|
-
return polysemous_inner_loop<HammingComputer>(args...);
|
|
316
|
-
}
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
} // anonymous namespace
|
|
211
|
+
// polysemous_inner_loop template code is now in
|
|
212
|
+
// impl/binary_hamming/IndexPQ_impl.h (compiled per-ISA)
|
|
320
213
|
|
|
321
214
|
void IndexPQ::search_core_polysemous(
|
|
322
215
|
idx_t n,
|
|
@@ -330,7 +223,7 @@ void IndexPQ::search_core_polysemous(
|
|
|
330
223
|
FAISS_THROW_IF_NOT(pq.nbits == 8);
|
|
331
224
|
|
|
332
225
|
if (param_polysemous_ht == 0) {
|
|
333
|
-
param_polysemous_ht = pq.nbits * pq.M + 1;
|
|
226
|
+
param_polysemous_ht = static_cast<int>(pq.nbits * pq.M) + 1;
|
|
334
227
|
}
|
|
335
228
|
|
|
336
229
|
// PQ distance tables
|
|
@@ -366,37 +259,39 @@ void IndexPQ::search_core_polysemous(
|
|
|
366
259
|
maxheap_heapify(k, heap_dis, heap_ids);
|
|
367
260
|
|
|
368
261
|
if (!generalized_hamming) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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
|
+
});
|
|
380
273
|
|
|
381
274
|
} else { // generalized hamming
|
|
382
275
|
switch (pq.code_size) {
|
|
383
|
-
#define DISPATCH(cs)
|
|
384
|
-
case cs:
|
|
385
|
-
n_pass += polysemous_inner_loop<
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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); \
|
|
393
287
|
break;
|
|
394
288
|
DISPATCH(8)
|
|
395
289
|
DISPATCH(16)
|
|
396
290
|
DISPATCH(32)
|
|
397
291
|
default:
|
|
398
292
|
if (pq.code_size % 8 == 0) {
|
|
399
|
-
n_pass += polysemous_inner_loop<
|
|
293
|
+
n_pass += polysemous_inner_loop<
|
|
294
|
+
GenHammingComputerM8_tpl<SIMDLevel::NONE>>(
|
|
400
295
|
this,
|
|
401
296
|
dis_table_qi,
|
|
402
297
|
q_code,
|
|
@@ -472,7 +367,7 @@ void IndexPQ::hamming_distance_histogram(
|
|
|
472
367
|
nb = ntotal;
|
|
473
368
|
b_codes = codes.data();
|
|
474
369
|
}
|
|
475
|
-
int nbits = pq.M * pq.nbits;
|
|
370
|
+
int nbits = static_cast<int>(pq.M * pq.nbits);
|
|
476
371
|
memset(hist, 0, sizeof(*hist) * (nbits + 1));
|
|
477
372
|
size_t bs = 256;
|
|
478
373
|
|
|
@@ -484,8 +379,9 @@ void IndexPQ::hamming_distance_histogram(
|
|
|
484
379
|
for (idx_t q0 = 0; q0 < n; q0 += bs) {
|
|
485
380
|
// printf ("dis stats: %zd/%zd\n", q0, n);
|
|
486
381
|
size_t q1 = q0 + bs;
|
|
487
|
-
if (q1 > n)
|
|
382
|
+
if (q1 > static_cast<size_t>(n)) {
|
|
488
383
|
q1 = n;
|
|
384
|
+
}
|
|
489
385
|
|
|
490
386
|
hammings(
|
|
491
387
|
q_codes.get() + q0 * pq.code_size,
|
|
@@ -495,13 +391,15 @@ void IndexPQ::hamming_distance_histogram(
|
|
|
495
391
|
pq.code_size,
|
|
496
392
|
distances.get());
|
|
497
393
|
|
|
498
|
-
for (size_t i = 0; i < nb * (q1 - q0); i++)
|
|
394
|
+
for (size_t i = 0; i < nb * (q1 - q0); i++) {
|
|
499
395
|
histi[distances[i]]++;
|
|
396
|
+
}
|
|
500
397
|
}
|
|
501
398
|
#pragma omp critical
|
|
502
399
|
{
|
|
503
|
-
for (int i = 0; i <= nbits; i++)
|
|
400
|
+
for (int i = 0; i <= nbits; i++) {
|
|
504
401
|
hist[i] += histi[i];
|
|
402
|
+
}
|
|
505
403
|
}
|
|
506
404
|
}
|
|
507
405
|
}
|
|
@@ -517,7 +415,7 @@ struct PreSortedArray {
|
|
|
517
415
|
const T* x;
|
|
518
416
|
int N;
|
|
519
417
|
|
|
520
|
-
explicit PreSortedArray(int
|
|
418
|
+
explicit PreSortedArray(int N_in) : N(N_in) {}
|
|
521
419
|
void init(const T* x_2) {
|
|
522
420
|
this->x = x_2;
|
|
523
421
|
}
|
|
@@ -554,15 +452,17 @@ struct SortedArray {
|
|
|
554
452
|
int N;
|
|
555
453
|
std::vector<int> perm;
|
|
556
454
|
|
|
557
|
-
explicit SortedArray(int
|
|
558
|
-
this->N =
|
|
559
|
-
perm.resize(
|
|
455
|
+
explicit SortedArray(int N_in) {
|
|
456
|
+
this->N = N_in;
|
|
457
|
+
perm.resize(N_in);
|
|
560
458
|
}
|
|
561
459
|
|
|
562
460
|
void init(const T* x_2) {
|
|
563
461
|
this->x = x_2;
|
|
564
|
-
|
|
462
|
+
FAISS_THROW_IF_NOT(!perm.empty());
|
|
463
|
+
for (int n = 0; n < N; n++) {
|
|
565
464
|
perm[n] = n;
|
|
465
|
+
}
|
|
566
466
|
ArgSort<T> cmp = {x_2};
|
|
567
467
|
std::sort(perm.begin(), perm.end(), cmp);
|
|
568
468
|
}
|
|
@@ -629,22 +529,24 @@ struct SemiSortedArray {
|
|
|
629
529
|
using HC = CMax<T, int>;
|
|
630
530
|
std::vector<int> perm;
|
|
631
531
|
|
|
632
|
-
int k; // k elements are sorted
|
|
532
|
+
int k = 0; // k elements are sorted
|
|
633
533
|
|
|
634
534
|
int initial_k, k_factor;
|
|
635
535
|
|
|
636
|
-
explicit SemiSortedArray(int
|
|
637
|
-
this->N =
|
|
638
|
-
perm.resize(
|
|
639
|
-
perm.resize(
|
|
536
|
+
explicit SemiSortedArray(int N_in) {
|
|
537
|
+
this->N = N_in;
|
|
538
|
+
perm.resize(N_in);
|
|
539
|
+
perm.resize(N_in);
|
|
640
540
|
initial_k = 3;
|
|
641
541
|
k_factor = 4;
|
|
642
542
|
}
|
|
643
543
|
|
|
644
544
|
void init(const T* x_2) {
|
|
645
545
|
this->x = x_2;
|
|
646
|
-
|
|
546
|
+
FAISS_THROW_IF_NOT(!perm.empty());
|
|
547
|
+
for (int n = 0; n < N; n++) {
|
|
647
548
|
perm[n] = n;
|
|
549
|
+
}
|
|
648
550
|
k = 0;
|
|
649
551
|
grow(initial_k);
|
|
650
552
|
}
|
|
@@ -678,7 +580,7 @@ struct SemiSortedArray {
|
|
|
678
580
|
|
|
679
581
|
// remap orders counted from smallest to indices in array
|
|
680
582
|
int get_ord(int n) {
|
|
681
|
-
|
|
583
|
+
FAISS_THROW_IF_NOT(n < k);
|
|
682
584
|
return perm[n];
|
|
683
585
|
}
|
|
684
586
|
};
|
|
@@ -721,7 +623,8 @@ struct MinSumK {
|
|
|
721
623
|
* terms involved in the sum.
|
|
722
624
|
*/
|
|
723
625
|
using HC = CMin<T, int64_t>;
|
|
724
|
-
size_t heap_capacity
|
|
626
|
+
size_t heap_capacity = 0;
|
|
627
|
+
size_t heap_size = 0;
|
|
725
628
|
T* bh_val;
|
|
726
629
|
int64_t* bh_ids;
|
|
727
630
|
|
|
@@ -733,9 +636,10 @@ struct MinSumK {
|
|
|
733
636
|
// that were seen before.
|
|
734
637
|
std::vector<uint8_t> seen;
|
|
735
638
|
|
|
736
|
-
MinSumK(int
|
|
737
|
-
|
|
738
|
-
|
|
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));
|
|
739
643
|
|
|
740
644
|
// we'll do k steps, each step pushes at most M vals
|
|
741
645
|
bh_val = new T[heap_capacity];
|
|
@@ -746,8 +650,9 @@ struct MinSumK {
|
|
|
746
650
|
seen.resize((n_ids + 7) / 8);
|
|
747
651
|
}
|
|
748
652
|
|
|
749
|
-
for (int m = 0; m < M; m++)
|
|
653
|
+
for (int m = 0; m < M; m++) {
|
|
750
654
|
ssx.push_back(SSA(N));
|
|
655
|
+
}
|
|
751
656
|
}
|
|
752
657
|
|
|
753
658
|
int64_t weight(int i) {
|
|
@@ -759,8 +664,10 @@ struct MinSumK {
|
|
|
759
664
|
}
|
|
760
665
|
|
|
761
666
|
void mark_seen(int64_t i) {
|
|
762
|
-
if (use_seen)
|
|
667
|
+
if (use_seen) {
|
|
668
|
+
FAISS_THROW_IF_NOT(!seen.empty());
|
|
763
669
|
seen[i >> 3] |= 1 << (i & 7);
|
|
670
|
+
}
|
|
764
671
|
}
|
|
765
672
|
|
|
766
673
|
void run(const T* x, int64_t ldx, T* sums, int64_t* terms) {
|
|
@@ -793,11 +700,11 @@ struct MinSumK {
|
|
|
793
700
|
// pop smallest value from heap
|
|
794
701
|
if (use_seen) { // skip already seen elements
|
|
795
702
|
while (is_seen(bh_ids[0])) {
|
|
796
|
-
|
|
703
|
+
FAISS_THROW_IF_NOT(heap_size > 0);
|
|
797
704
|
heap_pop<HC>(heap_size--, bh_val, bh_ids);
|
|
798
705
|
}
|
|
799
706
|
}
|
|
800
|
-
|
|
707
|
+
FAISS_THROW_IF_NOT(heap_size > 0);
|
|
801
708
|
|
|
802
709
|
T sum = sums[k] = bh_val[0];
|
|
803
710
|
int64_t ti = terms[k] = bh_ids[0];
|
|
@@ -816,8 +723,9 @@ struct MinSumK {
|
|
|
816
723
|
for (int m = 0; m < M; m++) {
|
|
817
724
|
int64_t n = ii & (((int64_t)1 << nbit) - 1);
|
|
818
725
|
ii >>= nbit;
|
|
819
|
-
if (n + 1 >= N)
|
|
726
|
+
if (n + 1 >= N) {
|
|
820
727
|
continue;
|
|
728
|
+
}
|
|
821
729
|
|
|
822
730
|
enqueue_follower(ti, m, n, sum);
|
|
823
731
|
}
|
|
@@ -860,8 +768,8 @@ struct MinSumK {
|
|
|
860
768
|
|
|
861
769
|
} // anonymous namespace
|
|
862
770
|
|
|
863
|
-
MultiIndexQuantizer::MultiIndexQuantizer(int
|
|
864
|
-
: Index(
|
|
771
|
+
MultiIndexQuantizer::MultiIndexQuantizer(int d_in, size_t M, size_t nbits)
|
|
772
|
+
: Index(d_in, METRIC_L2), pq(d_in, M, nbits) {
|
|
865
773
|
is_trained = false;
|
|
866
774
|
pq.verbose = verbose;
|
|
867
775
|
}
|
|
@@ -872,8 +780,9 @@ void MultiIndexQuantizer::train(idx_t n, const float* x) {
|
|
|
872
780
|
is_trained = true;
|
|
873
781
|
// count virtual elements in index
|
|
874
782
|
ntotal = 1;
|
|
875
|
-
for (
|
|
783
|
+
for (size_t m = 0; m < pq.M; m++) {
|
|
876
784
|
ntotal *= pq.ksub;
|
|
785
|
+
}
|
|
877
786
|
}
|
|
878
787
|
|
|
879
788
|
// block size used in MultiIndexQuantizer::search
|
|
@@ -918,16 +827,16 @@ void MultiIndexQuantizer::search(
|
|
|
918
827
|
// simple version that just finds the min in each table
|
|
919
828
|
|
|
920
829
|
#pragma omp parallel for
|
|
921
|
-
for (
|
|
830
|
+
for (idx_t i = 0; i < n; i++) {
|
|
922
831
|
const float* dis_table = dis_tables.get() + i * pq.ksub * pq.M;
|
|
923
832
|
float dis = 0;
|
|
924
833
|
idx_t label = 0;
|
|
925
834
|
|
|
926
|
-
for (
|
|
835
|
+
for (size_t s = 0; s < pq.M; s++) {
|
|
927
836
|
float vmin = HUGE_VALF;
|
|
928
837
|
idx_t lmin = -1;
|
|
929
838
|
|
|
930
|
-
for (
|
|
839
|
+
for (size_t j = 0; j < pq.ksub; j++) {
|
|
931
840
|
if (dis_table[j] < vmin) {
|
|
932
841
|
vmin = dis_table[j];
|
|
933
842
|
lmin = j;
|
|
@@ -946,9 +855,12 @@ void MultiIndexQuantizer::search(
|
|
|
946
855
|
#pragma omp parallel if (n > 1)
|
|
947
856
|
{
|
|
948
857
|
MinSumK<float, SemiSortedArray<float>, false> msk(
|
|
949
|
-
k,
|
|
858
|
+
static_cast<int>(k),
|
|
859
|
+
static_cast<int>(pq.M),
|
|
860
|
+
static_cast<int>(pq.nbits),
|
|
861
|
+
static_cast<int>(pq.ksub));
|
|
950
862
|
#pragma omp for
|
|
951
|
-
for (
|
|
863
|
+
for (idx_t i = 0; i < n; i++) {
|
|
952
864
|
msk.run(dis_tables.get() + i * pq.ksub * pq.M,
|
|
953
865
|
pq.ksub,
|
|
954
866
|
distances + i * k,
|
|
@@ -960,7 +872,7 @@ void MultiIndexQuantizer::search(
|
|
|
960
872
|
|
|
961
873
|
void MultiIndexQuantizer::reconstruct(idx_t key, float* recons) const {
|
|
962
874
|
int64_t jj = key;
|
|
963
|
-
for (
|
|
875
|
+
for (size_t m = 0; m < pq.M; m++) {
|
|
964
876
|
int64_t n = jj & (((int64_t)1 << pq.nbits) - 1);
|
|
965
877
|
jj >>= pq.nbits;
|
|
966
878
|
memcpy(recons, pq.get_centroids(m, n), sizeof(recons[0]) * pq.dsub);
|
|
@@ -985,15 +897,15 @@ void MultiIndexQuantizer::reset() {
|
|
|
985
897
|
******************************************/
|
|
986
898
|
|
|
987
899
|
MultiIndexQuantizer2::MultiIndexQuantizer2(
|
|
988
|
-
int
|
|
900
|
+
int d_in,
|
|
989
901
|
size_t M,
|
|
990
902
|
size_t nbits,
|
|
991
903
|
Index** indexes)
|
|
992
|
-
: MultiIndexQuantizer(
|
|
904
|
+
: MultiIndexQuantizer(d_in, M, nbits) {
|
|
993
905
|
assign_indexes.resize(M);
|
|
994
|
-
for (
|
|
906
|
+
for (size_t i = 0; i < M; i++) {
|
|
995
907
|
FAISS_THROW_IF_NOT_MSG(
|
|
996
|
-
indexes[i]->d == pq.dsub,
|
|
908
|
+
static_cast<size_t>(indexes[i]->d) == pq.dsub,
|
|
997
909
|
"Provided sub-index has incorrect size");
|
|
998
910
|
assign_indexes[i] = indexes[i];
|
|
999
911
|
}
|
|
@@ -1001,13 +913,14 @@ MultiIndexQuantizer2::MultiIndexQuantizer2(
|
|
|
1001
913
|
}
|
|
1002
914
|
|
|
1003
915
|
MultiIndexQuantizer2::MultiIndexQuantizer2(
|
|
1004
|
-
int
|
|
916
|
+
int d_in,
|
|
1005
917
|
size_t nbits,
|
|
1006
918
|
Index* assign_index_0,
|
|
1007
919
|
Index* assign_index_1)
|
|
1008
|
-
: MultiIndexQuantizer(
|
|
920
|
+
: MultiIndexQuantizer(d_in, 2, nbits) {
|
|
1009
921
|
FAISS_THROW_IF_NOT_MSG(
|
|
1010
|
-
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,
|
|
1011
924
|
"Provided sub-index has incorrect size");
|
|
1012
925
|
assign_indexes.resize(2);
|
|
1013
926
|
assign_indexes[0] = assign_index_0;
|
|
@@ -1018,7 +931,7 @@ MultiIndexQuantizer2::MultiIndexQuantizer2(
|
|
|
1018
931
|
void MultiIndexQuantizer2::train(idx_t n, const float* x) {
|
|
1019
932
|
MultiIndexQuantizer::train(n, x);
|
|
1020
933
|
// add centroids to sub-indexes
|
|
1021
|
-
for (
|
|
934
|
+
for (size_t i = 0; i < pq.M; i++) {
|
|
1022
935
|
assign_indexes[i]->add(pq.ksub, pq.get_centroids(i, 0));
|
|
1023
936
|
}
|
|
1024
937
|
}
|
|
@@ -1037,7 +950,7 @@ void MultiIndexQuantizer2::search(
|
|
|
1037
950
|
return;
|
|
1038
951
|
}
|
|
1039
952
|
|
|
1040
|
-
int k2 = std::min(K, int64_t(pq.ksub));
|
|
953
|
+
int k2 = static_cast<int>(std::min(K, int64_t(pq.ksub)));
|
|
1041
954
|
FAISS_THROW_IF_NOT(k2);
|
|
1042
955
|
|
|
1043
956
|
int64_t M = pq.M;
|
|
@@ -1048,10 +961,10 @@ void MultiIndexQuantizer2::search(
|
|
|
1048
961
|
std::vector<float> sub_dis(n * M * k2);
|
|
1049
962
|
std::vector<float> xsub(n * dsub);
|
|
1050
963
|
|
|
1051
|
-
for (
|
|
964
|
+
for (int64_t m = 0; m < M; m++) {
|
|
1052
965
|
float* xdest = xsub.data();
|
|
1053
966
|
const float* xsrc = x + m * dsub;
|
|
1054
|
-
for (
|
|
967
|
+
for (idx_t j = 0; j < n; j++) {
|
|
1055
968
|
memcpy(xdest, xsrc, dsub * sizeof(xdest[0]));
|
|
1056
969
|
xsrc += d;
|
|
1057
970
|
xdest += dsub;
|
|
@@ -1063,13 +976,13 @@ void MultiIndexQuantizer2::search(
|
|
|
1063
976
|
|
|
1064
977
|
if (K == 1) {
|
|
1065
978
|
// simple version that just finds the min in each table
|
|
1066
|
-
|
|
979
|
+
FAISS_THROW_IF_NOT(k2 == 1);
|
|
1067
980
|
|
|
1068
|
-
for (
|
|
981
|
+
for (idx_t i = 0; i < n; i++) {
|
|
1069
982
|
float dis = 0;
|
|
1070
983
|
idx_t label = 0;
|
|
1071
984
|
|
|
1072
|
-
for (
|
|
985
|
+
for (int64_t m = 0; m < M; m++) {
|
|
1073
986
|
float vmin = sub_dis[i + m * n];
|
|
1074
987
|
idx_t lmin = sub_ids[i + m * n];
|
|
1075
988
|
dis += vmin;
|
|
@@ -1083,9 +996,12 @@ void MultiIndexQuantizer2::search(
|
|
|
1083
996
|
#pragma omp parallel if (n > 1)
|
|
1084
997
|
{
|
|
1085
998
|
MinSumK<float, PreSortedArray<float>, false> msk(
|
|
1086
|
-
K,
|
|
999
|
+
static_cast<int>(K),
|
|
1000
|
+
static_cast<int>(pq.M),
|
|
1001
|
+
static_cast<int>(pq.nbits),
|
|
1002
|
+
k2);
|
|
1087
1003
|
#pragma omp for
|
|
1088
|
-
for (
|
|
1004
|
+
for (idx_t i = 0; i < n; i++) {
|
|
1089
1005
|
idx_t* li = labels + i * K;
|
|
1090
1006
|
msk.run(&sub_dis[i * k2], k2 * n, distances + i * K, li);
|
|
1091
1007
|
|
|
@@ -1095,12 +1011,12 @@ void MultiIndexQuantizer2::search(
|
|
|
1095
1011
|
int64_t ld_idmap = k2 * n;
|
|
1096
1012
|
int64_t mask1 = ksub - (int64_t)1;
|
|
1097
1013
|
|
|
1098
|
-
for (
|
|
1014
|
+
for (idx_t k = 0; k < K; k++) {
|
|
1099
1015
|
const idx_t* idmap = idmap0;
|
|
1100
1016
|
int64_t vin = li[k];
|
|
1101
1017
|
int64_t vout = 0;
|
|
1102
|
-
|
|
1103
|
-
for (
|
|
1018
|
+
size_t bs = 0;
|
|
1019
|
+
for (int64_t m = 0; m < M; m++) {
|
|
1104
1020
|
int64_t s = vin & mask1;
|
|
1105
1021
|
vin >>= pq.nbits;
|
|
1106
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
|
|