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
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
#ifdef COMPILE_SIMD_AVX2
|
|
9
9
|
|
|
10
|
+
#include <faiss/impl/simdlib/simdlib_avx2.h>
|
|
11
|
+
|
|
12
|
+
#include <cstring>
|
|
13
|
+
|
|
10
14
|
#include <faiss/impl/scalar_quantizer/codecs.h>
|
|
11
15
|
#include <faiss/impl/scalar_quantizer/distance_computers.h>
|
|
12
16
|
#include <faiss/impl/scalar_quantizer/quantizers.h>
|
|
@@ -17,6 +21,63 @@ namespace faiss {
|
|
|
17
21
|
|
|
18
22
|
namespace scalar_quantizer {
|
|
19
23
|
|
|
24
|
+
using simd8float32 = faiss::simd8float32_tpl<SIMDLevel::AVX2>;
|
|
25
|
+
|
|
26
|
+
namespace {
|
|
27
|
+
|
|
28
|
+
FAISS_ALWAYS_INLINE uint16_t load_u16(const uint8_t* ptr) {
|
|
29
|
+
uint16_t value;
|
|
30
|
+
std::memcpy(&value, ptr, sizeof(value));
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
FAISS_ALWAYS_INLINE uint32_t load_u32(const uint8_t* ptr) {
|
|
35
|
+
uint32_t value;
|
|
36
|
+
std::memcpy(&value, ptr, sizeof(value));
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
FAISS_ALWAYS_INLINE uint32_t load_u24(const uint8_t* ptr) {
|
|
41
|
+
return static_cast<uint32_t>(ptr[0]) |
|
|
42
|
+
(static_cast<uint32_t>(ptr[1]) << 8) |
|
|
43
|
+
(static_cast<uint32_t>(ptr[2]) << 16);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
FAISS_ALWAYS_INLINE __m256i unpack_8x1bit_to_u32(const uint8_t* code, int i) {
|
|
47
|
+
const uint32_t packed = code[static_cast<size_t>(i) >> 3];
|
|
48
|
+
const __m256i shifts = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
|
|
49
|
+
const __m256i indices =
|
|
50
|
+
_mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
|
|
51
|
+
return _mm256_and_si256(indices, _mm256_set1_epi32(0x1));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
FAISS_ALWAYS_INLINE __m256i unpack_8x2bit_to_u32(const uint8_t* code, int i) {
|
|
55
|
+
const uint32_t packed = load_u16(code + (static_cast<size_t>(i) >> 2));
|
|
56
|
+
const __m256i shifts = _mm256_setr_epi32(0, 2, 4, 6, 8, 10, 12, 14);
|
|
57
|
+
const __m256i indices =
|
|
58
|
+
_mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
|
|
59
|
+
return _mm256_and_si256(indices, _mm256_set1_epi32(0x3));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
FAISS_ALWAYS_INLINE __m256i unpack_8x3bit_to_u32(const uint8_t* code, int i) {
|
|
63
|
+
const uint32_t packed =
|
|
64
|
+
load_u24(code + ((static_cast<size_t>(i) >> 3) * 3));
|
|
65
|
+
const __m256i shifts = _mm256_setr_epi32(0, 3, 6, 9, 12, 15, 18, 21);
|
|
66
|
+
const __m256i indices =
|
|
67
|
+
_mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
|
|
68
|
+
return _mm256_and_si256(indices, _mm256_set1_epi32(0x7));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
FAISS_ALWAYS_INLINE __m256i unpack_8x4bit_to_u32(const uint8_t* code, int i) {
|
|
72
|
+
const uint32_t packed = load_u32(code + (static_cast<size_t>(i) >> 1));
|
|
73
|
+
const __m256i shifts = _mm256_setr_epi32(0, 4, 8, 12, 16, 20, 24, 28);
|
|
74
|
+
const __m256i indices =
|
|
75
|
+
_mm256_srlv_epi32(_mm256_set1_epi32(packed), shifts);
|
|
76
|
+
return _mm256_and_si256(indices, _mm256_set1_epi32(0xf));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
} // namespace
|
|
80
|
+
|
|
20
81
|
/**********************************************************
|
|
21
82
|
* Codecs
|
|
22
83
|
**********************************************************/
|
|
@@ -135,6 +196,12 @@ struct QuantizerTemplate<
|
|
|
135
196
|
return simd8float32(_mm256_fmadd_ps(
|
|
136
197
|
xi, _mm256_set1_ps(this->vdiff), _mm256_set1_ps(this->vmin)));
|
|
137
198
|
}
|
|
199
|
+
|
|
200
|
+
/// Raw codec decode without denormalization
|
|
201
|
+
FAISS_ALWAYS_INLINE simd8float32
|
|
202
|
+
decode_8_raw(const uint8_t* code, int i) const {
|
|
203
|
+
return Codec::decode_8_components(code, i);
|
|
204
|
+
}
|
|
138
205
|
};
|
|
139
206
|
|
|
140
207
|
template <class Codec>
|
|
@@ -164,6 +231,171 @@ struct QuantizerTemplate<
|
|
|
164
231
|
}
|
|
165
232
|
};
|
|
166
233
|
|
|
234
|
+
/**********************************************************
|
|
235
|
+
* TurboQuant MSE quantizer
|
|
236
|
+
**********************************************************/
|
|
237
|
+
|
|
238
|
+
// 1-bit MSE: boundary is always at centroids midpoint.
|
|
239
|
+
// Encode: 8 comparisons → 1 byte via movemask.
|
|
240
|
+
// Decode: gather 8 centroids via index unpack.
|
|
241
|
+
// NOLINTNEXTLINE(facebook-hte-MisplacedTemplateSpecialization,facebook-hte-ShadowingClass)
|
|
242
|
+
template <>
|
|
243
|
+
struct QuantizerTurboQuantMSE<1, SIMDLevel::AVX2>
|
|
244
|
+
: QuantizerTurboQuantMSE<1, SIMDLevel::NONE> {
|
|
245
|
+
using Base = QuantizerTurboQuantMSE<1, SIMDLevel::NONE>;
|
|
246
|
+
|
|
247
|
+
QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained)
|
|
248
|
+
: Base(d, trained) {
|
|
249
|
+
assert(d % 8 == 0);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
FAISS_ALWAYS_INLINE simd8float32
|
|
253
|
+
reconstruct_8_components(const uint8_t* code, int i) const {
|
|
254
|
+
return simd8float32(_mm256_i32gather_ps(
|
|
255
|
+
this->centroids, unpack_8x1bit_to_u32(code, i), sizeof(float)));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
void encode_vector(const float* x, uint8_t* code) const final {
|
|
259
|
+
__m256 boundary = _mm256_set1_ps(this->boundaries[0]);
|
|
260
|
+
for (size_t i = 0; i < this->d; i += 8) {
|
|
261
|
+
__m256 vals = _mm256_loadu_ps(x + i);
|
|
262
|
+
int mask = _mm256_movemask_ps(
|
|
263
|
+
_mm256_cmp_ps(vals, boundary, _CMP_GT_OQ));
|
|
264
|
+
code[i / 8] = static_cast<uint8_t>(mask);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
void decode_vector(const uint8_t* code, float* x) const final {
|
|
269
|
+
for (size_t i = 0; i < this->d; i += 8) {
|
|
270
|
+
simd8float32 xi =
|
|
271
|
+
reconstruct_8_components(code, static_cast<int>(i));
|
|
272
|
+
_mm256_storeu_ps(x + i, xi.f);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// 2-bit MSE: 4 centroids, 3 boundaries.
|
|
278
|
+
// Encode: branchless index = sum of 3 comparisons per component.
|
|
279
|
+
// Decode: gather via index unpack.
|
|
280
|
+
// NOLINTNEXTLINE(facebook-hte-MisplacedTemplateSpecialization,facebook-hte-ShadowingClass)
|
|
281
|
+
template <>
|
|
282
|
+
struct QuantizerTurboQuantMSE<2, SIMDLevel::AVX2>
|
|
283
|
+
: QuantizerTurboQuantMSE<2, SIMDLevel::NONE> {
|
|
284
|
+
using Base = QuantizerTurboQuantMSE<2, SIMDLevel::NONE>;
|
|
285
|
+
|
|
286
|
+
QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained)
|
|
287
|
+
: Base(d, trained) {
|
|
288
|
+
assert(d % 8 == 0);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
FAISS_ALWAYS_INLINE simd8float32
|
|
292
|
+
reconstruct_8_components(const uint8_t* code, int i) const {
|
|
293
|
+
return simd8float32(_mm256_i32gather_ps(
|
|
294
|
+
this->centroids, unpack_8x2bit_to_u32(code, i), sizeof(float)));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
void encode_vector(const float* x, uint8_t* code) const final {
|
|
298
|
+
// 3 boundaries → branchless: idx = (x>b0) + (x>b1) + (x>b2)
|
|
299
|
+
// _mm256_cmp_ps returns all-ones (-1 as int32) for true,
|
|
300
|
+
// so we negate the sum to get positive indices.
|
|
301
|
+
__m256 b0 = _mm256_set1_ps(this->boundaries[0]);
|
|
302
|
+
__m256 b1 = _mm256_set1_ps(this->boundaries[1]);
|
|
303
|
+
__m256 b2 = _mm256_set1_ps(this->boundaries[2]);
|
|
304
|
+
for (size_t i = 0; i < this->d; i += 8) {
|
|
305
|
+
__m256 vals = _mm256_loadu_ps(x + i);
|
|
306
|
+
__m256i gt0 =
|
|
307
|
+
_mm256_castps_si256(_mm256_cmp_ps(vals, b0, _CMP_GT_OQ));
|
|
308
|
+
__m256i gt1 =
|
|
309
|
+
_mm256_castps_si256(_mm256_cmp_ps(vals, b1, _CMP_GT_OQ));
|
|
310
|
+
__m256i gt2 =
|
|
311
|
+
_mm256_castps_si256(_mm256_cmp_ps(vals, b2, _CMP_GT_OQ));
|
|
312
|
+
// Each gt is 0 or -1 (0xFFFFFFFF). Sum = -(index).
|
|
313
|
+
__m256i idx = _mm256_sub_epi32(
|
|
314
|
+
_mm256_setzero_si256(),
|
|
315
|
+
_mm256_add_epi32(_mm256_add_epi32(gt0, gt1), gt2));
|
|
316
|
+
// Pack 8 x 2-bit indices into 2 bytes.
|
|
317
|
+
// Store to temp array and pack scalarly - faster than
|
|
318
|
+
// extract+permute.
|
|
319
|
+
alignas(32) int32_t idx_array[8];
|
|
320
|
+
_mm256_store_si256((__m256i*)idx_array, idx);
|
|
321
|
+
for (int j = 0; j < 8; j++) {
|
|
322
|
+
this->encode_index(
|
|
323
|
+
static_cast<uint8_t>(idx_array[j] & 0x3), code, i + j);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
void decode_vector(const uint8_t* code, float* x) const final {
|
|
329
|
+
for (size_t i = 0; i < this->d; i += 8) {
|
|
330
|
+
simd8float32 xi =
|
|
331
|
+
reconstruct_8_components(code, static_cast<int>(i));
|
|
332
|
+
_mm256_storeu_ps(x + i, xi.f);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
// 3-bit and 4-bit MSE: use branchless comparison chain for encode.
|
|
338
|
+
// k boundaries → idx = sum of k-1 comparisons.
|
|
339
|
+
#define DEFINE_TQMSE_AVX2_MULTIBIT(NBITS, UNPACK_EXPR) \
|
|
340
|
+
template <> \
|
|
341
|
+
struct QuantizerTurboQuantMSE<NBITS, SIMDLevel::AVX2> \
|
|
342
|
+
: QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE> { \
|
|
343
|
+
using Base = QuantizerTurboQuantMSE<NBITS, SIMDLevel::NONE>; \
|
|
344
|
+
\
|
|
345
|
+
QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained) \
|
|
346
|
+
: Base(d, trained) { \
|
|
347
|
+
assert(d % 8 == 0); \
|
|
348
|
+
} \
|
|
349
|
+
\
|
|
350
|
+
FAISS_ALWAYS_INLINE simd8float32 \
|
|
351
|
+
reconstruct_8_components(const uint8_t* code, int i) const { \
|
|
352
|
+
return simd8float32(_mm256_i32gather_ps( \
|
|
353
|
+
this->centroids, (UNPACK_EXPR), sizeof(float))); \
|
|
354
|
+
} \
|
|
355
|
+
\
|
|
356
|
+
void decode_vector(const uint8_t* code, float* x) const final { \
|
|
357
|
+
for (size_t i = 0; i < this->d; i += 8) { \
|
|
358
|
+
simd8float32 xi = \
|
|
359
|
+
reconstruct_8_components(code, static_cast<int>(i)); \
|
|
360
|
+
_mm256_storeu_ps(x + i, xi.f); \
|
|
361
|
+
} \
|
|
362
|
+
} \
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
DEFINE_TQMSE_AVX2_MULTIBIT(3, unpack_8x3bit_to_u32(code, i));
|
|
366
|
+
DEFINE_TQMSE_AVX2_MULTIBIT(4, unpack_8x4bit_to_u32(code, i));
|
|
367
|
+
|
|
368
|
+
#undef DEFINE_TQMSE_AVX2_MULTIBIT
|
|
369
|
+
|
|
370
|
+
// 8-bit MSE: indices are raw bytes, no bit packing.
|
|
371
|
+
template <>
|
|
372
|
+
struct QuantizerTurboQuantMSE<8, SIMDLevel::AVX2>
|
|
373
|
+
: QuantizerTurboQuantMSE<8, SIMDLevel::NONE> {
|
|
374
|
+
using Base = QuantizerTurboQuantMSE<8, SIMDLevel::NONE>;
|
|
375
|
+
|
|
376
|
+
QuantizerTurboQuantMSE(size_t d, const std::vector<float>& trained)
|
|
377
|
+
: Base(d, trained) {
|
|
378
|
+
assert(d % 8 == 0);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
FAISS_ALWAYS_INLINE simd8float32
|
|
382
|
+
reconstruct_8_components(const uint8_t* code, int i) const {
|
|
383
|
+
const __m128i packed = _mm_loadl_epi64(
|
|
384
|
+
(const __m128i*)(code + static_cast<size_t>(i)));
|
|
385
|
+
const __m256i indices = _mm256_cvtepu8_epi32(packed);
|
|
386
|
+
return simd8float32(
|
|
387
|
+
_mm256_i32gather_ps(this->centroids, indices, sizeof(float)));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
void decode_vector(const uint8_t* code, float* x) const final {
|
|
391
|
+
for (size_t i = 0; i < this->d; i += 8) {
|
|
392
|
+
simd8float32 xi =
|
|
393
|
+
reconstruct_8_components(code, static_cast<int>(i));
|
|
394
|
+
_mm256_storeu_ps(x + i, xi.f);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
|
|
167
399
|
/**********************************************************
|
|
168
400
|
* FP16 Quantizer
|
|
169
401
|
**********************************************************/
|
|
@@ -288,6 +520,22 @@ struct SimilarityL2<SIMDLevel::AVX2> {
|
|
|
288
520
|
const __m128 v3 = _mm_add_ps(v1, v2);
|
|
289
521
|
return _mm_cvtss_f32(v3);
|
|
290
522
|
}
|
|
523
|
+
|
|
524
|
+
static void adjust_query_for_raw_decode(
|
|
525
|
+
const float* x,
|
|
526
|
+
float* q_adj,
|
|
527
|
+
size_t d,
|
|
528
|
+
float vmin,
|
|
529
|
+
float vdiff,
|
|
530
|
+
float& scale_factor,
|
|
531
|
+
float& bias) {
|
|
532
|
+
float inv_vdiff = (vdiff != 0) ? 1.0f / vdiff : 0.0f;
|
|
533
|
+
for (size_t i = 0; i < d; i++) {
|
|
534
|
+
q_adj[i] = (x[i] - vmin) * inv_vdiff;
|
|
535
|
+
}
|
|
536
|
+
scale_factor = vdiff * vdiff;
|
|
537
|
+
bias = 0;
|
|
538
|
+
}
|
|
291
539
|
};
|
|
292
540
|
|
|
293
541
|
template <>
|
|
@@ -331,6 +579,23 @@ struct SimilarityIP<SIMDLevel::AVX2> {
|
|
|
331
579
|
const __m128 v3 = _mm_add_ps(v1, v2);
|
|
332
580
|
return _mm_cvtss_f32(v3);
|
|
333
581
|
}
|
|
582
|
+
|
|
583
|
+
static void adjust_query_for_raw_decode(
|
|
584
|
+
const float* x,
|
|
585
|
+
float* q_adj,
|
|
586
|
+
size_t d,
|
|
587
|
+
float vmin,
|
|
588
|
+
float vdiff,
|
|
589
|
+
float& scale_factor,
|
|
590
|
+
float& bias) {
|
|
591
|
+
float sum_q = 0;
|
|
592
|
+
for (size_t i = 0; i < d; i++) {
|
|
593
|
+
q_adj[i] = x[i];
|
|
594
|
+
sum_q += x[i];
|
|
595
|
+
}
|
|
596
|
+
scale_factor = vdiff;
|
|
597
|
+
bias = vmin * sum_q;
|
|
598
|
+
}
|
|
334
599
|
};
|
|
335
600
|
|
|
336
601
|
/**********************************************************
|
|
@@ -343,8 +608,23 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
|
|
|
343
608
|
|
|
344
609
|
Quantizer quant;
|
|
345
610
|
|
|
611
|
+
// Pre-adjusted query buffer for uniform quantizers
|
|
612
|
+
std::vector<float> q_adj;
|
|
613
|
+
float scale_factor = 0;
|
|
614
|
+
float bias = 0;
|
|
615
|
+
|
|
616
|
+
static constexpr bool has_decode_raw() {
|
|
617
|
+
return requires(const Quantizer& q, const uint8_t* c, int i) {
|
|
618
|
+
{ q.decode_8_raw(c, i) };
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
|
|
346
622
|
DCTemplate(size_t d, const std::vector<float>& trained)
|
|
347
|
-
: quant(d, trained) {
|
|
623
|
+
: quant(d, trained) {
|
|
624
|
+
if constexpr (has_decode_raw()) {
|
|
625
|
+
q_adj.resize(d);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
348
628
|
|
|
349
629
|
float compute_distance(const float* x, const uint8_t* code) const {
|
|
350
630
|
Similarity sim(x);
|
|
@@ -373,6 +653,26 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
|
|
|
373
653
|
|
|
374
654
|
void set_query(const float* x) final {
|
|
375
655
|
q = x;
|
|
656
|
+
if constexpr (has_decode_raw()) {
|
|
657
|
+
Sim::adjust_query_for_raw_decode(
|
|
658
|
+
x,
|
|
659
|
+
q_adj.data(),
|
|
660
|
+
quant.d,
|
|
661
|
+
quant.vmin,
|
|
662
|
+
quant.vdiff,
|
|
663
|
+
scale_factor,
|
|
664
|
+
bias);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
float query_to_code_predecoded(const uint8_t* code) const {
|
|
669
|
+
Similarity sim(q_adj.data());
|
|
670
|
+
sim.begin_8();
|
|
671
|
+
for (size_t i = 0; i < quant.d; i += 8) {
|
|
672
|
+
simd8float32 xi = quant.decode_8_raw(code, static_cast<int>(i));
|
|
673
|
+
sim.add_8_components(xi);
|
|
674
|
+
}
|
|
675
|
+
return bias + scale_factor * sim.result_8();
|
|
376
676
|
}
|
|
377
677
|
|
|
378
678
|
float symmetric_dis(idx_t i, idx_t j) override {
|
|
@@ -381,7 +681,48 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
|
|
|
381
681
|
}
|
|
382
682
|
|
|
383
683
|
float query_to_code(const uint8_t* code) const final {
|
|
384
|
-
|
|
684
|
+
if constexpr (has_decode_raw()) {
|
|
685
|
+
return query_to_code_predecoded(code);
|
|
686
|
+
} else {
|
|
687
|
+
return compute_distance(q, code);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
void query_to_codes_batch_4(
|
|
692
|
+
const uint8_t* code_0,
|
|
693
|
+
const uint8_t* code_1,
|
|
694
|
+
const uint8_t* code_2,
|
|
695
|
+
const uint8_t* code_3,
|
|
696
|
+
float& dis0,
|
|
697
|
+
float& dis1,
|
|
698
|
+
float& dis2,
|
|
699
|
+
float& dis3) const final {
|
|
700
|
+
Similarity sim0(q);
|
|
701
|
+
Similarity sim1(q);
|
|
702
|
+
Similarity sim2(q);
|
|
703
|
+
Similarity sim3(q);
|
|
704
|
+
|
|
705
|
+
sim0.begin_8();
|
|
706
|
+
sim1.begin_8();
|
|
707
|
+
sim2.begin_8();
|
|
708
|
+
sim3.begin_8();
|
|
709
|
+
|
|
710
|
+
for (size_t i = 0; i < quant.d; i += 8) {
|
|
711
|
+
const int ii = static_cast<int>(i);
|
|
712
|
+
simd8float32 xi0 = quant.reconstruct_8_components(code_0, ii);
|
|
713
|
+
simd8float32 xi1 = quant.reconstruct_8_components(code_1, ii);
|
|
714
|
+
simd8float32 xi2 = quant.reconstruct_8_components(code_2, ii);
|
|
715
|
+
simd8float32 xi3 = quant.reconstruct_8_components(code_3, ii);
|
|
716
|
+
sim0.add_8_components(xi0);
|
|
717
|
+
sim1.add_8_components(xi1);
|
|
718
|
+
sim2.add_8_components(xi2);
|
|
719
|
+
sim3.add_8_components(xi3);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
dis0 = sim0.result_8();
|
|
723
|
+
dis1 = sim1.result_8();
|
|
724
|
+
dis2 = sim2.result_8();
|
|
725
|
+
dis3 = sim3.result_8();
|
|
385
726
|
}
|
|
386
727
|
};
|
|
387
728
|
|
|
@@ -446,6 +787,50 @@ struct DistanceComputerByte<Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
|
|
|
446
787
|
}
|
|
447
788
|
};
|
|
448
789
|
|
|
790
|
+
/**********************************************************
|
|
791
|
+
* TurboQuant masked_sum AVX2 specialization
|
|
792
|
+
**********************************************************/
|
|
793
|
+
|
|
794
|
+
template <SIMDLevel SL0>
|
|
795
|
+
float turboq_masked_sum(const float* arr, const uint8_t* bits, size_t d);
|
|
796
|
+
|
|
797
|
+
template <>
|
|
798
|
+
float turboq_masked_sum<SIMDLevel::AVX2>(
|
|
799
|
+
const float* arr,
|
|
800
|
+
const uint8_t* bits,
|
|
801
|
+
size_t d) {
|
|
802
|
+
const __m256i bit_masks = _mm256_set_epi32(128, 64, 32, 16, 8, 4, 2, 1);
|
|
803
|
+
__m256 acc = _mm256_setzero_ps();
|
|
804
|
+
size_t full_bytes = d / 8;
|
|
805
|
+
for (size_t byte_idx = 0; byte_idx < full_bytes; byte_idx++) {
|
|
806
|
+
__m256i byte_broadcast =
|
|
807
|
+
_mm256_set1_epi32(static_cast<int>(bits[byte_idx]));
|
|
808
|
+
__m256i masked = _mm256_and_si256(byte_broadcast, bit_masks);
|
|
809
|
+
__m256i cmp = _mm256_cmpeq_epi32(masked, bit_masks);
|
|
810
|
+
__m256 mask = _mm256_castsi256_ps(cmp);
|
|
811
|
+
__m256 vals = _mm256_loadu_ps(arr + byte_idx * 8);
|
|
812
|
+
acc = _mm256_add_ps(acc, _mm256_and_ps(mask, vals));
|
|
813
|
+
}
|
|
814
|
+
__m128 hi = _mm256_extractf128_ps(acc, 1);
|
|
815
|
+
__m128 lo = _mm256_castps256_ps128(acc);
|
|
816
|
+
__m128 sum128 = _mm_add_ps(lo, hi);
|
|
817
|
+
__m128 shuf = _mm_movehdup_ps(sum128);
|
|
818
|
+
__m128 sums = _mm_add_ps(sum128, shuf);
|
|
819
|
+
shuf = _mm_movehl_ps(shuf, sums);
|
|
820
|
+
sums = _mm_add_ss(sums, shuf);
|
|
821
|
+
float result = _mm_cvtss_f32(sums);
|
|
822
|
+
size_t tail_start = full_bytes * 8;
|
|
823
|
+
if (tail_start < d) {
|
|
824
|
+
uint8_t last_byte = bits[full_bytes];
|
|
825
|
+
for (size_t j = tail_start; j < d; j++) {
|
|
826
|
+
if (last_byte & (1 << (j - tail_start))) {
|
|
827
|
+
result += arr[j];
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
return result;
|
|
832
|
+
}
|
|
833
|
+
|
|
449
834
|
} // namespace scalar_quantizer
|
|
450
835
|
} // namespace faiss
|
|
451
836
|
|