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
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
10
|
#include <faiss/impl/ScalarQuantizer.h>
|
|
11
|
+
#include <faiss/impl/simdlib/simdlib_dispatch.h>
|
|
11
12
|
#include <faiss/utils/simd_levels.h>
|
|
12
|
-
#include <faiss/utils/simdlib.h>
|
|
13
13
|
|
|
14
14
|
namespace faiss {
|
|
15
15
|
|
|
@@ -77,6 +77,12 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::NONE> : SQDistanceComputer {
|
|
|
77
77
|
template <class Similarity, SIMDLevel SL>
|
|
78
78
|
struct DistanceComputerByte : SQDistanceComputer {};
|
|
79
79
|
|
|
80
|
+
// Byte-domain distance computer for QT_8bit_direct_signed (storage is
|
|
81
|
+
// value+128). Only specialized for AVX512_SPR; other levels fall back to
|
|
82
|
+
// the float-domain DCTemplate path via the dispatch logic.
|
|
83
|
+
template <class Similarity, SIMDLevel SL>
|
|
84
|
+
struct DistanceComputerByteSigned : SQDistanceComputer {};
|
|
85
|
+
|
|
80
86
|
template <class Similarity>
|
|
81
87
|
struct DistanceComputerByte<Similarity, SIMDLevel::NONE> : SQDistanceComputer {
|
|
82
88
|
using Sim = Similarity;
|
|
@@ -84,7 +90,8 @@ struct DistanceComputerByte<Similarity, SIMDLevel::NONE> : SQDistanceComputer {
|
|
|
84
90
|
int d;
|
|
85
91
|
std::vector<uint8_t> tmp;
|
|
86
92
|
|
|
87
|
-
DistanceComputerByte(int
|
|
93
|
+
DistanceComputerByte(int d_in, const std::vector<float>&)
|
|
94
|
+
: d(d_in), tmp(d_in) {}
|
|
88
95
|
|
|
89
96
|
int compute_code_distance(const uint8_t* code1, const uint8_t* code2)
|
|
90
97
|
const {
|
|
@@ -7,11 +7,44 @@
|
|
|
7
7
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
|
+
#include <cmath>
|
|
11
|
+
|
|
12
|
+
// Hack for MSVC
|
|
13
|
+
#ifndef M_PI
|
|
14
|
+
#define M_PI 3.14159265358979323846
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
#include <algorithm>
|
|
18
|
+
#include <cstring>
|
|
19
|
+
|
|
20
|
+
#include <faiss/impl/FaissAssert.h>
|
|
21
|
+
#include <faiss/impl/RaBitQUtils.h>
|
|
10
22
|
#include <faiss/impl/ScalarQuantizer.h>
|
|
23
|
+
#include <faiss/impl/platform_macros.h>
|
|
24
|
+
#include <faiss/impl/simdlib/simdlib_dispatch.h>
|
|
11
25
|
#include <faiss/utils/bf16.h>
|
|
26
|
+
#include <faiss/utils/distances.h>
|
|
12
27
|
#include <faiss/utils/fp16.h>
|
|
28
|
+
#include <faiss/utils/random.h>
|
|
13
29
|
#include <faiss/utils/simd_levels.h>
|
|
14
|
-
#include <faiss/utils/
|
|
30
|
+
#include <faiss/utils/utils.h>
|
|
31
|
+
|
|
32
|
+
extern "C" {
|
|
33
|
+
int sgemm_(
|
|
34
|
+
const char* transa,
|
|
35
|
+
const char* transb,
|
|
36
|
+
int* m,
|
|
37
|
+
int* n,
|
|
38
|
+
int* k,
|
|
39
|
+
const float* alpha,
|
|
40
|
+
const float* a,
|
|
41
|
+
int* lda,
|
|
42
|
+
const float* b,
|
|
43
|
+
int* ldb,
|
|
44
|
+
float* beta,
|
|
45
|
+
float* c,
|
|
46
|
+
int* ldc);
|
|
47
|
+
}
|
|
15
48
|
|
|
16
49
|
namespace faiss {
|
|
17
50
|
|
|
@@ -37,8 +70,8 @@ struct QuantizerTemplate<
|
|
|
37
70
|
const size_t d;
|
|
38
71
|
const float vmin, vdiff;
|
|
39
72
|
|
|
40
|
-
QuantizerTemplate(size_t
|
|
41
|
-
: d(
|
|
73
|
+
QuantizerTemplate(size_t d_in, const std::vector<float>& trained)
|
|
74
|
+
: d(d_in), vmin(trained[0]), vdiff(trained[1]) {}
|
|
42
75
|
|
|
43
76
|
void encode_vector(const float* x, uint8_t* code) const final {
|
|
44
77
|
for (size_t i = 0; i < d; i++) {
|
|
@@ -79,8 +112,8 @@ struct QuantizerTemplate<
|
|
|
79
112
|
const size_t d;
|
|
80
113
|
const float *vmin, *vdiff;
|
|
81
114
|
|
|
82
|
-
QuantizerTemplate(size_t
|
|
83
|
-
: d(
|
|
115
|
+
QuantizerTemplate(size_t d_in, const std::vector<float>& trained)
|
|
116
|
+
: d(d_in), vmin(trained.data()), vdiff(trained.data() + d_in) {}
|
|
84
117
|
|
|
85
118
|
void encode_vector(const float* x, uint8_t* code) const final {
|
|
86
119
|
for (size_t i = 0; i < d; i++) {
|
|
@@ -113,6 +146,86 @@ struct QuantizerTemplate<
|
|
|
113
146
|
}
|
|
114
147
|
};
|
|
115
148
|
|
|
149
|
+
/*******************************************************************
|
|
150
|
+
* TurboQuant MSE quantizer
|
|
151
|
+
*******************************************************************/
|
|
152
|
+
template <int NBits, SIMDLevel SL>
|
|
153
|
+
struct QuantizerTurboQuantMSE;
|
|
154
|
+
|
|
155
|
+
template <int NBits>
|
|
156
|
+
struct QuantizerTurboQuantMSE<NBits, SIMDLevel::NONE>
|
|
157
|
+
: ScalarQuantizer::SQuantizer {
|
|
158
|
+
static_assert(NBits >= 1 && NBits <= 8);
|
|
159
|
+
|
|
160
|
+
static constexpr size_t kCentroidsCount = size_t(1) << NBits;
|
|
161
|
+
static constexpr uint16_t kIndexMask =
|
|
162
|
+
static_cast<uint16_t>((1u << NBits) - 1);
|
|
163
|
+
|
|
164
|
+
const size_t d;
|
|
165
|
+
const float* centroids;
|
|
166
|
+
const float* boundaries;
|
|
167
|
+
|
|
168
|
+
QuantizerTurboQuantMSE(size_t d_in, const std::vector<float>& trained)
|
|
169
|
+
: d(d_in), centroids(nullptr), boundaries(nullptr) {
|
|
170
|
+
FAISS_THROW_IF_NOT(trained.size() == 2 * kCentroidsCount - 1);
|
|
171
|
+
centroids = trained.data();
|
|
172
|
+
boundaries = trained.data() + kCentroidsCount;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
uint8_t select_index(float x) const {
|
|
176
|
+
return static_cast<uint8_t>(
|
|
177
|
+
std::upper_bound(
|
|
178
|
+
boundaries, boundaries + (kCentroidsCount - 1), x) -
|
|
179
|
+
boundaries);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
void encode_index(uint8_t idx, uint8_t* code, size_t i) const {
|
|
183
|
+
const size_t bit_offset = i * NBits;
|
|
184
|
+
const size_t byte_offset = bit_offset >> 3;
|
|
185
|
+
const size_t bit_shift = bit_offset & 7;
|
|
186
|
+
const uint16_t packed = static_cast<uint16_t>(idx & kIndexMask)
|
|
187
|
+
<< bit_shift;
|
|
188
|
+
code[byte_offset] |= packed & 0xff;
|
|
189
|
+
if (bit_shift + NBits > 8) {
|
|
190
|
+
code[byte_offset + 1] |= packed >> 8;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
uint8_t decode_index(const uint8_t* code, size_t i) const {
|
|
195
|
+
const size_t bit_offset = i * NBits;
|
|
196
|
+
const size_t byte_offset = bit_offset >> 3;
|
|
197
|
+
const size_t bit_shift = bit_offset & 7;
|
|
198
|
+
|
|
199
|
+
uint16_t packed = code[byte_offset];
|
|
200
|
+
if (bit_shift + NBits > 8) {
|
|
201
|
+
packed |= static_cast<uint16_t>(code[byte_offset + 1]) << 8;
|
|
202
|
+
}
|
|
203
|
+
return static_cast<uint8_t>((packed >> bit_shift) & kIndexMask);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
void encode_vector(const float* x, uint8_t* code) const override {
|
|
207
|
+
for (size_t i = 0; i < d; i++) {
|
|
208
|
+
encode_index(select_index(x[i]), code, i);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
void decode_vector(const uint8_t* code, float* x) const override {
|
|
213
|
+
for (size_t i = 0; i < d; i++) {
|
|
214
|
+
x[i] = centroids[decode_index(code, i)];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
float reconstruct_component(const uint8_t* code, size_t i) const {
|
|
219
|
+
return centroids[decode_index(code, i)];
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
template <int NBits, SIMDLevel SL>
|
|
224
|
+
struct QuantizerTurboQuantMSE : QuantizerTurboQuantMSE<NBits, SIMDLevel::NONE> {
|
|
225
|
+
using QuantizerTurboQuantMSE<NBits, SIMDLevel::NONE>::
|
|
226
|
+
QuantizerTurboQuantMSE;
|
|
227
|
+
};
|
|
228
|
+
|
|
116
229
|
/*******************************************************************
|
|
117
230
|
* FP16 quantizer
|
|
118
231
|
*******************************************************************/
|
|
@@ -124,7 +237,8 @@ template <>
|
|
|
124
237
|
struct QuantizerFP16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
|
|
125
238
|
const size_t d;
|
|
126
239
|
|
|
127
|
-
QuantizerFP16(size_t
|
|
240
|
+
QuantizerFP16(size_t d_in, const std::vector<float>& /* unused */)
|
|
241
|
+
: d(d_in) {}
|
|
128
242
|
|
|
129
243
|
void encode_vector(const float* x, uint8_t* code) const final {
|
|
130
244
|
for (size_t i = 0; i < d; i++) {
|
|
@@ -161,18 +275,15 @@ template <>
|
|
|
161
275
|
struct QuantizerBF16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
|
|
162
276
|
const size_t d;
|
|
163
277
|
|
|
164
|
-
QuantizerBF16(size_t
|
|
278
|
+
QuantizerBF16(size_t d_in, const std::vector<float>& /* unused */)
|
|
279
|
+
: d(d_in) {}
|
|
165
280
|
|
|
166
|
-
void encode_vector(const float* x, uint8_t* code) const
|
|
167
|
-
|
|
168
|
-
((uint16_t*)code)[i] = encode_bf16(x[i]);
|
|
169
|
-
}
|
|
281
|
+
void encode_vector(const float* x, uint8_t* code) const override {
|
|
282
|
+
encode_bf16_simd(x, (uint16_t*)code, d);
|
|
170
283
|
}
|
|
171
284
|
|
|
172
|
-
void decode_vector(const uint8_t* code, float* x) const
|
|
173
|
-
|
|
174
|
-
x[i] = decode_bf16(((uint16_t*)code)[i]);
|
|
175
|
-
}
|
|
285
|
+
void decode_vector(const uint8_t* code, float* x) const override {
|
|
286
|
+
decode_bf16_simd((const uint16_t*)code, x, d);
|
|
176
287
|
}
|
|
177
288
|
|
|
178
289
|
FAISS_ALWAYS_INLINE float reconstruct_component(
|
|
@@ -187,6 +298,11 @@ struct QuantizerBF16 : QuantizerBF16<SIMDLevel::NONE> {
|
|
|
187
298
|
using QuantizerBF16<SIMDLevel::NONE>::QuantizerBF16;
|
|
188
299
|
};
|
|
189
300
|
|
|
301
|
+
template <>
|
|
302
|
+
struct QuantizerBF16<SIMDLevel::AVX512>;
|
|
303
|
+
template <>
|
|
304
|
+
struct QuantizerBF16<SIMDLevel::AVX512_SPR>;
|
|
305
|
+
|
|
190
306
|
/*******************************************************************
|
|
191
307
|
* 8bit_direct quantizer
|
|
192
308
|
*******************************************************************/
|
|
@@ -198,8 +314,8 @@ template <>
|
|
|
198
314
|
struct Quantizer8bitDirect<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
|
|
199
315
|
const size_t d;
|
|
200
316
|
|
|
201
|
-
Quantizer8bitDirect(size_t
|
|
202
|
-
: d(
|
|
317
|
+
Quantizer8bitDirect(size_t d_in, const std::vector<float>& /* unused */)
|
|
318
|
+
: d(d_in) {}
|
|
203
319
|
|
|
204
320
|
void encode_vector(const float* x, uint8_t* code) const final {
|
|
205
321
|
for (size_t i = 0; i < d; i++) {
|
|
@@ -237,8 +353,10 @@ struct Quantizer8bitDirectSigned<SIMDLevel::NONE>
|
|
|
237
353
|
: ScalarQuantizer::SQuantizer {
|
|
238
354
|
const size_t d;
|
|
239
355
|
|
|
240
|
-
Quantizer8bitDirectSigned(
|
|
241
|
-
|
|
356
|
+
Quantizer8bitDirectSigned(
|
|
357
|
+
size_t d_in,
|
|
358
|
+
const std::vector<float>& /* unused */)
|
|
359
|
+
: d(d_in) {}
|
|
242
360
|
|
|
243
361
|
void encode_vector(const float* x, uint8_t* code) const final {
|
|
244
362
|
for (size_t i = 0; i < d; i++) {
|
|
@@ -264,6 +382,288 @@ struct Quantizer8bitDirectSigned : Quantizer8bitDirectSigned<SIMDLevel::NONE> {
|
|
|
264
382
|
using Quantizer8bitDirectSigned<SIMDLevel::NONE>::Quantizer8bitDirectSigned;
|
|
265
383
|
};
|
|
266
384
|
|
|
385
|
+
/*******************************************************************
|
|
386
|
+
* Full TurboQuant (MSE + QJL) quantizer
|
|
387
|
+
*
|
|
388
|
+
* NBits = total bits per dimension (2-5).
|
|
389
|
+
* MSE bits = NBits - 1, QJL bits = 1.
|
|
390
|
+
*
|
|
391
|
+
* Trained vector layout:
|
|
392
|
+
* [centroids (k floats), boundaries (k-1 floats),
|
|
393
|
+
* seed_lo (float), seed_hi (float), qjl_type (float)]
|
|
394
|
+
* where k = 2^(NBits-1).
|
|
395
|
+
*******************************************************************/
|
|
396
|
+
|
|
397
|
+
FAISS_PACK_STRUCTS_BEGIN
|
|
398
|
+
struct SQTurboQFactors {
|
|
399
|
+
float norm = 0;
|
|
400
|
+
float gamma = 0;
|
|
401
|
+
};
|
|
402
|
+
FAISS_PACK_STRUCTS_END
|
|
403
|
+
|
|
404
|
+
template <int NBits, SIMDLevel SL>
|
|
405
|
+
struct QuantizerTurboQuantFull;
|
|
406
|
+
|
|
407
|
+
template <int NBits>
|
|
408
|
+
struct QuantizerTurboQuantFull<NBits, SIMDLevel::NONE>
|
|
409
|
+
: ScalarQuantizer::SQuantizer {
|
|
410
|
+
static_assert(NBits >= 2 && NBits <= 5);
|
|
411
|
+
|
|
412
|
+
static constexpr int kMSEBits = NBits - 1;
|
|
413
|
+
static constexpr size_t kCentroidsCount = size_t(1) << kMSEBits;
|
|
414
|
+
|
|
415
|
+
const size_t d;
|
|
416
|
+
const float* centroids;
|
|
417
|
+
const float* boundaries;
|
|
418
|
+
|
|
419
|
+
// QJL projection type: 0 = FWHT, 2 = Random Rotation
|
|
420
|
+
uint8_t qjl_type;
|
|
421
|
+
|
|
422
|
+
// FWHT state (qjl_type == 0)
|
|
423
|
+
size_t padded_d;
|
|
424
|
+
std::vector<float> fwht_signs;
|
|
425
|
+
|
|
426
|
+
// Random Rotation state (qjl_type == 2)
|
|
427
|
+
std::vector<float> rr_matrix; // d x d orthogonal matrix (row-major)
|
|
428
|
+
|
|
429
|
+
size_t mse_plane_bytes; // bytes for one bit-plane of d bits
|
|
430
|
+
size_t mse_total_bytes; // kMSEBits * mse_plane_bytes
|
|
431
|
+
size_t qjl_plane_bytes;
|
|
432
|
+
|
|
433
|
+
QuantizerTurboQuantFull(size_t d_in, const std::vector<float>& trained)
|
|
434
|
+
: d(d_in),
|
|
435
|
+
centroids(trained.data()),
|
|
436
|
+
boundaries(trained.data() + kCentroidsCount) {
|
|
437
|
+
// trained = [centroids(k), boundaries(k-1), seed_lo, seed_hi, qjl_type]
|
|
438
|
+
size_t k = kCentroidsCount;
|
|
439
|
+
FAISS_THROW_IF_NOT(trained.size() == 2 * k - 1 + 3);
|
|
440
|
+
|
|
441
|
+
mse_plane_bytes = (d + 7) / 8;
|
|
442
|
+
mse_total_bytes = kMSEBits * mse_plane_bytes;
|
|
443
|
+
qjl_plane_bytes = (d + 7) / 8;
|
|
444
|
+
|
|
445
|
+
// Extract seed from trained
|
|
446
|
+
uint64_t seed = ScalarQuantizer::TurboQuantRefine::unpack_seed(
|
|
447
|
+
trained[2 * k - 1], trained[2 * k]);
|
|
448
|
+
qjl_type = static_cast<uint8_t>(trained[2 * k + 1]);
|
|
449
|
+
|
|
450
|
+
if (qjl_type == 0) {
|
|
451
|
+
// FWHT mode
|
|
452
|
+
padded_d = 1;
|
|
453
|
+
while (padded_d < d) {
|
|
454
|
+
padded_d <<= 1;
|
|
455
|
+
}
|
|
456
|
+
fwht_signs.resize(padded_d);
|
|
457
|
+
RandomGenerator rng(seed);
|
|
458
|
+
for (size_t i = 0; i < padded_d; i++) {
|
|
459
|
+
fwht_signs[i] = (rng.rand_int(2) == 0) ? 1.0f : -1.0f;
|
|
460
|
+
}
|
|
461
|
+
} else {
|
|
462
|
+
// Random Rotation mode
|
|
463
|
+
padded_d = d; // no padding needed for dense multiply
|
|
464
|
+
rr_matrix.resize(d * d);
|
|
465
|
+
float_randn(rr_matrix.data(), d * d, static_cast<int64_t>(seed));
|
|
466
|
+
matrix_qr(
|
|
467
|
+
static_cast<int>(d), static_cast<int>(d), rr_matrix.data());
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
void fwht_inplace(float* x, size_t n) const {
|
|
472
|
+
for (size_t h = 1; h < n; h <<= 1) {
|
|
473
|
+
for (size_t i = 0; i < n; i += h << 1) {
|
|
474
|
+
for (size_t j = i; j < i + h; j++) {
|
|
475
|
+
float a = x[j];
|
|
476
|
+
float b = x[j + h];
|
|
477
|
+
x[j] = a + b;
|
|
478
|
+
x[j + h] = a - b;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/// Forward QJL projection: residual -> projected (d outputs)
|
|
485
|
+
void project_forward(const float* residual, float* out) const {
|
|
486
|
+
if (qjl_type == 0) {
|
|
487
|
+
std::vector<float> fwht_buf(padded_d);
|
|
488
|
+
for (size_t j = 0; j < d; j++) {
|
|
489
|
+
fwht_buf[j] = residual[j] * fwht_signs[j];
|
|
490
|
+
}
|
|
491
|
+
for (size_t j = d; j < padded_d; j++) {
|
|
492
|
+
fwht_buf[j] = 0.0f;
|
|
493
|
+
}
|
|
494
|
+
fwht_inplace(fwht_buf.data(), padded_d);
|
|
495
|
+
for (size_t j = 0; j < d; j++) {
|
|
496
|
+
out[j] = fwht_buf[j];
|
|
497
|
+
}
|
|
498
|
+
} else {
|
|
499
|
+
rr_forward(residual, out);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/// Inverse QJL projection: signs_buf -> reconstructed (d outputs)
|
|
504
|
+
void project_inverse(float* signs_buf, float* out) const {
|
|
505
|
+
if (qjl_type == 0) {
|
|
506
|
+
fwht_inplace(signs_buf, padded_d);
|
|
507
|
+
for (size_t j = 0; j < d; j++) {
|
|
508
|
+
out[j] = signs_buf[j] * fwht_signs[j];
|
|
509
|
+
}
|
|
510
|
+
} else {
|
|
511
|
+
rr_inverse(signs_buf, out);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
void rr_forward(const float* x, float* out) const {
|
|
516
|
+
float alpha = 1.0f;
|
|
517
|
+
float beta = 0.0f;
|
|
518
|
+
int di = static_cast<int>(d);
|
|
519
|
+
int one = 1;
|
|
520
|
+
sgemm_("T",
|
|
521
|
+
"N",
|
|
522
|
+
&di,
|
|
523
|
+
&one,
|
|
524
|
+
&di,
|
|
525
|
+
&alpha,
|
|
526
|
+
rr_matrix.data(),
|
|
527
|
+
&di,
|
|
528
|
+
x,
|
|
529
|
+
&di,
|
|
530
|
+
&beta,
|
|
531
|
+
out,
|
|
532
|
+
&di);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
void rr_inverse(const float* x, float* out) const {
|
|
536
|
+
float alpha = 1.0f;
|
|
537
|
+
float beta = 0.0f;
|
|
538
|
+
int di = static_cast<int>(d);
|
|
539
|
+
int one = 1;
|
|
540
|
+
sgemm_("N",
|
|
541
|
+
"N",
|
|
542
|
+
&di,
|
|
543
|
+
&one,
|
|
544
|
+
&di,
|
|
545
|
+
&alpha,
|
|
546
|
+
rr_matrix.data(),
|
|
547
|
+
&di,
|
|
548
|
+
x,
|
|
549
|
+
&di,
|
|
550
|
+
&beta,
|
|
551
|
+
out,
|
|
552
|
+
&di);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/// Store MSE index for dimension j using BIT-PLANE layout.
|
|
556
|
+
/// Plane p stores bit p of every dimension's index.
|
|
557
|
+
void store_mse_index(uint8_t idx, uint8_t* code, size_t j) const {
|
|
558
|
+
for (int p = 0; p < kMSEBits; p++) {
|
|
559
|
+
if (idx & (1 << p)) {
|
|
560
|
+
code[p * mse_plane_bytes + j / 8] |= (1 << (j % 8));
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/// Load MSE index for dimension j from BIT-PLANE layout.
|
|
566
|
+
uint8_t load_mse_index(const uint8_t* code, size_t j) const {
|
|
567
|
+
uint8_t idx = 0;
|
|
568
|
+
for (int p = 0; p < kMSEBits; p++) {
|
|
569
|
+
if (code[p * mse_plane_bytes + j / 8] & (1 << (j % 8))) {
|
|
570
|
+
idx |= (1 << p);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
return idx;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
void encode_vector(const float* x, uint8_t* code) const final {
|
|
577
|
+
float sqrt_d = std::sqrt(static_cast<float>(d));
|
|
578
|
+
float inv_sqrt_d = 1.0f / sqrt_d;
|
|
579
|
+
|
|
580
|
+
float x_norm = std::sqrt(fvec_norm_L2sqr(x, d));
|
|
581
|
+
if (x_norm < 1e-30f) {
|
|
582
|
+
x_norm = 1e-30f;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// MSE quantize in scaled space + compute residual
|
|
586
|
+
std::vector<float> residual(padded_d);
|
|
587
|
+
for (size_t j = 0; j < d; j++) {
|
|
588
|
+
float v = x[j] / x_norm; // unit-normalized
|
|
589
|
+
float val = v * sqrt_d; // scaled for MSE lookup
|
|
590
|
+
uint8_t idx = static_cast<uint8_t>(
|
|
591
|
+
std::upper_bound(
|
|
592
|
+
boundaries,
|
|
593
|
+
boundaries + (kCentroidsCount - 1),
|
|
594
|
+
val) -
|
|
595
|
+
boundaries);
|
|
596
|
+
store_mse_index(idx, code, j);
|
|
597
|
+
residual[j] = v - centroids[idx] * inv_sqrt_d;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// QJL: project residual, take signs
|
|
601
|
+
std::vector<float> proj(d);
|
|
602
|
+
project_forward(residual.data(), proj.data());
|
|
603
|
+
|
|
604
|
+
uint8_t* qjl_code = code + mse_total_bytes;
|
|
605
|
+
for (size_t j = 0; j < d; j++) {
|
|
606
|
+
if (proj[j] > 0.0f) {
|
|
607
|
+
rabitq_utils::set_bit_standard(qjl_code, j);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Store per-vector factors
|
|
612
|
+
float gamma = std::sqrt(fvec_norm_L2sqr(residual.data(), d));
|
|
613
|
+
auto* factors = reinterpret_cast<SQTurboQFactors*>(
|
|
614
|
+
code + mse_total_bytes + qjl_plane_bytes);
|
|
615
|
+
factors->norm = x_norm;
|
|
616
|
+
factors->gamma = gamma;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
void decode_vector(const uint8_t* code, float* x) const final {
|
|
620
|
+
float inv_sqrt_d = 1.0f / std::sqrt(static_cast<float>(d));
|
|
621
|
+
float inv_sqrt_pd = 1.0f / std::sqrt(static_cast<float>(padded_d));
|
|
622
|
+
|
|
623
|
+
const auto* factors = reinterpret_cast<const SQTurboQFactors*>(
|
|
624
|
+
code + mse_total_bytes + qjl_plane_bytes);
|
|
625
|
+
|
|
626
|
+
// MSE reconstruction
|
|
627
|
+
for (size_t j = 0; j < d; j++) {
|
|
628
|
+
uint8_t idx = load_mse_index(code, j);
|
|
629
|
+
x[j] = centroids[idx] * inv_sqrt_d;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// QJL reconstruction: coeff * gamma * S^T * signs
|
|
633
|
+
const uint8_t* qjl_code = code + mse_total_bytes;
|
|
634
|
+
float coeff =
|
|
635
|
+
std::sqrt(M_PI / 2.0f) / static_cast<float>(d) * factors->gamma;
|
|
636
|
+
|
|
637
|
+
std::vector<float> signs_buf(padded_d);
|
|
638
|
+
for (size_t j = 0; j < d; j++) {
|
|
639
|
+
signs_buf[j] = rabitq_utils::extract_bit_standard(qjl_code, j)
|
|
640
|
+
? inv_sqrt_pd
|
|
641
|
+
: -inv_sqrt_pd;
|
|
642
|
+
}
|
|
643
|
+
for (size_t j = d; j < padded_d; j++) {
|
|
644
|
+
signs_buf[j] = 0.0f;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
std::vector<float> reconstructed(d);
|
|
648
|
+
project_inverse(signs_buf.data(), reconstructed.data());
|
|
649
|
+
for (size_t j = 0; j < d; j++) {
|
|
650
|
+
x[j] += coeff * reconstructed[j];
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// Scale by norm
|
|
654
|
+
for (size_t j = 0; j < d; j++) {
|
|
655
|
+
x[j] *= factors->norm;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
|
|
660
|
+
template <int NBits, SIMDLevel SL>
|
|
661
|
+
struct QuantizerTurboQuantFull
|
|
662
|
+
: QuantizerTurboQuantFull<NBits, SIMDLevel::NONE> {
|
|
663
|
+
using QuantizerTurboQuantFull<NBits, SIMDLevel::NONE>::
|
|
664
|
+
QuantizerTurboQuantFull;
|
|
665
|
+
};
|
|
666
|
+
|
|
267
667
|
/*******************************************************************
|
|
268
668
|
* Selection function
|
|
269
669
|
*******************************************************************/
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
#pragma once
|
|
12
12
|
|
|
13
13
|
#include <faiss/impl/ScalarQuantizer.h>
|
|
14
|
+
#include <faiss/impl/simdlib/simdlib_dispatch.h>
|
|
14
15
|
#include <faiss/utils/simd_levels.h>
|
|
15
|
-
#include <faiss/utils/simdlib.h>
|
|
16
16
|
|
|
17
17
|
#include <faiss/impl/simd_dispatch.h>
|
|
18
18
|
|
|
@@ -159,6 +159,32 @@ InvertedListScanner* sq_select_InvertedListScanner(
|
|
|
159
159
|
const IDSelector* sel,
|
|
160
160
|
bool by_residual);
|
|
161
161
|
|
|
162
|
+
/// Scanner for QT_0bit / centroid-only distance: always returns the
|
|
163
|
+
/// coarse distance that was set via set_list().
|
|
164
|
+
struct IVFCoarseDistanceScanner : InvertedListScanner {
|
|
165
|
+
float coarse_dis = 0;
|
|
166
|
+
|
|
167
|
+
IVFCoarseDistanceScanner(
|
|
168
|
+
bool is_similarity,
|
|
169
|
+
bool store_pairs,
|
|
170
|
+
const IDSelector* sel)
|
|
171
|
+
: InvertedListScanner(store_pairs, sel) {
|
|
172
|
+
code_size = 0;
|
|
173
|
+
keep_max = is_similarity;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
void set_query(const float* /*query_vector*/) override {}
|
|
177
|
+
|
|
178
|
+
void set_list(idx_t list_no_in, float coarse_dis_in) override {
|
|
179
|
+
this->list_no = list_no_in;
|
|
180
|
+
this->coarse_dis = coarse_dis_in;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
float distance_to_code(const uint8_t* /*code*/) const override {
|
|
184
|
+
return coarse_dis;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
162
188
|
} // namespace scalar_quantizer
|
|
163
189
|
|
|
164
190
|
} // namespace faiss
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
10
|
#include <faiss/impl/ScalarQuantizer.h>
|
|
11
|
+
#include <faiss/impl/simdlib/simdlib_dispatch.h>
|
|
11
12
|
#include <faiss/utils/simd_levels.h>
|
|
12
|
-
#include <faiss/utils/simdlib.h>
|
|
13
13
|
|
|
14
14
|
namespace faiss {
|
|
15
15
|
|
|
@@ -32,7 +32,7 @@ struct SimilarityL2<SIMDLevel::NONE> {
|
|
|
32
32
|
|
|
33
33
|
const float *y, *yi;
|
|
34
34
|
|
|
35
|
-
explicit SimilarityL2(const float*
|
|
35
|
+
explicit SimilarityL2(const float* y_in) : y(y_in), yi(nullptr), accu(0) {}
|
|
36
36
|
|
|
37
37
|
/******* scalar accumulator *******/
|
|
38
38
|
|
|
@@ -70,7 +70,7 @@ struct SimilarityIP<SIMDLevel::NONE> {
|
|
|
70
70
|
|
|
71
71
|
float accu;
|
|
72
72
|
|
|
73
|
-
explicit SimilarityIP(const float*
|
|
73
|
+
explicit SimilarityIP(const float* y_in) : y(y_in), yi(nullptr), accu(0) {}
|
|
74
74
|
|
|
75
75
|
FAISS_ALWAYS_INLINE void begin() {
|
|
76
76
|
accu = 0;
|