faiss 0.3.1 → 0.3.3
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/LICENSE.txt +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +2 -2
- data/vendor/faiss/faiss/AutoTune.h +3 -3
- data/vendor/faiss/faiss/Clustering.cpp +37 -6
- data/vendor/faiss/faiss/Clustering.h +12 -3
- data/vendor/faiss/faiss/IVFlib.cpp +6 -3
- data/vendor/faiss/faiss/IVFlib.h +2 -2
- data/vendor/faiss/faiss/Index.cpp +6 -2
- data/vendor/faiss/faiss/Index.h +30 -8
- data/vendor/faiss/faiss/Index2Layer.cpp +2 -2
- data/vendor/faiss/faiss/Index2Layer.h +2 -2
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +7 -7
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +2 -2
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +14 -16
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +2 -2
- data/vendor/faiss/faiss/IndexBinary.cpp +13 -2
- data/vendor/faiss/faiss/IndexBinary.h +8 -2
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +2 -3
- data/vendor/faiss/faiss/IndexBinaryFlat.h +2 -2
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +2 -2
- data/vendor/faiss/faiss/IndexBinaryFromFloat.h +2 -2
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +2 -7
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +3 -3
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +2 -3
- data/vendor/faiss/faiss/IndexBinaryHash.h +2 -2
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +3 -3
- data/vendor/faiss/faiss/IndexBinaryIVF.h +2 -2
- data/vendor/faiss/faiss/IndexFastScan.cpp +32 -18
- data/vendor/faiss/faiss/IndexFastScan.h +11 -2
- data/vendor/faiss/faiss/IndexFlat.cpp +13 -10
- data/vendor/faiss/faiss/IndexFlat.h +2 -2
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +170 -7
- data/vendor/faiss/faiss/IndexFlatCodes.h +25 -5
- data/vendor/faiss/faiss/IndexHNSW.cpp +156 -96
- data/vendor/faiss/faiss/IndexHNSW.h +54 -5
- data/vendor/faiss/faiss/IndexIDMap.cpp +19 -3
- data/vendor/faiss/faiss/IndexIDMap.h +5 -2
- data/vendor/faiss/faiss/IndexIVF.cpp +5 -6
- data/vendor/faiss/faiss/IndexIVF.h +13 -4
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +21 -7
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +5 -2
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +3 -14
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +2 -4
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +201 -91
- data/vendor/faiss/faiss/IndexIVFFastScan.h +33 -9
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +2 -2
- data/vendor/faiss/faiss/IndexIVFFlat.h +2 -2
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +2 -2
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.h +2 -2
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +3 -6
- data/vendor/faiss/faiss/IndexIVFPQ.h +2 -2
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +7 -14
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +2 -4
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +2 -2
- data/vendor/faiss/faiss/IndexIVFPQR.h +2 -2
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +2 -3
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +2 -2
- data/vendor/faiss/faiss/IndexLSH.cpp +2 -3
- data/vendor/faiss/faiss/IndexLSH.h +2 -2
- data/vendor/faiss/faiss/IndexLattice.cpp +3 -21
- data/vendor/faiss/faiss/IndexLattice.h +5 -24
- data/vendor/faiss/faiss/IndexNNDescent.cpp +2 -31
- data/vendor/faiss/faiss/IndexNNDescent.h +3 -3
- data/vendor/faiss/faiss/IndexNSG.cpp +2 -5
- data/vendor/faiss/faiss/IndexNSG.h +3 -3
- data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +56 -0
- data/vendor/faiss/faiss/IndexNeuralNetCodec.h +49 -0
- data/vendor/faiss/faiss/IndexPQ.cpp +26 -26
- data/vendor/faiss/faiss/IndexPQ.h +2 -2
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +2 -5
- data/vendor/faiss/faiss/IndexPQFastScan.h +2 -11
- data/vendor/faiss/faiss/IndexPreTransform.cpp +2 -2
- data/vendor/faiss/faiss/IndexPreTransform.h +3 -3
- data/vendor/faiss/faiss/IndexRefine.cpp +46 -9
- data/vendor/faiss/faiss/IndexRefine.h +9 -2
- data/vendor/faiss/faiss/IndexReplicas.cpp +2 -2
- data/vendor/faiss/faiss/IndexReplicas.h +2 -2
- data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +2 -2
- data/vendor/faiss/faiss/IndexRowwiseMinMax.h +2 -2
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +5 -4
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +2 -2
- data/vendor/faiss/faiss/IndexShards.cpp +2 -2
- data/vendor/faiss/faiss/IndexShards.h +2 -2
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +2 -2
- data/vendor/faiss/faiss/IndexShardsIVF.h +2 -2
- data/vendor/faiss/faiss/MatrixStats.cpp +2 -2
- data/vendor/faiss/faiss/MatrixStats.h +2 -2
- data/vendor/faiss/faiss/MetaIndexes.cpp +2 -3
- data/vendor/faiss/faiss/MetaIndexes.h +2 -2
- data/vendor/faiss/faiss/MetricType.h +9 -4
- data/vendor/faiss/faiss/VectorTransform.cpp +2 -2
- data/vendor/faiss/faiss/VectorTransform.h +2 -2
- data/vendor/faiss/faiss/clone_index.cpp +2 -2
- data/vendor/faiss/faiss/clone_index.h +2 -2
- data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +2 -2
- data/vendor/faiss/faiss/cppcontrib/detail/CoarseBitType.h +2 -2
- data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +97 -19
- data/vendor/faiss/faiss/cppcontrib/factory_tools.cpp +192 -0
- data/vendor/faiss/faiss/cppcontrib/factory_tools.h +29 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +2 -2
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +85 -32
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +2 -2
- data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMax-inl.h +2 -2
- data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMaxFP16-inl.h +2 -2
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +2 -2
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +2 -2
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +2 -2
- data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +2 -5
- data/vendor/faiss/faiss/gpu/GpuAutoTune.h +2 -2
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +45 -13
- data/vendor/faiss/faiss/gpu/GpuCloner.h +2 -2
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +12 -6
- data/vendor/faiss/faiss/gpu/GpuDistance.h +11 -7
- data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +3 -3
- data/vendor/faiss/faiss/gpu/GpuIcmEncoder.h +2 -2
- data/vendor/faiss/faiss/gpu/GpuIndex.h +10 -15
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +2 -2
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +285 -0
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +2 -2
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +8 -2
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +4 -2
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +3 -3
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +2 -2
- data/vendor/faiss/faiss/gpu/GpuIndicesOptions.h +2 -2
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +7 -2
- data/vendor/faiss/faiss/gpu/GpuResources.h +11 -4
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +66 -11
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +15 -5
- data/vendor/faiss/faiss/gpu/impl/IndexUtils.h +2 -2
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +28 -23
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +2 -2
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +2 -2
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +2 -2
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +2 -2
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +2 -2
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +8 -2
- data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +2 -3
- data/vendor/faiss/faiss/gpu/perf/WriteIndex.cpp +2 -2
- data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +10 -7
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +2 -2
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +54 -54
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +144 -77
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +51 -51
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +2 -2
- data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +3 -3
- data/vendor/faiss/faiss/gpu/test/TestGpuResidualQuantizer.cpp +70 -0
- data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +74 -4
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +2 -2
- data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +3 -3
- data/vendor/faiss/faiss/gpu/utils/{RaftUtils.h → CuvsUtils.h} +12 -11
- data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +8 -2
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +2 -2
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.h +2 -2
- data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +2 -2
- data/vendor/faiss/faiss/gpu/utils/Timer.cpp +6 -3
- data/vendor/faiss/faiss/gpu/utils/Timer.h +3 -3
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +79 -11
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +17 -5
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +27 -2
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +11 -3
- data/vendor/faiss/faiss/impl/CodePacker.cpp +2 -2
- data/vendor/faiss/faiss/impl/CodePacker.h +2 -2
- data/vendor/faiss/faiss/impl/DistanceComputer.h +48 -2
- data/vendor/faiss/faiss/impl/FaissAssert.h +6 -4
- data/vendor/faiss/faiss/impl/FaissException.cpp +2 -2
- data/vendor/faiss/faiss/impl/FaissException.h +2 -3
- data/vendor/faiss/faiss/impl/HNSW.cpp +378 -205
- data/vendor/faiss/faiss/impl/HNSW.h +55 -24
- data/vendor/faiss/faiss/impl/IDSelector.cpp +2 -2
- data/vendor/faiss/faiss/impl/IDSelector.h +2 -2
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +10 -10
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +2 -2
- data/vendor/faiss/faiss/impl/LookupTableScaler.h +36 -2
- data/vendor/faiss/faiss/impl/NNDescent.cpp +15 -10
- data/vendor/faiss/faiss/impl/NNDescent.h +2 -2
- data/vendor/faiss/faiss/impl/NSG.cpp +26 -49
- data/vendor/faiss/faiss/impl/NSG.h +20 -8
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +2 -2
- data/vendor/faiss/faiss/impl/PolysemousTraining.h +2 -2
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +2 -4
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +2 -2
- data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +2 -2
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +3 -2
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +7 -3
- data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +2 -36
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +3 -13
- data/vendor/faiss/faiss/impl/ResultHandler.h +153 -34
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +721 -104
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +5 -2
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +2 -2
- data/vendor/faiss/faiss/impl/ThreadedIndex.h +2 -2
- data/vendor/faiss/faiss/impl/code_distance/code_distance-avx2.h +7 -2
- data/vendor/faiss/faiss/impl/code_distance/code_distance-avx512.h +248 -0
- data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +2 -2
- data/vendor/faiss/faiss/impl/code_distance/code_distance-sve.h +440 -0
- data/vendor/faiss/faiss/impl/code_distance/code_distance.h +55 -2
- data/vendor/faiss/faiss/impl/index_read.cpp +31 -20
- data/vendor/faiss/faiss/impl/index_read_utils.h +37 -0
- data/vendor/faiss/faiss/impl/index_write.cpp +30 -16
- data/vendor/faiss/faiss/impl/io.cpp +15 -7
- data/vendor/faiss/faiss/impl/io.h +6 -6
- data/vendor/faiss/faiss/impl/io_macros.h +8 -9
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +2 -3
- data/vendor/faiss/faiss/impl/kmeans1d.h +2 -2
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +2 -3
- data/vendor/faiss/faiss/impl/lattice_Zn.h +2 -2
- data/vendor/faiss/faiss/impl/platform_macros.h +34 -2
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +13 -2
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +20 -2
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +3 -3
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +450 -3
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +8 -8
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +3 -3
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +151 -67
- data/vendor/faiss/faiss/index_factory.cpp +51 -34
- data/vendor/faiss/faiss/index_factory.h +2 -2
- data/vendor/faiss/faiss/index_io.h +14 -7
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +30 -10
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +5 -2
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +11 -3
- data/vendor/faiss/faiss/invlists/DirectMap.h +2 -2
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +57 -19
- data/vendor/faiss/faiss/invlists/InvertedLists.h +20 -11
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +2 -2
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +2 -2
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +23 -9
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +4 -3
- data/vendor/faiss/faiss/python/python_callbacks.cpp +5 -5
- data/vendor/faiss/faiss/python/python_callbacks.h +2 -2
- data/vendor/faiss/faiss/utils/AlignedTable.h +5 -3
- data/vendor/faiss/faiss/utils/Heap.cpp +2 -2
- data/vendor/faiss/faiss/utils/Heap.h +107 -2
- data/vendor/faiss/faiss/utils/NeuralNet.cpp +346 -0
- data/vendor/faiss/faiss/utils/NeuralNet.h +147 -0
- data/vendor/faiss/faiss/utils/WorkerThread.cpp +2 -2
- data/vendor/faiss/faiss/utils/WorkerThread.h +2 -2
- data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +2 -2
- data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +2 -2
- data/vendor/faiss/faiss/utils/approx_topk/generic.h +2 -2
- data/vendor/faiss/faiss/utils/approx_topk/mode.h +2 -2
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +2 -2
- data/vendor/faiss/faiss/utils/bf16.h +36 -0
- data/vendor/faiss/faiss/utils/distances.cpp +249 -90
- data/vendor/faiss/faiss/utils/distances.h +8 -8
- data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +2 -2
- data/vendor/faiss/faiss/utils/distances_fused/avx512.h +2 -2
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +2 -2
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +2 -2
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +2 -2
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.h +2 -2
- data/vendor/faiss/faiss/utils/distances_simd.cpp +1543 -56
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +72 -2
- data/vendor/faiss/faiss/utils/extra_distances.cpp +87 -140
- data/vendor/faiss/faiss/utils/extra_distances.h +5 -4
- data/vendor/faiss/faiss/utils/fp16-arm.h +2 -2
- data/vendor/faiss/faiss/utils/fp16-fp16c.h +2 -2
- data/vendor/faiss/faiss/utils/fp16-inl.h +2 -2
- data/vendor/faiss/faiss/utils/fp16.h +2 -2
- data/vendor/faiss/faiss/utils/hamming-inl.h +2 -2
- data/vendor/faiss/faiss/utils/hamming.cpp +3 -4
- data/vendor/faiss/faiss/utils/hamming.h +2 -2
- data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +2 -2
- data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +490 -0
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +2 -2
- data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +6 -3
- data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +7 -3
- data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +5 -5
- data/vendor/faiss/faiss/utils/ordered_key_value.h +2 -2
- data/vendor/faiss/faiss/utils/partitioning.cpp +2 -2
- data/vendor/faiss/faiss/utils/partitioning.h +2 -2
- data/vendor/faiss/faiss/utils/prefetch.h +2 -2
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +2 -2
- data/vendor/faiss/faiss/utils/quantize_lut.h +2 -2
- data/vendor/faiss/faiss/utils/random.cpp +45 -2
- data/vendor/faiss/faiss/utils/random.h +27 -2
- data/vendor/faiss/faiss/utils/simdlib.h +12 -3
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +2 -2
- data/vendor/faiss/faiss/utils/simdlib_avx512.h +296 -0
- data/vendor/faiss/faiss/utils/simdlib_emulated.h +2 -2
- data/vendor/faiss/faiss/utils/simdlib_neon.h +7 -4
- data/vendor/faiss/faiss/utils/simdlib_ppc64.h +1084 -0
- data/vendor/faiss/faiss/utils/sorting.cpp +2 -2
- data/vendor/faiss/faiss/utils/sorting.h +2 -2
- data/vendor/faiss/faiss/utils/transpose/transpose-avx2-inl.h +2 -2
- data/vendor/faiss/faiss/utils/transpose/transpose-avx512-inl.h +176 -0
- data/vendor/faiss/faiss/utils/utils.cpp +17 -10
- data/vendor/faiss/faiss/utils/utils.h +7 -3
- metadata +22 -11
- data/vendor/faiss/faiss/impl/code_distance/code_distance_avx512.h +0 -102
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
* Copyright (c)
|
1
|
+
/*
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
3
3
|
*
|
4
4
|
* This source code is licensed under the MIT license found in the
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
@@ -23,7 +23,6 @@
|
|
23
23
|
#include <faiss/impl/pq4_fast_scan.h>
|
24
24
|
#include <faiss/impl/simd_result_handlers.h>
|
25
25
|
#include <faiss/invlists/BlockInvertedLists.h>
|
26
|
-
#include <faiss/utils/distances.h>
|
27
26
|
#include <faiss/utils/hamming.h>
|
28
27
|
#include <faiss/utils/quantize_lut.h>
|
29
28
|
#include <faiss/utils/utils.h>
|
@@ -56,20 +55,24 @@ IndexIVFFastScan::IndexIVFFastScan() {
|
|
56
55
|
}
|
57
56
|
|
58
57
|
void IndexIVFFastScan::init_fastscan(
|
58
|
+
Quantizer* fine_quantizer,
|
59
59
|
size_t M,
|
60
|
-
size_t
|
60
|
+
size_t nbits_init,
|
61
61
|
size_t nlist,
|
62
62
|
MetricType /* metric */,
|
63
|
-
int
|
64
|
-
FAISS_THROW_IF_NOT(
|
65
|
-
FAISS_THROW_IF_NOT(
|
63
|
+
int bbs_2) {
|
64
|
+
FAISS_THROW_IF_NOT(bbs_2 % 32 == 0);
|
65
|
+
FAISS_THROW_IF_NOT(nbits_init == 4);
|
66
|
+
FAISS_THROW_IF_NOT(fine_quantizer->d == d);
|
66
67
|
|
68
|
+
this->fine_quantizer = fine_quantizer;
|
67
69
|
this->M = M;
|
68
|
-
this->nbits =
|
69
|
-
this->bbs =
|
70
|
-
ksub = (1 <<
|
70
|
+
this->nbits = nbits_init;
|
71
|
+
this->bbs = bbs_2;
|
72
|
+
ksub = (1 << nbits_init);
|
71
73
|
M2 = roundup(M, 2);
|
72
74
|
code_size = M2 / 2;
|
75
|
+
FAISS_THROW_IF_NOT(code_size == fine_quantizer->code_size);
|
73
76
|
|
74
77
|
is_trained = false;
|
75
78
|
replace_invlists(new BlockInvertedLists(nlist, get_CodePacker()), true);
|
@@ -211,7 +214,7 @@ void estimators_from_tables_generic(
|
|
211
214
|
int64_t* heap_ids,
|
212
215
|
const NormTableScaler* scaler) {
|
213
216
|
using accu_t = typename C::T;
|
214
|
-
|
217
|
+
size_t nscale = scaler ? scaler->nscale : 0;
|
215
218
|
for (size_t j = 0; j < ncodes; ++j) {
|
216
219
|
BitstringReader bsr(codes + j * index.code_size, index.code_size);
|
217
220
|
accu_t dis = bias;
|
@@ -270,6 +273,7 @@ void IndexIVFFastScan::compute_LUT_uint8(
|
|
270
273
|
biases.resize(n * nprobe);
|
271
274
|
}
|
272
275
|
|
276
|
+
// OMP for MSVC requires i to have signed integral type
|
273
277
|
#pragma omp parallel for if (n > 100)
|
274
278
|
for (int64_t i = 0; i < n; i++) {
|
275
279
|
const float* t_in = dis_tables_float.get() + i * dim123;
|
@@ -306,11 +310,16 @@ void IndexIVFFastScan::search(
|
|
306
310
|
idx_t k,
|
307
311
|
float* distances,
|
308
312
|
idx_t* labels,
|
309
|
-
const SearchParameters*
|
310
|
-
|
311
|
-
|
313
|
+
const SearchParameters* params_in) const {
|
314
|
+
const IVFSearchParameters* params = nullptr;
|
315
|
+
if (params_in) {
|
316
|
+
params = dynamic_cast<const IVFSearchParameters*>(params_in);
|
317
|
+
FAISS_THROW_IF_NOT_MSG(
|
318
|
+
params, "IndexIVFFastScan params have incorrect type");
|
319
|
+
}
|
320
|
+
|
312
321
|
search_preassigned(
|
313
|
-
n, x, k, nullptr, nullptr, distances, labels, false,
|
322
|
+
n, x, k, nullptr, nullptr, distances, labels, false, params);
|
314
323
|
}
|
315
324
|
|
316
325
|
void IndexIVFFastScan::search_preassigned(
|
@@ -326,18 +335,17 @@ void IndexIVFFastScan::search_preassigned(
|
|
326
335
|
IndexIVFStats* stats) const {
|
327
336
|
size_t nprobe = this->nprobe;
|
328
337
|
if (params) {
|
329
|
-
FAISS_THROW_IF_NOT_MSG(
|
330
|
-
!params->quantizer_params, "quantizer params not supported");
|
331
338
|
FAISS_THROW_IF_NOT(params->max_codes == 0);
|
332
339
|
nprobe = params->nprobe;
|
333
340
|
}
|
341
|
+
|
334
342
|
FAISS_THROW_IF_NOT_MSG(
|
335
343
|
!store_pairs, "store_pairs not supported for this index");
|
336
344
|
FAISS_THROW_IF_NOT_MSG(!stats, "stats not supported for this index");
|
337
345
|
FAISS_THROW_IF_NOT(k > 0);
|
338
346
|
|
339
347
|
const CoarseQuantized cq = {nprobe, centroid_dis, assign};
|
340
|
-
search_dispatch_implem(n, x, k, distances, labels, cq, nullptr);
|
348
|
+
search_dispatch_implem(n, x, k, distances, labels, cq, nullptr, params);
|
341
349
|
}
|
342
350
|
|
343
351
|
void IndexIVFFastScan::range_search(
|
@@ -345,10 +353,18 @@ void IndexIVFFastScan::range_search(
|
|
345
353
|
const float* x,
|
346
354
|
float radius,
|
347
355
|
RangeSearchResult* result,
|
348
|
-
const SearchParameters*
|
349
|
-
|
356
|
+
const SearchParameters* params_in) const {
|
357
|
+
size_t nprobe = this->nprobe;
|
358
|
+
const IVFSearchParameters* params = nullptr;
|
359
|
+
if (params_in) {
|
360
|
+
params = dynamic_cast<const IVFSearchParameters*>(params_in);
|
361
|
+
FAISS_THROW_IF_NOT_MSG(
|
362
|
+
params, "IndexIVFFastScan params have incorrect type");
|
363
|
+
nprobe = params->nprobe;
|
364
|
+
}
|
365
|
+
|
350
366
|
const CoarseQuantized cq = {nprobe, nullptr, nullptr};
|
351
|
-
range_search_dispatch_implem(n, x, radius, *result, cq, nullptr);
|
367
|
+
range_search_dispatch_implem(n, x, radius, *result, cq, nullptr, params);
|
352
368
|
}
|
353
369
|
|
354
370
|
namespace {
|
@@ -359,17 +375,18 @@ ResultHandlerCompare<C, true>* make_knn_handler_fixC(
|
|
359
375
|
idx_t n,
|
360
376
|
idx_t k,
|
361
377
|
float* distances,
|
362
|
-
idx_t* labels
|
378
|
+
idx_t* labels,
|
379
|
+
const IDSelector* sel) {
|
363
380
|
using HeapHC = HeapHandler<C, true>;
|
364
381
|
using ReservoirHC = ReservoirHandler<C, true>;
|
365
382
|
using SingleResultHC = SingleResultHandler<C, true>;
|
366
383
|
|
367
384
|
if (k == 1) {
|
368
|
-
return new SingleResultHC(n, 0, distances, labels);
|
385
|
+
return new SingleResultHC(n, 0, distances, labels, sel);
|
369
386
|
} else if (impl % 2 == 0) {
|
370
|
-
return new HeapHC(n, 0, k, distances, labels);
|
387
|
+
return new HeapHC(n, 0, k, distances, labels, sel);
|
371
388
|
} else /* if (impl % 2 == 1) */ {
|
372
|
-
return new ReservoirHC(n, 0, k, 2 * k, distances, labels);
|
389
|
+
return new ReservoirHC(n, 0, k, 2 * k, distances, labels, sel);
|
373
390
|
}
|
374
391
|
}
|
375
392
|
|
@@ -379,13 +396,14 @@ SIMDResultHandlerToFloat* make_knn_handler(
|
|
379
396
|
idx_t n,
|
380
397
|
idx_t k,
|
381
398
|
float* distances,
|
382
|
-
idx_t* labels
|
399
|
+
idx_t* labels,
|
400
|
+
const IDSelector* sel) {
|
383
401
|
if (is_max) {
|
384
402
|
return make_knn_handler_fixC<CMax<uint16_t, int64_t>>(
|
385
|
-
impl, n, k, distances, labels);
|
403
|
+
impl, n, k, distances, labels, sel);
|
386
404
|
} else {
|
387
405
|
return make_knn_handler_fixC<CMin<uint16_t, int64_t>>(
|
388
|
-
impl, n, k, distances, labels);
|
406
|
+
impl, n, k, distances, labels, sel);
|
389
407
|
}
|
390
408
|
}
|
391
409
|
|
@@ -402,10 +420,20 @@ struct CoarseQuantizedWithBuffer : CoarseQuantized {
|
|
402
420
|
std::vector<idx_t> ids_buffer;
|
403
421
|
std::vector<float> dis_buffer;
|
404
422
|
|
405
|
-
void quantize(
|
423
|
+
void quantize(
|
424
|
+
const Index* quantizer,
|
425
|
+
idx_t n,
|
426
|
+
const float* x,
|
427
|
+
const SearchParameters* quantizer_params) {
|
406
428
|
dis_buffer.resize(nprobe * n);
|
407
429
|
ids_buffer.resize(nprobe * n);
|
408
|
-
quantizer->search(
|
430
|
+
quantizer->search(
|
431
|
+
n,
|
432
|
+
x,
|
433
|
+
nprobe,
|
434
|
+
dis_buffer.data(),
|
435
|
+
ids_buffer.data(),
|
436
|
+
quantizer_params);
|
409
437
|
dis = dis_buffer.data();
|
410
438
|
ids = ids_buffer.data();
|
411
439
|
}
|
@@ -421,8 +449,11 @@ struct CoarseQuantizedSlice : CoarseQuantizedWithBuffer {
|
|
421
449
|
}
|
422
450
|
}
|
423
451
|
|
424
|
-
void quantize_slice(
|
425
|
-
|
452
|
+
void quantize_slice(
|
453
|
+
const Index* quantizer,
|
454
|
+
const float* x,
|
455
|
+
const SearchParameters* quantizer_params) {
|
456
|
+
quantize(quantizer, i1 - i0, x + quantizer->d * i0, quantizer_params);
|
426
457
|
}
|
427
458
|
};
|
428
459
|
|
@@ -459,7 +490,13 @@ void IndexIVFFastScan::search_dispatch_implem(
|
|
459
490
|
float* distances,
|
460
491
|
idx_t* labels,
|
461
492
|
const CoarseQuantized& cq_in,
|
462
|
-
const NormTableScaler* scaler
|
493
|
+
const NormTableScaler* scaler,
|
494
|
+
const IVFSearchParameters* params) const {
|
495
|
+
const idx_t nprobe = params ? params->nprobe : this->nprobe;
|
496
|
+
const IDSelector* sel = (params) ? params->sel : nullptr;
|
497
|
+
const SearchParameters* quantizer_params =
|
498
|
+
params ? params->quantizer_params : nullptr;
|
499
|
+
|
463
500
|
bool is_max = !is_similarity_metric(metric_type);
|
464
501
|
using RH = SIMDResultHandlerToFloat;
|
465
502
|
|
@@ -489,52 +526,70 @@ void IndexIVFFastScan::search_dispatch_implem(
|
|
489
526
|
}
|
490
527
|
|
491
528
|
CoarseQuantizedWithBuffer cq(cq_in);
|
529
|
+
cq.nprobe = nprobe;
|
492
530
|
|
493
531
|
if (!cq.done() && !multiple_threads) {
|
494
532
|
// we do the coarse quantization here execpt when search is
|
495
533
|
// sliced over threads (then it is more efficient to have each thread do
|
496
534
|
// its own coarse quantization)
|
497
|
-
cq.quantize(quantizer, n, x);
|
535
|
+
cq.quantize(quantizer, n, x, quantizer_params);
|
536
|
+
invlists->prefetch_lists(cq.ids, n * cq.nprobe);
|
498
537
|
}
|
499
538
|
|
500
539
|
if (impl == 1) {
|
501
540
|
if (is_max) {
|
502
541
|
search_implem_1<CMax<float, int64_t>>(
|
503
|
-
n, x, k, distances, labels, cq, scaler);
|
542
|
+
n, x, k, distances, labels, cq, scaler, params);
|
504
543
|
} else {
|
505
544
|
search_implem_1<CMin<float, int64_t>>(
|
506
|
-
n, x, k, distances, labels, cq, scaler);
|
545
|
+
n, x, k, distances, labels, cq, scaler, params);
|
507
546
|
}
|
508
547
|
} else if (impl == 2) {
|
509
548
|
if (is_max) {
|
510
549
|
search_implem_2<CMax<uint16_t, int64_t>>(
|
511
|
-
n, x, k, distances, labels, cq, scaler);
|
550
|
+
n, x, k, distances, labels, cq, scaler, params);
|
512
551
|
} else {
|
513
552
|
search_implem_2<CMin<uint16_t, int64_t>>(
|
514
|
-
n, x, k, distances, labels, cq, scaler);
|
553
|
+
n, x, k, distances, labels, cq, scaler, params);
|
515
554
|
}
|
516
|
-
|
517
555
|
} else if (impl >= 10 && impl <= 15) {
|
518
556
|
size_t ndis = 0, nlist_visited = 0;
|
519
557
|
|
520
558
|
if (!multiple_threads) {
|
521
559
|
// clang-format off
|
522
560
|
if (impl == 12 || impl == 13) {
|
523
|
-
std::unique_ptr<RH> handler(
|
561
|
+
std::unique_ptr<RH> handler(
|
562
|
+
make_knn_handler(
|
563
|
+
is_max,
|
564
|
+
impl,
|
565
|
+
n,
|
566
|
+
k,
|
567
|
+
distances,
|
568
|
+
labels, sel
|
569
|
+
)
|
570
|
+
);
|
524
571
|
search_implem_12(
|
525
572
|
n, x, *handler.get(),
|
526
|
-
cq, &ndis, &nlist_visited, scaler);
|
527
|
-
|
573
|
+
cq, &ndis, &nlist_visited, scaler, params);
|
528
574
|
} else if (impl == 14 || impl == 15) {
|
529
|
-
|
530
575
|
search_implem_14(
|
531
576
|
n, x, k, distances, labels,
|
532
|
-
cq, impl, scaler);
|
577
|
+
cq, impl, scaler, params);
|
533
578
|
} else {
|
534
|
-
std::unique_ptr<RH> handler(
|
579
|
+
std::unique_ptr<RH> handler(
|
580
|
+
make_knn_handler(
|
581
|
+
is_max,
|
582
|
+
impl,
|
583
|
+
n,
|
584
|
+
k,
|
585
|
+
distances,
|
586
|
+
labels,
|
587
|
+
sel
|
588
|
+
)
|
589
|
+
);
|
535
590
|
search_implem_10(
|
536
591
|
n, x, *handler.get(), cq,
|
537
|
-
&ndis, &nlist_visited, scaler);
|
592
|
+
&ndis, &nlist_visited, scaler, params);
|
538
593
|
}
|
539
594
|
// clang-format on
|
540
595
|
} else {
|
@@ -543,7 +598,8 @@ void IndexIVFFastScan::search_dispatch_implem(
|
|
543
598
|
if (impl == 14 || impl == 15) {
|
544
599
|
// this might require slicing if there are too
|
545
600
|
// many queries (for now we keep this simple)
|
546
|
-
search_implem_14(
|
601
|
+
search_implem_14(
|
602
|
+
n, x, k, distances, labels, cq, impl, scaler, params);
|
547
603
|
} else {
|
548
604
|
#pragma omp parallel for reduction(+ : ndis, nlist_visited)
|
549
605
|
for (int slice = 0; slice < nslice; slice++) {
|
@@ -553,19 +609,19 @@ void IndexIVFFastScan::search_dispatch_implem(
|
|
553
609
|
idx_t* lab_i = labels + i0 * k;
|
554
610
|
CoarseQuantizedSlice cq_i(cq, i0, i1);
|
555
611
|
if (!cq_i.done()) {
|
556
|
-
cq_i.quantize_slice(quantizer, x);
|
612
|
+
cq_i.quantize_slice(quantizer, x, quantizer_params);
|
557
613
|
}
|
558
614
|
std::unique_ptr<RH> handler(make_knn_handler(
|
559
|
-
is_max, impl, i1 - i0, k, dis_i, lab_i));
|
615
|
+
is_max, impl, i1 - i0, k, dis_i, lab_i, sel));
|
560
616
|
// clang-format off
|
561
617
|
if (impl == 12 || impl == 13) {
|
562
618
|
search_implem_12(
|
563
619
|
i1 - i0, x + i0 * d, *handler.get(),
|
564
|
-
cq_i, &ndis, &nlist_visited, scaler);
|
620
|
+
cq_i, &ndis, &nlist_visited, scaler, params);
|
565
621
|
} else {
|
566
622
|
search_implem_10(
|
567
623
|
i1 - i0, x + i0 * d, *handler.get(),
|
568
|
-
cq_i, &ndis, &nlist_visited, scaler);
|
624
|
+
cq_i, &ndis, &nlist_visited, scaler, params);
|
569
625
|
}
|
570
626
|
// clang-format on
|
571
627
|
}
|
@@ -585,7 +641,13 @@ void IndexIVFFastScan::range_search_dispatch_implem(
|
|
585
641
|
float radius,
|
586
642
|
RangeSearchResult& rres,
|
587
643
|
const CoarseQuantized& cq_in,
|
588
|
-
const NormTableScaler* scaler
|
644
|
+
const NormTableScaler* scaler,
|
645
|
+
const IVFSearchParameters* params) const {
|
646
|
+
// const idx_t nprobe = params ? params->nprobe : this->nprobe;
|
647
|
+
const IDSelector* sel = (params) ? params->sel : nullptr;
|
648
|
+
const SearchParameters* quantizer_params =
|
649
|
+
params ? params->quantizer_params : nullptr;
|
650
|
+
|
589
651
|
bool is_max = !is_similarity_metric(metric_type);
|
590
652
|
|
591
653
|
if (n == 0) {
|
@@ -613,7 +675,8 @@ void IndexIVFFastScan::range_search_dispatch_implem(
|
|
613
675
|
}
|
614
676
|
|
615
677
|
if (!multiple_threads && !cq.done()) {
|
616
|
-
cq.quantize(quantizer, n, x);
|
678
|
+
cq.quantize(quantizer, n, x, quantizer_params);
|
679
|
+
invlists->prefetch_lists(cq.ids, n * cq.nprobe);
|
617
680
|
}
|
618
681
|
|
619
682
|
size_t ndis = 0, nlist_visited = 0;
|
@@ -622,10 +685,10 @@ void IndexIVFFastScan::range_search_dispatch_implem(
|
|
622
685
|
std::unique_ptr<SIMDResultHandlerToFloat> handler;
|
623
686
|
if (is_max) {
|
624
687
|
handler.reset(new RangeHandler<CMax<uint16_t, int64_t>, true>(
|
625
|
-
rres, radius, 0));
|
688
|
+
rres, radius, 0, sel));
|
626
689
|
} else {
|
627
690
|
handler.reset(new RangeHandler<CMin<uint16_t, int64_t>, true>(
|
628
|
-
rres, radius, 0));
|
691
|
+
rres, radius, 0, sel));
|
629
692
|
}
|
630
693
|
if (impl == 12) {
|
631
694
|
search_implem_12(
|
@@ -634,7 +697,7 @@ void IndexIVFFastScan::range_search_dispatch_implem(
|
|
634
697
|
search_implem_10(
|
635
698
|
n, x, *handler.get(), cq, &ndis, &nlist_visited, scaler);
|
636
699
|
} else {
|
637
|
-
FAISS_THROW_FMT("Range search implem %d not
|
700
|
+
FAISS_THROW_FMT("Range search implem %d not implemented", impl);
|
638
701
|
}
|
639
702
|
} else {
|
640
703
|
// explicitly slice over threads
|
@@ -649,17 +712,17 @@ void IndexIVFFastScan::range_search_dispatch_implem(
|
|
649
712
|
idx_t i1 = n * (slice + 1) / nslice;
|
650
713
|
CoarseQuantizedSlice cq_i(cq, i0, i1);
|
651
714
|
if (!cq_i.done()) {
|
652
|
-
cq_i.quantize_slice(quantizer, x);
|
715
|
+
cq_i.quantize_slice(quantizer, x, quantizer_params);
|
653
716
|
}
|
654
717
|
std::unique_ptr<SIMDResultHandlerToFloat> handler;
|
655
718
|
if (is_max) {
|
656
719
|
handler.reset(new PartialRangeHandler<
|
657
720
|
CMax<uint16_t, int64_t>,
|
658
|
-
true>(pres, radius, 0, i0, i1));
|
721
|
+
true>(pres, radius, 0, i0, i1, sel));
|
659
722
|
} else {
|
660
723
|
handler.reset(new PartialRangeHandler<
|
661
724
|
CMin<uint16_t, int64_t>,
|
662
|
-
true>(pres, radius, 0, i0, i1));
|
725
|
+
true>(pres, radius, 0, i0, i1, sel));
|
663
726
|
}
|
664
727
|
|
665
728
|
if (impl == 12 || impl == 13) {
|
@@ -670,7 +733,8 @@ void IndexIVFFastScan::range_search_dispatch_implem(
|
|
670
733
|
cq_i,
|
671
734
|
&ndis,
|
672
735
|
&nlist_visited,
|
673
|
-
scaler
|
736
|
+
scaler,
|
737
|
+
params);
|
674
738
|
} else {
|
675
739
|
search_implem_10(
|
676
740
|
i1 - i0,
|
@@ -679,7 +743,8 @@ void IndexIVFFastScan::range_search_dispatch_implem(
|
|
679
743
|
cq_i,
|
680
744
|
&ndis,
|
681
745
|
&nlist_visited,
|
682
|
-
scaler
|
746
|
+
scaler,
|
747
|
+
params);
|
683
748
|
}
|
684
749
|
}
|
685
750
|
pres.finalize();
|
@@ -699,7 +764,8 @@ void IndexIVFFastScan::search_implem_1(
|
|
699
764
|
float* distances,
|
700
765
|
idx_t* labels,
|
701
766
|
const CoarseQuantized& cq,
|
702
|
-
const NormTableScaler* scaler
|
767
|
+
const NormTableScaler* scaler,
|
768
|
+
const IVFSearchParameters* params) const {
|
703
769
|
FAISS_THROW_IF_NOT(orig_invlists);
|
704
770
|
|
705
771
|
size_t dim12 = ksub * M;
|
@@ -766,7 +832,8 @@ void IndexIVFFastScan::search_implem_2(
|
|
766
832
|
float* distances,
|
767
833
|
idx_t* labels,
|
768
834
|
const CoarseQuantized& cq,
|
769
|
-
const NormTableScaler* scaler
|
835
|
+
const NormTableScaler* scaler,
|
836
|
+
const IVFSearchParameters* params) const {
|
770
837
|
FAISS_THROW_IF_NOT(orig_invlists);
|
771
838
|
|
772
839
|
size_t dim12 = ksub * M2;
|
@@ -848,7 +915,8 @@ void IndexIVFFastScan::search_implem_10(
|
|
848
915
|
const CoarseQuantized& cq,
|
849
916
|
size_t* ndis_out,
|
850
917
|
size_t* nlist_out,
|
851
|
-
const NormTableScaler* scaler
|
918
|
+
const NormTableScaler* scaler,
|
919
|
+
const IVFSearchParameters* params) const {
|
852
920
|
size_t dim12 = ksub * M2;
|
853
921
|
AlignedTable<uint8_t> dis_tables;
|
854
922
|
AlignedTable<uint16_t> biases;
|
@@ -909,6 +977,7 @@ void IndexIVFFastScan::search_implem_10(
|
|
909
977
|
ndis++;
|
910
978
|
}
|
911
979
|
}
|
980
|
+
|
912
981
|
handler.end();
|
913
982
|
*ndis_out = ndis;
|
914
983
|
*nlist_out = nlist;
|
@@ -921,7 +990,8 @@ void IndexIVFFastScan::search_implem_12(
|
|
921
990
|
const CoarseQuantized& cq,
|
922
991
|
size_t* ndis_out,
|
923
992
|
size_t* nlist_out,
|
924
|
-
const NormTableScaler* scaler
|
993
|
+
const NormTableScaler* scaler,
|
994
|
+
const IVFSearchParameters* params) const {
|
925
995
|
if (n == 0) { // does not work well with reservoir
|
926
996
|
return;
|
927
997
|
}
|
@@ -933,6 +1003,7 @@ void IndexIVFFastScan::search_implem_12(
|
|
933
1003
|
std::unique_ptr<float[]> normalizers(new float[2 * n]);
|
934
1004
|
|
935
1005
|
compute_LUT_uint8(n, x, cq, dis_tables, biases, normalizers.get());
|
1006
|
+
|
936
1007
|
handler.begin(skip & 16 ? nullptr : normalizers.get());
|
937
1008
|
|
938
1009
|
struct QC {
|
@@ -958,13 +1029,14 @@ void IndexIVFFastScan::search_implem_12(
|
|
958
1029
|
return a.list_no < b.list_no;
|
959
1030
|
});
|
960
1031
|
}
|
1032
|
+
|
961
1033
|
// prepare the result handlers
|
962
1034
|
|
963
|
-
int
|
1035
|
+
int actual_qbs2 = this->qbs2 ? this->qbs2 : 11;
|
964
1036
|
|
965
1037
|
std::vector<uint16_t> tmp_bias;
|
966
1038
|
if (biases.get()) {
|
967
|
-
tmp_bias.resize(
|
1039
|
+
tmp_bias.resize(actual_qbs2);
|
968
1040
|
handler.dbias = tmp_bias.data();
|
969
1041
|
}
|
970
1042
|
|
@@ -977,7 +1049,7 @@ void IndexIVFFastScan::search_implem_12(
|
|
977
1049
|
int list_no = qcs[i0].list_no;
|
978
1050
|
size_t i1 = i0 + 1;
|
979
1051
|
|
980
|
-
while (i1 < qcs.size() && i1 < i0 +
|
1052
|
+
while (i1 < qcs.size() && i1 < i0 + actual_qbs2) {
|
981
1053
|
if (qcs[i1].list_no != list_no) {
|
982
1054
|
break;
|
983
1055
|
}
|
@@ -997,7 +1069,7 @@ void IndexIVFFastScan::search_implem_12(
|
|
997
1069
|
std::vector<int> q_map(nc), lut_entries(nc);
|
998
1070
|
AlignedTable<uint8_t> LUT(nc * dim12);
|
999
1071
|
memset(LUT.get(), -1, nc * dim12);
|
1000
|
-
int
|
1072
|
+
int qbs_for_list = pq4_preferred_qbs(nc);
|
1001
1073
|
|
1002
1074
|
for (size_t i = i0; i < i1; i++) {
|
1003
1075
|
const QC& qc = qcs[i];
|
@@ -1009,7 +1081,11 @@ void IndexIVFFastScan::search_implem_12(
|
|
1009
1081
|
}
|
1010
1082
|
}
|
1011
1083
|
pq4_pack_LUT_qbs_q_map(
|
1012
|
-
|
1084
|
+
qbs_for_list,
|
1085
|
+
M2,
|
1086
|
+
dis_tables.get(),
|
1087
|
+
lut_entries.data(),
|
1088
|
+
LUT.get());
|
1013
1089
|
|
1014
1090
|
// access the inverted list
|
1015
1091
|
|
@@ -1025,7 +1101,13 @@ void IndexIVFFastScan::search_implem_12(
|
|
1025
1101
|
handler.id_map = ids.get();
|
1026
1102
|
|
1027
1103
|
pq4_accumulate_loop_qbs(
|
1028
|
-
|
1104
|
+
qbs_for_list,
|
1105
|
+
list_size,
|
1106
|
+
M2,
|
1107
|
+
codes.get(),
|
1108
|
+
LUT.get(),
|
1109
|
+
handler,
|
1110
|
+
scaler);
|
1029
1111
|
// prepare for next loop
|
1030
1112
|
i0 = i1;
|
1031
1113
|
}
|
@@ -1049,12 +1131,15 @@ void IndexIVFFastScan::search_implem_14(
|
|
1049
1131
|
idx_t* labels,
|
1050
1132
|
const CoarseQuantized& cq,
|
1051
1133
|
int impl,
|
1052
|
-
const NormTableScaler* scaler
|
1134
|
+
const NormTableScaler* scaler,
|
1135
|
+
const IVFSearchParameters* params) const {
|
1053
1136
|
if (n == 0) { // does not work well with reservoir
|
1054
1137
|
return;
|
1055
1138
|
}
|
1056
1139
|
FAISS_THROW_IF_NOT(bbs == 32);
|
1057
1140
|
|
1141
|
+
const IDSelector* sel = params ? params->sel : nullptr;
|
1142
|
+
|
1058
1143
|
size_t dim12 = ksub * M2;
|
1059
1144
|
AlignedTable<uint8_t> dis_tables;
|
1060
1145
|
AlignedTable<uint16_t> biases;
|
@@ -1157,16 +1242,17 @@ void IndexIVFFastScan::search_implem_14(
|
|
1157
1242
|
|
1158
1243
|
// prepare the result handlers
|
1159
1244
|
std::unique_ptr<SIMDResultHandlerToFloat> handler(make_knn_handler(
|
1160
|
-
is_max, impl, n, k, local_dis.data(), local_idx.data()));
|
1245
|
+
is_max, impl, n, k, local_dis.data(), local_idx.data(), sel));
|
1161
1246
|
handler->begin(normalizers.get());
|
1162
1247
|
|
1163
|
-
int
|
1248
|
+
int actual_qbs2 = this->qbs2 ? this->qbs2 : 11;
|
1164
1249
|
|
1165
1250
|
std::vector<uint16_t> tmp_bias;
|
1166
1251
|
if (biases.get()) {
|
1167
|
-
tmp_bias.resize(
|
1252
|
+
tmp_bias.resize(actual_qbs2);
|
1168
1253
|
handler->dbias = tmp_bias.data();
|
1169
1254
|
}
|
1255
|
+
|
1170
1256
|
std::set<int> q_set;
|
1171
1257
|
uint64_t t_copy_pack = 0, t_scan = 0;
|
1172
1258
|
#pragma omp for schedule(dynamic)
|
@@ -1183,7 +1269,7 @@ void IndexIVFFastScan::search_implem_14(
|
|
1183
1269
|
std::vector<int> q_map(nc), lut_entries(nc);
|
1184
1270
|
AlignedTable<uint8_t> LUT(nc * dim12);
|
1185
1271
|
memset(LUT.get(), -1, nc * dim12);
|
1186
|
-
int
|
1272
|
+
int qbs_for_list = pq4_preferred_qbs(nc);
|
1187
1273
|
|
1188
1274
|
for (size_t i = i0; i < i1; i++) {
|
1189
1275
|
const QC& qc = qcs[i];
|
@@ -1196,7 +1282,11 @@ void IndexIVFFastScan::search_implem_14(
|
|
1196
1282
|
}
|
1197
1283
|
}
|
1198
1284
|
pq4_pack_LUT_qbs_q_map(
|
1199
|
-
|
1285
|
+
qbs_for_list,
|
1286
|
+
M2,
|
1287
|
+
dis_tables.get(),
|
1288
|
+
lut_entries.data(),
|
1289
|
+
LUT.get());
|
1200
1290
|
|
1201
1291
|
// access the inverted list
|
1202
1292
|
|
@@ -1212,7 +1302,7 @@ void IndexIVFFastScan::search_implem_14(
|
|
1212
1302
|
handler->id_map = ids.get();
|
1213
1303
|
|
1214
1304
|
pq4_accumulate_loop_qbs(
|
1215
|
-
|
1305
|
+
qbs_for_list,
|
1216
1306
|
list_size,
|
1217
1307
|
M2,
|
1218
1308
|
codes.get(),
|
@@ -1267,34 +1357,30 @@ void IndexIVFFastScan::reconstruct_from_offset(
|
|
1267
1357
|
int64_t offset,
|
1268
1358
|
float* recons) const {
|
1269
1359
|
// unpack codes
|
1360
|
+
size_t coarse_size = coarse_code_size();
|
1361
|
+
std::vector<uint8_t> code(coarse_size + code_size, 0);
|
1362
|
+
encode_listno(list_no, code.data());
|
1270
1363
|
InvertedLists::ScopedCodes list_codes(invlists, list_no);
|
1271
|
-
|
1272
|
-
|
1364
|
+
BitstringWriter bsw(code.data() + coarse_size, code_size);
|
1365
|
+
|
1273
1366
|
for (size_t m = 0; m < M; m++) {
|
1274
1367
|
uint8_t c =
|
1275
1368
|
pq4_get_packed_element(list_codes.get(), bbs, M2, offset, m);
|
1276
1369
|
bsw.write(c, nbits);
|
1277
1370
|
}
|
1278
|
-
sa_decode(1, code.data(), recons);
|
1279
1371
|
|
1280
|
-
|
1281
|
-
if (by_residual) {
|
1282
|
-
std::vector<float> centroid(d);
|
1283
|
-
quantizer->reconstruct(list_no, centroid.data());
|
1284
|
-
for (int i = 0; i < d; ++i) {
|
1285
|
-
recons[i] += centroid[i];
|
1286
|
-
}
|
1287
|
-
}
|
1372
|
+
sa_decode(1, code.data(), recons);
|
1288
1373
|
}
|
1289
1374
|
|
1290
1375
|
void IndexIVFFastScan::reconstruct_orig_invlists() {
|
1291
1376
|
FAISS_THROW_IF_NOT(orig_invlists != nullptr);
|
1292
1377
|
FAISS_THROW_IF_NOT(orig_invlists->list_size(0) == 0);
|
1293
1378
|
|
1294
|
-
|
1379
|
+
#pragma omp parallel for if (nlist > 100)
|
1380
|
+
for (idx_t list_no = 0; list_no < nlist; list_no++) {
|
1295
1381
|
InvertedLists::ScopedCodes codes(invlists, list_no);
|
1296
1382
|
InvertedLists::ScopedIds ids(invlists, list_no);
|
1297
|
-
size_t list_size =
|
1383
|
+
size_t list_size = invlists->list_size(list_no);
|
1298
1384
|
std::vector<uint8_t> code(code_size, 0);
|
1299
1385
|
|
1300
1386
|
for (size_t offset = 0; offset < list_size; offset++) {
|
@@ -1314,6 +1400,30 @@ void IndexIVFFastScan::reconstruct_orig_invlists() {
|
|
1314
1400
|
}
|
1315
1401
|
}
|
1316
1402
|
|
1403
|
+
void IndexIVFFastScan::sa_decode(idx_t n, const uint8_t* codes, float* x)
|
1404
|
+
const {
|
1405
|
+
size_t coarse_size = coarse_code_size();
|
1406
|
+
|
1407
|
+
#pragma omp parallel if (n > 1)
|
1408
|
+
{
|
1409
|
+
std::vector<float> residual(d);
|
1410
|
+
|
1411
|
+
#pragma omp for
|
1412
|
+
for (idx_t i = 0; i < n; i++) {
|
1413
|
+
const uint8_t* code = codes + i * (code_size + coarse_size);
|
1414
|
+
int64_t list_no = decode_listno(code);
|
1415
|
+
float* xi = x + i * d;
|
1416
|
+
fine_quantizer->decode(code + coarse_size, xi, 1);
|
1417
|
+
if (by_residual) {
|
1418
|
+
quantizer->reconstruct(list_no, residual.data());
|
1419
|
+
for (size_t j = 0; j < d; j++) {
|
1420
|
+
xi[j] += residual[j];
|
1421
|
+
}
|
1422
|
+
}
|
1423
|
+
}
|
1424
|
+
}
|
1425
|
+
}
|
1426
|
+
|
1317
1427
|
IVFFastScanStats IVFFastScan_stats;
|
1318
1428
|
|
1319
1429
|
} // namespace faiss
|