faiss 0.6.0 → 0.6.2
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 +8 -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 +88 -97
- 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 +89 -417
- 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 +374 -206
- 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 +467 -364
- data/vendor/faiss/faiss/IndexIVF.h +33 -12
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +79 -76
- 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 +39 -69
- data/vendor/faiss/faiss/IndexIVFFlat.h +32 -0
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +56 -33
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +3 -1
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +18 -15
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +73 -846
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +151 -121
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +3 -0
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +23 -20
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +30 -52
- 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 +38 -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 +150 -20
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +10 -0
- 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/SaDecodeKernels.h +1 -1
- 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/Level2-neon-inl.h +902 -12
- 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/sa_decode/PQ-neon-inl.h +702 -10
- data/vendor/faiss/faiss/factory_tools.cpp +9 -0
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +6 -5
- data/vendor/faiss/faiss/gpu/GpuResources.h +3 -2
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +15 -16
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +5 -4
- 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/MetalDistance.h +87 -0
- data/vendor/faiss/faiss/gpu_metal/MetalFlatKernels.h +40 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +58 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexFlat.h +65 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +181 -0
- data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +111 -0
- data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +45 -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/gpu_metal/impl/MetalIVFFlat.h +193 -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 +639 -507
- data/vendor/faiss/faiss/impl/HNSW.h +61 -44
- 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 +53 -32
- 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 +269 -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 +55 -25
- 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 +302 -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 +100 -75
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +318 -7
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +77 -1
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +14 -11
- data/vendor/faiss/faiss/impl/VisitedTable.cpp +10 -10
- data/vendor/faiss/faiss/impl/VisitedTable.h +70 -28
- 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 +270 -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 +83 -0
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +113 -0
- data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +150 -0
- data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +142 -0
- data/vendor/faiss/faiss/impl/index_read.cpp +1227 -79
- data/vendor/faiss/faiss/impl/index_read_utils.h +1 -1
- data/vendor/faiss/faiss/impl/index_write.cpp +96 -13
- data/vendor/faiss/faiss/impl/io.cpp +6 -6
- data/vendor/faiss/faiss/impl/io_macros.h +58 -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 +15 -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 +23 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +23 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +23 -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 +45 -107
- 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 +274 -5
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +10 -7
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +105 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +70 -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 +9 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +419 -19
- 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 +387 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +553 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +559 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +341 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +425 -3
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +290 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +337 -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 +157 -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 +90 -18
- data/vendor/faiss/faiss/index_io.h +40 -0
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +66 -16
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +28 -15
- data/vendor/faiss/faiss/invlists/DirectMap.h +4 -3
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +170 -86
- data/vendor/faiss/faiss/invlists/InvertedLists.h +88 -25
- 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 +142 -21
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +33 -7
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +3 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +77 -27
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +10 -4
- 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/bf16.h +34 -0
- 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 -178
- 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 +16 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +15 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.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 +210 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_spr.h +171 -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 -989
- 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 +1031 -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_avx512_spr.cpp +343 -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 +29 -7
- 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 +129 -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
|
@@ -13,12 +13,15 @@
|
|
|
13
13
|
#include <cstdio>
|
|
14
14
|
#include <cstring>
|
|
15
15
|
#include <memory>
|
|
16
|
+
#include <type_traits>
|
|
16
17
|
|
|
17
18
|
#include <algorithm>
|
|
18
19
|
|
|
19
20
|
#include <faiss/IndexFlat.h>
|
|
20
21
|
#include <faiss/VectorTransform.h>
|
|
21
22
|
#include <faiss/impl/FaissAssert.h>
|
|
23
|
+
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
24
|
+
#include <faiss/impl/pq_code_distance/pq_code_distance-inl.h>
|
|
22
25
|
#include <faiss/impl/simd_dispatch.h>
|
|
23
26
|
#include <faiss/utils/distances.h>
|
|
24
27
|
|
|
@@ -48,8 +51,8 @@ namespace faiss {
|
|
|
48
51
|
* PQ implementation
|
|
49
52
|
*********************************************/
|
|
50
53
|
|
|
51
|
-
ProductQuantizer::ProductQuantizer(size_t
|
|
52
|
-
: Quantizer(
|
|
54
|
+
ProductQuantizer::ProductQuantizer(size_t d_in, size_t M_in, size_t nbits_in)
|
|
55
|
+
: Quantizer(d_in, 0), M(M_in), nbits(nbits_in), assign_index(nullptr) {
|
|
53
56
|
set_derived_values();
|
|
54
57
|
}
|
|
55
58
|
|
|
@@ -139,8 +142,8 @@ void ProductQuantizer::train(size_t n, const float* x) {
|
|
|
139
142
|
}
|
|
140
143
|
|
|
141
144
|
std::unique_ptr<float[]> xslice(new float[n * dsub]);
|
|
142
|
-
for (
|
|
143
|
-
for (
|
|
145
|
+
for (size_t m = 0; m < M; m++) {
|
|
146
|
+
for (size_t j = 0; j < n; j++)
|
|
144
147
|
memcpy(xslice.get() + j * dsub,
|
|
145
148
|
x + j * d + m * dsub,
|
|
146
149
|
dsub * sizeof(float));
|
|
@@ -179,7 +182,7 @@ void ProductQuantizer::train(size_t n, const float* x) {
|
|
|
179
182
|
|
|
180
183
|
if (verbose) {
|
|
181
184
|
clus.verbose = true;
|
|
182
|
-
printf("Training PQ slice %
|
|
185
|
+
printf("Training PQ slice %zd/%zd\n", m, M);
|
|
183
186
|
}
|
|
184
187
|
IndexFlatL2 index(dsub);
|
|
185
188
|
clus.train(n, xslice.get(), assign_index ? *assign_index : index);
|
|
@@ -197,7 +200,7 @@ void ProductQuantizer::train(size_t n, const float* x) {
|
|
|
197
200
|
IndexFlatL2 index(dsub);
|
|
198
201
|
|
|
199
202
|
clus.train(n * M, x, assign_index ? *assign_index : index);
|
|
200
|
-
for (
|
|
203
|
+
for (size_t m = 0; m < M; m++) {
|
|
201
204
|
set_params(clus.centroids.data(), m);
|
|
202
205
|
}
|
|
203
206
|
}
|
|
@@ -322,8 +325,9 @@ void ProductQuantizer::decode(const uint8_t* code, float* x) const {
|
|
|
322
325
|
}
|
|
323
326
|
|
|
324
327
|
void ProductQuantizer::decode(const uint8_t* code, float* x, size_t n) const {
|
|
328
|
+
int64_t n_signed = n;
|
|
325
329
|
#pragma omp parallel for if (n > 100)
|
|
326
|
-
for (int64_t i = 0; i <
|
|
330
|
+
for (int64_t i = 0; i < n_signed; i++) {
|
|
327
331
|
this->decode(code + code_size * i, x + d * i);
|
|
328
332
|
}
|
|
329
333
|
}
|
|
@@ -353,7 +357,8 @@ void ProductQuantizer::compute_codes_with_assign_index(
|
|
|
353
357
|
const float* x,
|
|
354
358
|
uint8_t* codes,
|
|
355
359
|
size_t n) {
|
|
356
|
-
FAISS_THROW_IF_NOT(
|
|
360
|
+
FAISS_THROW_IF_NOT(
|
|
361
|
+
assign_index && static_cast<size_t>(assign_index->d) == dsub);
|
|
357
362
|
|
|
358
363
|
for (size_t m = 0; m < M; m++) {
|
|
359
364
|
assign_index->reset();
|
|
@@ -415,10 +420,11 @@ void ProductQuantizer::compute_codes(const float* x, uint8_t* codes, size_t n)
|
|
|
415
420
|
return;
|
|
416
421
|
}
|
|
417
422
|
|
|
423
|
+
int64_t n_signed = n;
|
|
418
424
|
if (dsub < 16) { // simple direct computation
|
|
419
425
|
|
|
420
426
|
#pragma omp parallel for
|
|
421
|
-
for (int64_t i = 0; i <
|
|
427
|
+
for (int64_t i = 0; i < n_signed; i++)
|
|
422
428
|
compute_code(x + i * d, codes + i * code_size);
|
|
423
429
|
|
|
424
430
|
} else { // worthwhile to use BLAS
|
|
@@ -426,7 +432,7 @@ void ProductQuantizer::compute_codes(const float* x, uint8_t* codes, size_t n)
|
|
|
426
432
|
compute_distance_tables(n, x, dis_tables.get());
|
|
427
433
|
|
|
428
434
|
#pragma omp parallel for
|
|
429
|
-
for (int64_t i = 0; i <
|
|
435
|
+
for (int64_t i = 0; i < n_signed; i++) {
|
|
430
436
|
uint8_t* code = codes + i * code_size;
|
|
431
437
|
const float* tab = dis_tables.get() + i * ksub * M;
|
|
432
438
|
compute_code_from_distance_table(tab, code);
|
|
@@ -482,7 +488,8 @@ void ProductQuantizer::compute_distance_tables(
|
|
|
482
488
|
size_t nx,
|
|
483
489
|
const float* x,
|
|
484
490
|
float* dis_tables) const {
|
|
485
|
-
|
|
491
|
+
int64_t nx_signed = nx;
|
|
492
|
+
#if defined(COMPILE_SIMD_AVX2) || defined(COMPILE_SIMD_ARM_NEON)
|
|
486
493
|
if (dsub == 2 && nbits < 8) { // interesting for a narrow range of settings
|
|
487
494
|
compute_PQ_dis_tables_dsub2(
|
|
488
495
|
d, ksub, centroids.data(), nx, x, false, dis_tables);
|
|
@@ -491,13 +498,13 @@ void ProductQuantizer::compute_distance_tables(
|
|
|
491
498
|
if (dsub < 16) {
|
|
492
499
|
|
|
493
500
|
#pragma omp parallel for if (nx > 1)
|
|
494
|
-
for (int64_t i = 0; i <
|
|
501
|
+
for (int64_t i = 0; i < nx_signed; i++) {
|
|
495
502
|
compute_distance_table(x + i * d, dis_tables + i * ksub * M);
|
|
496
503
|
}
|
|
497
504
|
|
|
498
505
|
} else { // use BLAS
|
|
499
506
|
|
|
500
|
-
for (
|
|
507
|
+
for (size_t m = 0; m < M; m++) {
|
|
501
508
|
pairwise_L2sqr(
|
|
502
509
|
dsub,
|
|
503
510
|
nx,
|
|
@@ -516,7 +523,8 @@ void ProductQuantizer::compute_inner_prod_tables(
|
|
|
516
523
|
size_t nx,
|
|
517
524
|
const float* x,
|
|
518
525
|
float* dis_tables) const {
|
|
519
|
-
|
|
526
|
+
int64_t nx_signed = nx;
|
|
527
|
+
#if defined(COMPILE_SIMD_AVX2) || defined(COMPILE_SIMD_ARM_NEON)
|
|
520
528
|
if (dsub == 2 && nbits < 8) {
|
|
521
529
|
compute_PQ_dis_tables_dsub2(
|
|
522
530
|
d, ksub, centroids.data(), nx, x, true, dis_tables);
|
|
@@ -525,14 +533,14 @@ void ProductQuantizer::compute_inner_prod_tables(
|
|
|
525
533
|
if (dsub < 16) {
|
|
526
534
|
|
|
527
535
|
#pragma omp parallel for if (nx > 1)
|
|
528
|
-
for (int64_t i = 0; i <
|
|
536
|
+
for (int64_t i = 0; i < nx_signed; i++) {
|
|
529
537
|
compute_inner_prod_table(x + i * d, dis_tables + i * ksub * M);
|
|
530
538
|
}
|
|
531
539
|
|
|
532
540
|
} else { // use BLAS
|
|
533
541
|
|
|
534
542
|
// compute distance tables
|
|
535
|
-
for (
|
|
543
|
+
for (size_t m = 0; m < M; m++) {
|
|
536
544
|
FINTEGER ldc = ksub * M, nxi = nx, ksubi = ksub, dsubi = dsub,
|
|
537
545
|
di = d;
|
|
538
546
|
float one = 1.0, zero = 0;
|
|
@@ -576,7 +584,7 @@ void pq_estimators_from_tables_Mmul4(
|
|
|
576
584
|
float dis = 0;
|
|
577
585
|
const float* dt = dis_table;
|
|
578
586
|
|
|
579
|
-
for (
|
|
587
|
+
for (int m = 0; m < M; m += 4) {
|
|
580
588
|
float dism = 0;
|
|
581
589
|
dism = dt[*codes++];
|
|
582
590
|
dt += ksub;
|
|
@@ -648,7 +656,7 @@ void pq_estimators_from_tables(
|
|
|
648
656
|
for (size_t j = 0; j < ncodes; j++) {
|
|
649
657
|
float dis = 0;
|
|
650
658
|
const float* __restrict dt = dis_table;
|
|
651
|
-
for (
|
|
659
|
+
for (size_t m = 0; m < M; m++) {
|
|
652
660
|
dis += dt[*codes++];
|
|
653
661
|
dt += ksub;
|
|
654
662
|
}
|
|
@@ -696,10 +704,11 @@ void pq_knn_search_with_tables(
|
|
|
696
704
|
HeapArray<C>* res,
|
|
697
705
|
bool init_finalize_heap) {
|
|
698
706
|
size_t k = res->k, nx = res->nh;
|
|
707
|
+
int64_t nx_signed = nx;
|
|
699
708
|
size_t ksub = pq.ksub, M = pq.M;
|
|
700
709
|
|
|
701
710
|
#pragma omp parallel for if (nx > 1)
|
|
702
|
-
for (int64_t i = 0; i <
|
|
711
|
+
for (int64_t i = 0; i < nx_signed; i++) {
|
|
703
712
|
/* query preparation for asymmetric search: compute look-up tables */
|
|
704
713
|
const float* dis_table = dis_tables + i * ksub * M;
|
|
705
714
|
|
|
@@ -713,8 +722,28 @@ void pq_knn_search_with_tables(
|
|
|
713
722
|
|
|
714
723
|
switch (nbits) {
|
|
715
724
|
case 8:
|
|
716
|
-
|
|
717
|
-
|
|
725
|
+
if (ksub == 256) {
|
|
726
|
+
constexpr bool max_heap =
|
|
727
|
+
std::is_same_v<C, CMax<float, int64_t>>;
|
|
728
|
+
pq_code_distance::pq_scan_8bit(
|
|
729
|
+
M,
|
|
730
|
+
dis_table,
|
|
731
|
+
codes,
|
|
732
|
+
ncodes,
|
|
733
|
+
k,
|
|
734
|
+
heap_dis,
|
|
735
|
+
heap_ids,
|
|
736
|
+
max_heap);
|
|
737
|
+
} else {
|
|
738
|
+
pq_estimators_from_tables<uint8_t, C>(
|
|
739
|
+
pq,
|
|
740
|
+
codes,
|
|
741
|
+
ncodes,
|
|
742
|
+
dis_table,
|
|
743
|
+
k,
|
|
744
|
+
heap_dis,
|
|
745
|
+
heap_ids);
|
|
746
|
+
}
|
|
718
747
|
break;
|
|
719
748
|
|
|
720
749
|
case 16:
|
|
@@ -797,7 +826,7 @@ void ProductQuantizer::compute_sdc_table() {
|
|
|
797
826
|
if (dsub < 4) {
|
|
798
827
|
with_simd_level([&]<SIMDLevel SL>() {
|
|
799
828
|
#pragma omp parallel for
|
|
800
|
-
for (
|
|
829
|
+
for (int64_t mk = 0; mk < static_cast<int64_t>(M * ksub); mk++) {
|
|
801
830
|
// allow omp to schedule in a more fine-grained way
|
|
802
831
|
// `collapse` is not supported in OpenMP 2.x
|
|
803
832
|
int m = mk / ksub;
|
|
@@ -812,7 +841,7 @@ void ProductQuantizer::compute_sdc_table() {
|
|
|
812
841
|
// NOTE: it would disable the omp loop in pairwise_L2sqr
|
|
813
842
|
// but still accelerate especially when M >= 4
|
|
814
843
|
#pragma omp parallel for
|
|
815
|
-
for (
|
|
844
|
+
for (int64_t m = 0; m < static_cast<int64_t>(M); m++) {
|
|
816
845
|
const float* cents = centroids.data() + m * ksub * dsub;
|
|
817
846
|
float* dis_tab = sdc_table.data() + m * ksub * ksub;
|
|
818
847
|
pairwise_L2sqr(
|
|
@@ -831,9 +860,10 @@ void ProductQuantizer::search_sdc(
|
|
|
831
860
|
FAISS_THROW_IF_NOT(sdc_table.size() == M * ksub * ksub);
|
|
832
861
|
FAISS_THROW_IF_NOT(nbits == 8);
|
|
833
862
|
size_t k = res->k;
|
|
863
|
+
int64_t nq_signed = nq;
|
|
834
864
|
|
|
835
865
|
#pragma omp parallel for
|
|
836
|
-
for (int64_t i = 0; i <
|
|
866
|
+
for (int64_t i = 0; i < nq_signed; i++) {
|
|
837
867
|
/* Compute distances and keep smallest values */
|
|
838
868
|
idx_t* heap_ids = res->ids + i * k;
|
|
839
869
|
float* heap_dis = res->val + i * k;
|
|
@@ -846,7 +876,7 @@ void ProductQuantizer::search_sdc(
|
|
|
846
876
|
for (size_t j = 0; j < nb; j++) {
|
|
847
877
|
float dis = 0;
|
|
848
878
|
const float* tab = sdc_table.data();
|
|
849
|
-
for (
|
|
879
|
+
for (size_t m = 0; m < M; m++) {
|
|
850
880
|
dis += tab[bcode[m] + qcode[m] * ksub];
|
|
851
881
|
tab += ksub * ksub;
|
|
852
882
|
}
|
|
@@ -16,8 +16,8 @@ struct Quantizer {
|
|
|
16
16
|
size_t d; ///< size of the input vectors
|
|
17
17
|
size_t code_size; ///< bytes per indexed vector
|
|
18
18
|
|
|
19
|
-
explicit Quantizer(size_t
|
|
20
|
-
: d(
|
|
19
|
+
explicit Quantizer(size_t d_in = 0, size_t code_size_in = 0)
|
|
20
|
+
: d(d_in), code_size(code_size_in) {}
|
|
21
21
|
|
|
22
22
|
/** Train the quantizer
|
|
23
23
|
*
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#include <faiss/impl/RaBitQUtils.h>
|
|
9
9
|
|
|
10
10
|
#include <faiss/impl/FaissAssert.h>
|
|
11
|
+
#include <faiss/impl/simd_dispatch.h>
|
|
11
12
|
#include <faiss/utils/distances.h>
|
|
12
13
|
#include <faiss/utils/rabitq_simd.h>
|
|
13
14
|
#include <algorithm>
|
|
@@ -153,6 +154,7 @@ QueryFactorsData compute_query_factors(
|
|
|
153
154
|
std::vector<uint8_t>& rotated_qq) {
|
|
154
155
|
FAISS_THROW_IF_NOT(qb <= 8);
|
|
155
156
|
FAISS_THROW_IF_NOT(qb > 0);
|
|
157
|
+
FAISS_THROW_IF_NOT(d > 0);
|
|
156
158
|
|
|
157
159
|
QueryFactorsData query_factors;
|
|
158
160
|
|
|
@@ -165,38 +167,42 @@ QueryFactorsData compute_query_factors(
|
|
|
165
167
|
query_factors.g_error = std::sqrt(query_factors.qr_to_c_L2sqr);
|
|
166
168
|
|
|
167
169
|
// Rotate the query (subtract centroid)
|
|
170
|
+
// Save aliasing state before resize(), which may reallocate the buffer.
|
|
171
|
+
const bool query_aliased = (query == rotated_q.data());
|
|
172
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
173
|
+
!query_aliased || centroid == nullptr,
|
|
174
|
+
"query aliasing is only supported in the IVF residual path "
|
|
175
|
+
"(centroid == nullptr)");
|
|
168
176
|
rotated_q.resize(d);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
177
|
+
if (centroid == nullptr) {
|
|
178
|
+
// Caller may pass query == rotated_q.data() (IVF residual path);
|
|
179
|
+
// memcpy with overlapping src/dst is UB, so skip the copy in that case.
|
|
180
|
+
if (!query_aliased) {
|
|
181
|
+
memcpy(rotated_q.data(), query, d * sizeof(float));
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
for (size_t i = 0; i < d; i++) {
|
|
185
|
+
rotated_q[i] = query[i] - centroid[i];
|
|
173
186
|
}
|
|
174
187
|
}
|
|
175
188
|
|
|
176
|
-
const float inv_d_sqrt =
|
|
177
|
-
(d == 0) ? 1.0f : (1.0f / std::sqrt(static_cast<float>(d)));
|
|
189
|
+
const float inv_d_sqrt = 1.0f / std::sqrt(static_cast<float>(d));
|
|
178
190
|
|
|
179
191
|
// Compute quantization range
|
|
180
192
|
float v_min = std::numeric_limits<float>::max();
|
|
181
193
|
float v_max = std::numeric_limits<float>::lowest();
|
|
182
194
|
|
|
195
|
+
const float* rq = rotated_q.data();
|
|
183
196
|
if (centered) {
|
|
184
197
|
float z_max = Z_MAX_BY_QB[qb - 1];
|
|
185
198
|
float v_radius = z_max * std::sqrt(query_factors.qr_to_c_L2sqr / d);
|
|
186
199
|
v_min = -v_radius;
|
|
187
200
|
v_max = v_radius;
|
|
188
201
|
} else {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
v_min = std::min(v_min, v_q);
|
|
194
|
-
v_max = std::max(v_max, v_q);
|
|
195
|
-
}
|
|
196
|
-
} else {
|
|
197
|
-
// For empty dimensions, use default range
|
|
198
|
-
v_min = 0.0f;
|
|
199
|
-
v_max = 1.0f;
|
|
202
|
+
for (size_t i = 0; i < d; i++) {
|
|
203
|
+
const float v_q = rq[i];
|
|
204
|
+
v_min = std::min(v_min, v_q);
|
|
205
|
+
v_max = std::max(v_max, v_q);
|
|
200
206
|
}
|
|
201
207
|
}
|
|
202
208
|
|
|
@@ -209,25 +215,18 @@ QueryFactorsData compute_query_factors(
|
|
|
209
215
|
size_t sum_qq = 0;
|
|
210
216
|
int64_t sum2_signed_odd_int = 0;
|
|
211
217
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
int64_t signed_odd_int = int64_t(v_qq) * 2 - max_code;
|
|
224
|
-
sum2_signed_odd_int += signed_odd_int * signed_odd_int;
|
|
225
|
-
}
|
|
218
|
+
uint8_t* rqq = rotated_qq.data();
|
|
219
|
+
for (size_t i = 0; i < d; i++) {
|
|
220
|
+
const float v_q = rq[i];
|
|
221
|
+
const uint8_t v_qq = std::clamp<float>(
|
|
222
|
+
std::round((v_q - v_min) * inv_delta), 0, max_code);
|
|
223
|
+
rqq[i] = v_qq;
|
|
224
|
+
sum_qq += v_qq;
|
|
225
|
+
|
|
226
|
+
if (centered) {
|
|
227
|
+
int64_t signed_odd_int = int64_t(v_qq) * 2 - max_code;
|
|
228
|
+
sum2_signed_odd_int += signed_odd_int * signed_odd_int;
|
|
226
229
|
}
|
|
227
|
-
} else {
|
|
228
|
-
FAISS_THROW_MSG(
|
|
229
|
-
"Arrays unexpectedly empty when d=" + std::to_string(d) +
|
|
230
|
-
"or d is incorrectly set");
|
|
231
230
|
}
|
|
232
231
|
|
|
233
232
|
// Compute query factors
|
|
@@ -242,11 +241,15 @@ QueryFactorsData compute_query_factors(
|
|
|
242
241
|
query_factors.int_dot_scale = 1.0f;
|
|
243
242
|
}
|
|
244
243
|
|
|
245
|
-
// Compute query norm for inner product metric
|
|
244
|
+
// Compute query norm for inner product metric.
|
|
245
|
+
// When centroid is nullptr (IVF residual path), qr_to_c_L2sqr already
|
|
246
|
+
// holds fvec_norm_L2sqr(query, d) from line 164, so reuse it.
|
|
246
247
|
query_factors.qr_norm_L2sqr = 0.0f;
|
|
247
248
|
query_factors.q_dot_c = 0.0f;
|
|
248
249
|
if (metric_type == MetricType::METRIC_INNER_PRODUCT) {
|
|
249
|
-
query_factors.qr_norm_L2sqr =
|
|
250
|
+
query_factors.qr_norm_L2sqr = (centroid == nullptr)
|
|
251
|
+
? query_factors.qr_to_c_L2sqr
|
|
252
|
+
: fvec_norm_L2sqr(query, d);
|
|
250
253
|
if (centroid != nullptr) {
|
|
251
254
|
query_factors.q_dot_c = fvec_inner_product(query, centroid, d);
|
|
252
255
|
}
|
|
@@ -306,6 +309,9 @@ size_t compute_per_vector_storage_size(size_t nb_bits, size_t d) {
|
|
|
306
309
|
}
|
|
307
310
|
}
|
|
308
311
|
|
|
312
|
+
// Non-template wrapper with dynamic dispatch (one dispatch per call).
|
|
313
|
+
// The hot path in RaBitQuantizer dispatches once at distance computer
|
|
314
|
+
// construction, so per-vector dispatch only affects this utility path.
|
|
309
315
|
float compute_full_multibit_distance(
|
|
310
316
|
const uint8_t* sign_bits,
|
|
311
317
|
const uint8_t* ex_code,
|
|
@@ -315,18 +321,18 @@ float compute_full_multibit_distance(
|
|
|
315
321
|
size_t d,
|
|
316
322
|
size_t ex_bits,
|
|
317
323
|
MetricType metric_type) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
324
|
+
return with_selected_simd_levels<AVAILABLE_SIMD_LEVELS_A0_SPR>(
|
|
325
|
+
[&]<SIMDLevel SL>() {
|
|
326
|
+
return compute_full_multibit_distance<SL>(
|
|
327
|
+
sign_bits,
|
|
328
|
+
ex_code,
|
|
329
|
+
ex_fac,
|
|
330
|
+
rotated_q,
|
|
331
|
+
qr_base,
|
|
332
|
+
d,
|
|
333
|
+
ex_bits,
|
|
334
|
+
metric_type);
|
|
335
|
+
});
|
|
330
336
|
}
|
|
331
337
|
|
|
332
338
|
void populate_block_aux_from_flat_storage(
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
#include <faiss/MetricType.h>
|
|
11
11
|
#include <faiss/impl/platform_macros.h>
|
|
12
12
|
#include <faiss/utils/AlignedTable.h>
|
|
13
|
+
#include <faiss/utils/rabitq_simd.h>
|
|
14
|
+
#include <faiss/utils/simd_levels.h>
|
|
15
|
+
#include <algorithm>
|
|
13
16
|
#include <cstddef>
|
|
14
17
|
#include <cstdint>
|
|
15
18
|
#include <cstring>
|
|
@@ -337,6 +340,33 @@ float compute_full_multibit_distance(
|
|
|
337
340
|
size_t ex_bits,
|
|
338
341
|
MetricType metric_type);
|
|
339
342
|
|
|
343
|
+
// SIMDLevel-templatized version — avoids per-call dynamic dispatch.
|
|
344
|
+
// Inline so it can be used from templatized distance computers without
|
|
345
|
+
// needing explicit instantiations in per-SIMD TUs.
|
|
346
|
+
template <SIMDLevel SL>
|
|
347
|
+
inline float compute_full_multibit_distance(
|
|
348
|
+
const uint8_t* sign_bits,
|
|
349
|
+
const uint8_t* ex_code,
|
|
350
|
+
const ExtraBitsFactors& ex_fac,
|
|
351
|
+
const float* rotated_q,
|
|
352
|
+
float qr_base,
|
|
353
|
+
size_t d,
|
|
354
|
+
size_t ex_bits,
|
|
355
|
+
MetricType metric_type) {
|
|
356
|
+
const float cb = -(static_cast<float>(1 << ex_bits) - 0.5f);
|
|
357
|
+
|
|
358
|
+
float ex_ip = rabitq::multibit::compute_inner_product<SL>(
|
|
359
|
+
sign_bits, ex_code, rotated_q, d, ex_bits, cb);
|
|
360
|
+
|
|
361
|
+
float dist = qr_base + ex_fac.f_add_ex + ex_fac.f_rescale_ex * ex_ip;
|
|
362
|
+
|
|
363
|
+
if (metric_type == MetricType::METRIC_L2) {
|
|
364
|
+
dist = std::max(0.0f, dist);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return dist;
|
|
368
|
+
}
|
|
369
|
+
|
|
340
370
|
/** Compute pointer to a vector's auxiliary data within block layout. */
|
|
341
371
|
template <typename T>
|
|
342
372
|
inline T* get_block_aux_ptr(
|
|
@@ -350,6 +380,41 @@ inline T* get_block_aux_ptr(
|
|
|
350
380
|
(vec_pos % bbs) * storage_size;
|
|
351
381
|
}
|
|
352
382
|
|
|
383
|
+
/// Extract sign bits from PQ4-interleaved block into flat byte packing.
|
|
384
|
+
/// Like CodePackerRaBitQ::unpack_1 but sign-bits-only and with the
|
|
385
|
+
/// vector's in-block address hoisted out of the per-SQ loop.
|
|
386
|
+
inline void unpack_sign_bits_from_packed(
|
|
387
|
+
const uint8_t* block,
|
|
388
|
+
size_t bbs,
|
|
389
|
+
size_t nsq,
|
|
390
|
+
size_t offset,
|
|
391
|
+
size_t block_stride,
|
|
392
|
+
uint8_t* sign_bits_out) {
|
|
393
|
+
block += (offset / bbs) * block_stride;
|
|
394
|
+
offset = offset % bbs;
|
|
395
|
+
|
|
396
|
+
const bool nibble_high = offset > 15;
|
|
397
|
+
const size_t vid = offset & 15;
|
|
398
|
+
const size_t in_group_addr =
|
|
399
|
+
(vid < 8) ? (vid << 1) : (((vid - 8) << 1) + 1);
|
|
400
|
+
|
|
401
|
+
const size_t num_pairs = nsq / 2;
|
|
402
|
+
for (size_t k = 0; k < num_pairs; k++) {
|
|
403
|
+
const size_t base = k * bbs;
|
|
404
|
+
const uint8_t raw_even = block[base + in_group_addr];
|
|
405
|
+
const uint8_t raw_odd = block[base + in_group_addr + 16];
|
|
406
|
+
|
|
407
|
+
const uint8_t nib0 = nibble_high ? (raw_even >> 4) : (raw_even & 0xF);
|
|
408
|
+
const uint8_t nib1 = nibble_high ? (raw_odd >> 4) : (raw_odd & 0xF);
|
|
409
|
+
sign_bits_out[k] = nib0 | (nib1 << 4);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (nsq & 1) {
|
|
413
|
+
const uint8_t raw = block[num_pairs * bbs + in_group_addr];
|
|
414
|
+
sign_bits_out[num_pairs] = nibble_high ? (raw >> 4) : (raw & 0xF);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
353
418
|
/** Compute per-vector auxiliary storage size.
|
|
354
419
|
*
|
|
355
420
|
* @param nb_bits number of quantization bits (1 = sign-bit only)
|