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
|
@@ -8,44 +8,51 @@
|
|
|
8
8
|
#include <faiss/IndexIVFPQFastScan.h>
|
|
9
9
|
|
|
10
10
|
#include <array>
|
|
11
|
-
#include <cassert>
|
|
12
11
|
#include <cstdio>
|
|
13
12
|
|
|
14
13
|
#include <memory>
|
|
15
14
|
|
|
16
15
|
#include <faiss/impl/AuxIndexStructures.h>
|
|
17
16
|
#include <faiss/impl/FaissAssert.h>
|
|
18
|
-
#include <faiss/
|
|
17
|
+
#include <faiss/impl/ResultHandler.h>
|
|
18
|
+
#include <faiss/impl/simdlib/simdlib_dispatch.h>
|
|
19
19
|
#include <faiss/utils/distances.h>
|
|
20
|
-
#include <faiss/utils/
|
|
20
|
+
#include <faiss/utils/distances_dispatch.h>
|
|
21
|
+
#include <faiss/utils/extra_distances.h>
|
|
21
22
|
|
|
22
23
|
#include <faiss/invlists/BlockInvertedLists.h>
|
|
23
24
|
|
|
24
|
-
#include <faiss/impl/
|
|
25
|
-
#include <faiss/impl/
|
|
25
|
+
#include <faiss/impl/fast_scan/FastScanDistancePostProcessing.h>
|
|
26
|
+
#include <faiss/impl/fast_scan/fast_scan.h>
|
|
27
|
+
#include <faiss/impl/fast_scan/simd_result_handlers.h>
|
|
26
28
|
|
|
27
29
|
namespace faiss {
|
|
28
30
|
|
|
29
|
-
using namespace simd_result_handlers;
|
|
30
|
-
|
|
31
31
|
inline size_t roundup(size_t a, size_t b) {
|
|
32
32
|
return (a + b - 1) / b * b;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
IndexIVFPQFastScan::IndexIVFPQFastScan(
|
|
36
|
-
Index*
|
|
37
|
-
size_t
|
|
38
|
-
size_t
|
|
39
|
-
size_t
|
|
40
|
-
size_t
|
|
36
|
+
Index* quantizer_in,
|
|
37
|
+
size_t d_in,
|
|
38
|
+
size_t nlist_in,
|
|
39
|
+
size_t M_in,
|
|
40
|
+
size_t nbits_in,
|
|
41
41
|
MetricType metric,
|
|
42
|
-
int
|
|
43
|
-
bool
|
|
44
|
-
: IndexIVFFastScan(
|
|
45
|
-
|
|
42
|
+
int bbs_in,
|
|
43
|
+
bool own_invlists_in)
|
|
44
|
+
: IndexIVFFastScan(
|
|
45
|
+
quantizer_in,
|
|
46
|
+
d_in,
|
|
47
|
+
nlist_in,
|
|
48
|
+
0,
|
|
49
|
+
metric,
|
|
50
|
+
own_invlists_in),
|
|
51
|
+
pq(d_in, M_in, nbits_in) {
|
|
46
52
|
by_residual = false; // set to false by default because it's faster
|
|
47
53
|
|
|
48
|
-
init_fastscan(
|
|
54
|
+
init_fastscan(
|
|
55
|
+
&pq, M_in, nbits_in, nlist_in, metric, bbs_in, own_invlists_in);
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
IndexIVFPQFastScan::IndexIVFPQFastScan() {
|
|
@@ -54,7 +61,7 @@ IndexIVFPQFastScan::IndexIVFPQFastScan() {
|
|
|
54
61
|
M2 = 0;
|
|
55
62
|
}
|
|
56
63
|
|
|
57
|
-
IndexIVFPQFastScan::IndexIVFPQFastScan(const IndexIVFPQ& orig, int
|
|
64
|
+
IndexIVFPQFastScan::IndexIVFPQFastScan(const IndexIVFPQ& orig, int bbs_in)
|
|
58
65
|
: IndexIVFFastScan(
|
|
59
66
|
orig.quantizer,
|
|
60
67
|
orig.d,
|
|
@@ -71,7 +78,7 @@ IndexIVFPQFastScan::IndexIVFPQFastScan(const IndexIVFPQ& orig, int bbs)
|
|
|
71
78
|
orig.pq.nbits,
|
|
72
79
|
orig.nlist,
|
|
73
80
|
orig.metric_type,
|
|
74
|
-
|
|
81
|
+
bbs_in,
|
|
75
82
|
orig.own_invlists);
|
|
76
83
|
|
|
77
84
|
by_residual = orig.by_residual;
|
|
@@ -88,7 +95,7 @@ IndexIVFPQFastScan::IndexIVFPQFastScan(const IndexIVFPQ& orig, int bbs)
|
|
|
88
95
|
}
|
|
89
96
|
|
|
90
97
|
#pragma omp parallel for if (nlist > 100)
|
|
91
|
-
for (idx_t i = 0; i < nlist; i++) {
|
|
98
|
+
for (idx_t i = 0; i < static_cast<idx_t>(nlist); i++) {
|
|
92
99
|
size_t nb = orig.invlists->list_size(i);
|
|
93
100
|
size_t nb2 = roundup(nb, bbs);
|
|
94
101
|
AlignedTable<uint8_t> tmp(nb2 * M2 / 2);
|
|
@@ -110,6 +117,10 @@ IndexIVFPQFastScan::IndexIVFPQFastScan(const IndexIVFPQ& orig, int bbs)
|
|
|
110
117
|
orig_invlists = orig.invlists;
|
|
111
118
|
}
|
|
112
119
|
|
|
120
|
+
size_t IndexIVFPQFastScan::fast_scan_code_size() const {
|
|
121
|
+
return M2 / 2;
|
|
122
|
+
}
|
|
123
|
+
|
|
113
124
|
/*********************************************************
|
|
114
125
|
* Training
|
|
115
126
|
*********************************************************/
|
|
@@ -117,7 +128,7 @@ IndexIVFPQFastScan::IndexIVFPQFastScan(const IndexIVFPQ& orig, int bbs)
|
|
|
117
128
|
void IndexIVFPQFastScan::train_encoder(
|
|
118
129
|
idx_t n,
|
|
119
130
|
const float* x,
|
|
120
|
-
const idx_t* assign) {
|
|
131
|
+
const idx_t* /*assign*/) {
|
|
121
132
|
pq.verbose = verbose;
|
|
122
133
|
pq.train(n, x);
|
|
123
134
|
|
|
@@ -152,7 +163,7 @@ void IndexIVFPQFastScan::encode_vectors(
|
|
|
152
163
|
bool include_listnos) const {
|
|
153
164
|
if (by_residual) {
|
|
154
165
|
AlignedTable<float> residuals(n * d);
|
|
155
|
-
for (
|
|
166
|
+
for (idx_t i = 0; i < n; i++) {
|
|
156
167
|
if (list_nos[i] < 0) {
|
|
157
168
|
memset(residuals.data() + i * d, 0, sizeof(residuals[0]) * d);
|
|
158
169
|
} else {
|
|
@@ -179,16 +190,19 @@ void IndexIVFPQFastScan::encode_vectors(
|
|
|
179
190
|
* Look-Up Table functions
|
|
180
191
|
*********************************************************/
|
|
181
192
|
|
|
193
|
+
// Explicit SIMD-level alias (no global bare aliases).
|
|
194
|
+
using simd8float32 = simd8float32_tpl<SINGLE_SIMD_LEVEL_256>;
|
|
195
|
+
|
|
182
196
|
void fvec_madd_simd(
|
|
183
197
|
size_t n,
|
|
184
198
|
const float* a,
|
|
185
199
|
float bf,
|
|
186
200
|
const float* b,
|
|
187
201
|
float* c) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
202
|
+
FAISS_THROW_IF_NOT_MSG(is_aligned_pointer(a), "pointer a is not aligned");
|
|
203
|
+
FAISS_THROW_IF_NOT_MSG(is_aligned_pointer(b), "pointer b is not aligned");
|
|
204
|
+
FAISS_THROW_IF_NOT_MSG(is_aligned_pointer(c), "pointer c is not aligned");
|
|
205
|
+
FAISS_THROW_IF_NOT_MSG(n % 8 == 0, "n must be a multiple of 8");
|
|
192
206
|
simd8float32 bf8(bf);
|
|
193
207
|
n /= 8;
|
|
194
208
|
for (size_t i = 0; i < n; i++) {
|
|
@@ -215,23 +229,24 @@ void IndexIVFPQFastScan::compute_LUT(
|
|
|
215
229
|
AlignedTable<float>& biases,
|
|
216
230
|
const FastScanDistancePostProcessing&) const {
|
|
217
231
|
size_t dim12 = pq.ksub * pq.M;
|
|
218
|
-
size_t
|
|
219
|
-
size_t
|
|
232
|
+
size_t pq_d = pq.d;
|
|
233
|
+
size_t cq_nprobe = cq.nprobe;
|
|
220
234
|
|
|
221
235
|
if (by_residual) {
|
|
222
236
|
if (metric_type == METRIC_L2) {
|
|
223
|
-
dis_tables.resize(n *
|
|
237
|
+
dis_tables.resize(n * cq_nprobe * dim12);
|
|
224
238
|
|
|
225
239
|
if (use_precomputed_table == 1) {
|
|
226
|
-
biases.resize(n *
|
|
227
|
-
memcpy(biases.get(), cq.dis, sizeof(float) * n *
|
|
240
|
+
biases.resize(n * cq_nprobe);
|
|
241
|
+
memcpy(biases.get(), cq.dis, sizeof(float) * n * cq_nprobe);
|
|
228
242
|
|
|
229
243
|
AlignedTable<float> ip_table(n * dim12);
|
|
230
244
|
pq.compute_inner_prod_tables(n, x, ip_table.get());
|
|
231
245
|
|
|
232
|
-
#pragma omp parallel for if (n *
|
|
233
|
-
for (idx_t ij = 0; ij < n *
|
|
234
|
-
|
|
246
|
+
#pragma omp parallel for if (n * cq_nprobe > 8000)
|
|
247
|
+
for (idx_t ij = 0; ij < static_cast<idx_t>(n * cq_nprobe);
|
|
248
|
+
ij++) {
|
|
249
|
+
idx_t i = ij / cq_nprobe;
|
|
235
250
|
float* tab = dis_tables.get() + ij * dim12;
|
|
236
251
|
idx_t cij = cq.ids[ij];
|
|
237
252
|
|
|
@@ -250,26 +265,27 @@ void IndexIVFPQFastScan::compute_LUT(
|
|
|
250
265
|
}
|
|
251
266
|
|
|
252
267
|
} else {
|
|
253
|
-
std::unique_ptr<float[]> xrel(new float[n *
|
|
254
|
-
biases.resize(n *
|
|
255
|
-
memset(biases.get(), 0, sizeof(float) * n *
|
|
256
|
-
|
|
257
|
-
#pragma omp parallel for if (n *
|
|
258
|
-
for (idx_t ij = 0; ij < n *
|
|
259
|
-
|
|
260
|
-
|
|
268
|
+
std::unique_ptr<float[]> xrel(new float[n * cq_nprobe * pq_d]);
|
|
269
|
+
biases.resize(n * cq_nprobe);
|
|
270
|
+
memset(biases.get(), 0, sizeof(float) * n * cq_nprobe);
|
|
271
|
+
|
|
272
|
+
#pragma omp parallel for if (n * cq_nprobe > 8000)
|
|
273
|
+
for (idx_t ij = 0; ij < static_cast<idx_t>(n * cq_nprobe);
|
|
274
|
+
ij++) {
|
|
275
|
+
idx_t i = ij / cq_nprobe;
|
|
276
|
+
float* xij = &xrel[ij * pq_d];
|
|
261
277
|
idx_t cij = cq.ids[ij];
|
|
262
278
|
|
|
263
279
|
if (cij >= 0) {
|
|
264
|
-
quantizer->compute_residual(x + i *
|
|
280
|
+
quantizer->compute_residual(x + i * pq_d, xij, cij);
|
|
265
281
|
} else {
|
|
266
282
|
// will fill with NaNs
|
|
267
|
-
memset(xij, -1, sizeof(float) *
|
|
283
|
+
memset(xij, -1, sizeof(float) * pq_d);
|
|
268
284
|
}
|
|
269
285
|
}
|
|
270
286
|
|
|
271
287
|
pq.compute_distance_tables(
|
|
272
|
-
n *
|
|
288
|
+
n * cq_nprobe, xrel.get(), dis_tables.get());
|
|
273
289
|
}
|
|
274
290
|
|
|
275
291
|
} else if (metric_type == METRIC_INNER_PRODUCT) {
|
|
@@ -277,8 +293,8 @@ void IndexIVFPQFastScan::compute_LUT(
|
|
|
277
293
|
pq.compute_inner_prod_tables(n, x, dis_tables.get());
|
|
278
294
|
// compute_inner_prod_tables(pq, n, x, dis_tables.get());
|
|
279
295
|
|
|
280
|
-
biases.resize(n *
|
|
281
|
-
memcpy(biases.get(), cq.dis, sizeof(float) * n *
|
|
296
|
+
biases.resize(n * cq_nprobe);
|
|
297
|
+
memcpy(biases.get(), cq.dis, sizeof(float) * n * cq_nprobe);
|
|
282
298
|
} else {
|
|
283
299
|
FAISS_THROW_FMT("metric %d not supported", metric_type);
|
|
284
300
|
}
|
|
@@ -302,42 +318,74 @@ void IndexIVFPQFastScan::compute_LUT(
|
|
|
302
318
|
namespace {
|
|
303
319
|
|
|
304
320
|
struct IVFPQFastScanScanner : InvertedListScanner {
|
|
305
|
-
|
|
321
|
+
using InvertedListScanner::scan_codes;
|
|
322
|
+
[[maybe_unused]] static constexpr int impl =
|
|
323
|
+
10; // based on search_implem_10
|
|
306
324
|
static constexpr size_t nq = 1; // 1 query at a time.
|
|
307
325
|
const IndexIVFPQFastScan& index;
|
|
308
326
|
AlignedTable<uint8_t> dis_tables;
|
|
309
327
|
AlignedTable<uint16_t> biases;
|
|
328
|
+
std::vector<float> residual;
|
|
310
329
|
std::array<float, 2> normalizers{};
|
|
311
330
|
const float* xi = nullptr;
|
|
312
331
|
|
|
313
332
|
IVFPQFastScanScanner(
|
|
314
|
-
const IndexIVFPQFastScan&
|
|
315
|
-
bool
|
|
316
|
-
const IDSelector*
|
|
317
|
-
: InvertedListScanner(
|
|
318
|
-
this->keep_max = is_similarity_metric(
|
|
333
|
+
const IndexIVFPQFastScan& index_in,
|
|
334
|
+
bool store_pairs_in,
|
|
335
|
+
const IDSelector* sel_in)
|
|
336
|
+
: InvertedListScanner(store_pairs_in, sel_in), index(index_in) {
|
|
337
|
+
this->keep_max = is_similarity_metric(index_in.metric_type);
|
|
338
|
+
residual.resize(index_in.d);
|
|
319
339
|
}
|
|
320
340
|
|
|
321
341
|
void set_query(const float* query) override {
|
|
322
342
|
this->xi = query;
|
|
323
343
|
}
|
|
324
344
|
|
|
325
|
-
void set_list(idx_t
|
|
326
|
-
this->list_no =
|
|
345
|
+
void set_list(idx_t list_no_in, float coarse_dis_in) override {
|
|
346
|
+
this->list_no = list_no_in;
|
|
327
347
|
IndexIVFFastScan::CoarseQuantized cq{
|
|
328
|
-
.nprobe = 1,
|
|
329
|
-
.dis = &
|
|
330
|
-
.ids = &
|
|
348
|
+
.nprobe = 1, // 1 due to explicitly passing in list_no
|
|
349
|
+
.dis = &coarse_dis_in, // dis from query to list_no centroid.
|
|
350
|
+
.ids = &list_no_in, // id of the current list we are scanning
|
|
331
351
|
};
|
|
332
352
|
FastScanDistancePostProcessing empty_context{};
|
|
333
353
|
index.compute_LUT_uint8(
|
|
334
354
|
1, xi, cq, dis_tables, biases, &normalizers[0], empty_context);
|
|
355
|
+
// used in distance_to_code
|
|
356
|
+
index.quantizer->compute_residual(
|
|
357
|
+
this->xi, residual.data(), this->list_no);
|
|
335
358
|
}
|
|
336
359
|
|
|
337
|
-
float distance_to_code(const uint8_t*
|
|
338
|
-
//
|
|
339
|
-
|
|
340
|
-
|
|
360
|
+
float distance_to_code(const uint8_t* code) const override {
|
|
361
|
+
// directly use the PQ tables to compute the distance
|
|
362
|
+
const ProductQuantizer& pq = index.pq;
|
|
363
|
+
// when by_residual, codes are residuals so compare against query
|
|
364
|
+
// residual; otherwise codes are raw vectors so compare against raw
|
|
365
|
+
// query
|
|
366
|
+
const float* x = index.by_residual ? residual.data() : this->xi;
|
|
367
|
+
float accu = 0;
|
|
368
|
+
// implemented for all vector distances, although only L2 and IP are
|
|
369
|
+
// supported by FastScan
|
|
370
|
+
with_VectorDistance(pq.dsub, index.metric_type, 0.0, [&](auto vd) {
|
|
371
|
+
int m;
|
|
372
|
+
for (m = 0; m + 1 < pq.M; m += 2) {
|
|
373
|
+
const float* cent;
|
|
374
|
+
uint8_t c = *code++;
|
|
375
|
+
cent = pq.get_centroids(m, c & 15);
|
|
376
|
+
accu += vd(cent, x);
|
|
377
|
+
x += pq.dsub;
|
|
378
|
+
cent = pq.get_centroids(m + 1, c >> 4);
|
|
379
|
+
accu += vd(cent, x);
|
|
380
|
+
x += pq.dsub;
|
|
381
|
+
}
|
|
382
|
+
if (m < pq.M) { // leftover
|
|
383
|
+
uint8_t c = *code++;
|
|
384
|
+
const float* cent = pq.get_centroids(m, c & 15);
|
|
385
|
+
accu += vd(cent, x);
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
return accu;
|
|
341
389
|
}
|
|
342
390
|
|
|
343
391
|
// Based on IVFFastScan search_implem_10, since it also deals with 1 query
|
|
@@ -346,72 +394,86 @@ struct IVFPQFastScanScanner : InvertedListScanner {
|
|
|
346
394
|
size_t ntotal,
|
|
347
395
|
const uint8_t* codes,
|
|
348
396
|
const idx_t* ids,
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
size_t k
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
curr_labels.data(),
|
|
365
|
-
sel,
|
|
366
|
-
empty_context,
|
|
367
|
-
&normalizers[0]));
|
|
368
|
-
|
|
369
|
-
// This does not quite match search_implem_10, but it is fine because
|
|
370
|
-
// the scanner operates on a single query at a time, and this value is
|
|
371
|
-
// used as the query index. For a single query, the value is always 0.
|
|
372
|
-
int qmap1[1] = {0};
|
|
373
|
-
|
|
374
|
-
handler->q_map = qmap1;
|
|
375
|
-
handler->begin(&normalizers[0]);
|
|
376
|
-
|
|
377
|
-
const uint8_t* LUT = dis_tables.get();
|
|
378
|
-
handler->dbias = biases.get();
|
|
379
|
-
|
|
380
|
-
handler->ntotal = ntotal;
|
|
381
|
-
handler->id_map = ids;
|
|
382
|
-
|
|
383
|
-
pq4_accumulate_loop(
|
|
384
|
-
1,
|
|
385
|
-
roundup(ntotal, index.bbs),
|
|
386
|
-
index.bbs,
|
|
387
|
-
static_cast<int>(index.M2),
|
|
388
|
-
codes,
|
|
389
|
-
LUT,
|
|
390
|
-
*handler,
|
|
391
|
-
nullptr);
|
|
392
|
-
|
|
393
|
-
// The handler is for the results of this iteration.
|
|
394
|
-
// Then we need a second heap to combine across iterations.
|
|
395
|
-
handler->end();
|
|
396
|
-
if (keep_max) {
|
|
397
|
-
minheap_addn(
|
|
397
|
+
ResultHandler& handler) const override {
|
|
398
|
+
auto scan_with_heap = [&](auto* heap_handler) -> size_t {
|
|
399
|
+
const size_t k = heap_handler->k;
|
|
400
|
+
if (k == 0) {
|
|
401
|
+
return 0;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// initialize the current iteration heap to the worst possible value
|
|
405
|
+
// of the caller-owned result handler.
|
|
406
|
+
std::vector<float> curr_dists(k, handler.threshold);
|
|
407
|
+
std::vector<idx_t> curr_labels(k, -1);
|
|
408
|
+
|
|
409
|
+
auto scanner = index.make_knn_scanner(
|
|
410
|
+
!keep_max,
|
|
411
|
+
nq,
|
|
398
412
|
k,
|
|
399
|
-
distances,
|
|
400
|
-
labels,
|
|
401
413
|
curr_dists.data(),
|
|
402
414
|
curr_labels.data(),
|
|
403
|
-
|
|
415
|
+
sel);
|
|
416
|
+
|
|
417
|
+
SIMDResultHandlerToFloat* rh = scanner->handler();
|
|
418
|
+
|
|
419
|
+
// This does not quite match search_implem_10, but it is fine
|
|
420
|
+
// because the scanner operates on a single query at a time, and
|
|
421
|
+
// this value is used as the query index. For a single query, the
|
|
422
|
+
// value is always 0.
|
|
423
|
+
int qmap1[1] = {0};
|
|
424
|
+
|
|
425
|
+
rh->q_map = qmap1;
|
|
426
|
+
rh->begin(&normalizers[0]);
|
|
427
|
+
|
|
428
|
+
rh->dbias = biases.get();
|
|
429
|
+
rh->ntotal = ntotal;
|
|
430
|
+
rh->id_map = ids;
|
|
431
|
+
|
|
432
|
+
scanner->accumulate_loop(
|
|
433
|
+
1,
|
|
434
|
+
roundup(ntotal, index.bbs),
|
|
435
|
+
index.bbs,
|
|
436
|
+
static_cast<int>(index.M2),
|
|
437
|
+
codes,
|
|
438
|
+
dis_tables.get(),
|
|
439
|
+
0,
|
|
440
|
+
index.get_block_stride());
|
|
441
|
+
|
|
442
|
+
const size_t scan_cnt = rh->count_scanned_rows();
|
|
443
|
+
rh->end();
|
|
444
|
+
|
|
445
|
+
handler.stats.scan_cnt += scan_cnt;
|
|
446
|
+
size_t nup = 0;
|
|
447
|
+
for (size_t j = 0; j < k; j++) {
|
|
448
|
+
if (curr_labels[j] < 0) {
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
if (handler.add_result(curr_dists[j], curr_labels[j])) {
|
|
452
|
+
handler.stats.nheap_updates++;
|
|
453
|
+
nup++;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return nup;
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
if (!keep_max) {
|
|
460
|
+
using C = CMax<float, idx_t>;
|
|
461
|
+
if (auto* heap_handler =
|
|
462
|
+
dynamic_cast<HeapResultHandler<C, false>*>(&handler)) {
|
|
463
|
+
return scan_with_heap(heap_handler);
|
|
464
|
+
}
|
|
404
465
|
} else {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
curr_labels.data(),
|
|
411
|
-
k);
|
|
466
|
+
using C = CMin<float, idx_t>;
|
|
467
|
+
if (auto* heap_handler =
|
|
468
|
+
dynamic_cast<HeapResultHandler<C, false>*>(&handler)) {
|
|
469
|
+
return scan_with_heap(heap_handler);
|
|
470
|
+
}
|
|
412
471
|
}
|
|
413
472
|
|
|
414
|
-
|
|
473
|
+
FAISS_THROW_MSG(
|
|
474
|
+
"IVFPQFastScanScanner::scan_codes requires HeapResultHandler; "
|
|
475
|
+
"custom ResultHandler scan is not supported by this optimized "
|
|
476
|
+
"scanner");
|
|
415
477
|
}
|
|
416
478
|
};
|
|
417
479
|
|
|
@@ -55,6 +55,9 @@ struct IndexIVFPQFastScan : IndexIVFFastScan {
|
|
|
55
55
|
// built from an IndexIVFPQ
|
|
56
56
|
explicit IndexIVFPQFastScan(const IndexIVFPQ& orig, int bbs = 32);
|
|
57
57
|
|
|
58
|
+
/// Packed code size: M2 / 2 bytes (4-bit PQ sub-quantizer nibbles)
|
|
59
|
+
size_t fast_scan_code_size() const override;
|
|
60
|
+
|
|
58
61
|
void train_encoder(idx_t n, const float* x, const idx_t* assign) override;
|
|
59
62
|
|
|
60
63
|
idx_t train_encoder_num_vectors() const override;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
#include <cinttypes>
|
|
13
13
|
|
|
14
|
+
#include <faiss/impl/simd_dispatch.h>
|
|
14
15
|
#include <faiss/utils/Heap.h>
|
|
15
16
|
#include <faiss/utils/distances.h>
|
|
16
17
|
#include <faiss/utils/utils.h>
|
|
@@ -24,23 +25,23 @@ namespace faiss {
|
|
|
24
25
|
******************************************/
|
|
25
26
|
|
|
26
27
|
IndexIVFPQR::IndexIVFPQR(
|
|
27
|
-
Index*
|
|
28
|
-
size_t
|
|
29
|
-
size_t
|
|
28
|
+
Index* quantizer_in,
|
|
29
|
+
size_t d_in,
|
|
30
|
+
size_t nlist_in,
|
|
30
31
|
size_t M,
|
|
31
32
|
size_t nbits_per_idx,
|
|
32
33
|
size_t M_refine,
|
|
33
34
|
size_t nbits_per_idx_refine,
|
|
34
|
-
bool
|
|
35
|
+
bool own_invlists_in)
|
|
35
36
|
: IndexIVFPQ(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
quantizer_in,
|
|
38
|
+
d_in,
|
|
39
|
+
nlist_in,
|
|
39
40
|
M,
|
|
40
41
|
nbits_per_idx,
|
|
41
42
|
METRIC_L2,
|
|
42
|
-
|
|
43
|
-
refine_pq(
|
|
43
|
+
own_invlists_in),
|
|
44
|
+
refine_pq(d_in, M_refine, nbits_per_idx_refine),
|
|
44
45
|
k_factor(4) {
|
|
45
46
|
by_residual = true;
|
|
46
47
|
refine_pq.cp.max_points_per_centroid = 1000;
|
|
@@ -125,10 +126,10 @@ void IndexIVFPQR::search_preassigned(
|
|
|
125
126
|
idx_t* labels,
|
|
126
127
|
bool store_pairs,
|
|
127
128
|
const IVFSearchParameters* params,
|
|
128
|
-
IndexIVFStats* stats) const {
|
|
129
|
+
IndexIVFStats* /*stats*/) const {
|
|
129
130
|
uint64_t t0;
|
|
130
131
|
TIC;
|
|
131
|
-
size_t k_coarse = long(k * k_factor);
|
|
132
|
+
size_t k_coarse = long((size_t)k * k_factor);
|
|
132
133
|
std::unique_ptr<idx_t[]> coarse_labels(new idx_t[k_coarse * n]);
|
|
133
134
|
{
|
|
134
135
|
// query with quantizer levels 1 and 2.
|
|
@@ -165,18 +166,22 @@ void IndexIVFPQR::search_preassigned(
|
|
|
165
166
|
idx_t* heap_ids = labels + k * i;
|
|
166
167
|
maxheap_heapify(k, heap_sim, heap_ids);
|
|
167
168
|
|
|
168
|
-
for (
|
|
169
|
+
for (size_t j = 0; j < k_coarse; j++) {
|
|
169
170
|
idx_t sl = shortlist[j];
|
|
170
171
|
|
|
171
172
|
if (sl == -1) {
|
|
172
173
|
continue;
|
|
173
174
|
}
|
|
174
175
|
|
|
175
|
-
int list_no = lo_listno(sl);
|
|
176
|
-
int ofs = lo_offset(sl);
|
|
176
|
+
int list_no = static_cast<int>(lo_listno(sl));
|
|
177
|
+
int ofs = static_cast<int>(lo_offset(sl));
|
|
177
178
|
|
|
178
|
-
|
|
179
|
-
|
|
179
|
+
FAISS_THROW_IF_NOT(
|
|
180
|
+
list_no >= 0 && static_cast<size_t>(list_no) < nlist);
|
|
181
|
+
FAISS_THROW_IF_NOT(
|
|
182
|
+
ofs >= 0 &&
|
|
183
|
+
static_cast<size_t>(ofs) <
|
|
184
|
+
invlists->list_size(list_no));
|
|
180
185
|
|
|
181
186
|
// 1st level residual
|
|
182
187
|
quantizer->compute_residual(xq, residual_1.get(), list_no);
|
|
@@ -191,7 +196,7 @@ void IndexIVFPQR::search_preassigned(
|
|
|
191
196
|
|
|
192
197
|
// 3rd level residual's approximation
|
|
193
198
|
idx_t id = invlists->get_single_id(list_no, ofs);
|
|
194
|
-
|
|
199
|
+
FAISS_THROW_IF_NOT(0 <= id && id < ntotal);
|
|
195
200
|
refine_pq.decode(
|
|
196
201
|
&refine_codes[id * refine_pq.code_size],
|
|
197
202
|
residual_1.get());
|
|
@@ -218,7 +223,7 @@ void IndexIVFPQR::reconstruct_from_offset(
|
|
|
218
223
|
IndexIVFPQ::reconstruct_from_offset(list_no, offset, recons);
|
|
219
224
|
|
|
220
225
|
idx_t id = invlists->get_single_id(list_no, offset);
|
|
221
|
-
|
|
226
|
+
FAISS_THROW_IF_NOT(0 <= id && id < ntotal);
|
|
222
227
|
|
|
223
228
|
std::vector<float> r3(d);
|
|
224
229
|
refine_pq.decode(&refine_codes[id * refine_pq.code_size], r3.data());
|