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
@@ -0,0 +1,346 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include <faiss/utils/NeuralNet.h>
|
9
|
+
|
10
|
+
#include <algorithm>
|
11
|
+
#include <cstddef>
|
12
|
+
#include <cstring>
|
13
|
+
|
14
|
+
#include <faiss/impl/FaissAssert.h>
|
15
|
+
#include <faiss/utils/distances.h>
|
16
|
+
|
17
|
+
/* declare BLAS functions, see http://www.netlib.org/clapack/cblas/ */
|
18
|
+
|
19
|
+
extern "C" {
|
20
|
+
|
21
|
+
int sgemm_(
|
22
|
+
const char* transa,
|
23
|
+
const char* transb,
|
24
|
+
FINTEGER* m,
|
25
|
+
FINTEGER* n,
|
26
|
+
FINTEGER* k,
|
27
|
+
const float* alpha,
|
28
|
+
const float* a,
|
29
|
+
FINTEGER* lda,
|
30
|
+
const float* b,
|
31
|
+
FINTEGER* ldb,
|
32
|
+
float* beta,
|
33
|
+
float* c,
|
34
|
+
FINTEGER* ldc);
|
35
|
+
}
|
36
|
+
|
37
|
+
namespace faiss {
|
38
|
+
|
39
|
+
namespace nn {
|
40
|
+
|
41
|
+
/*************************************************************
|
42
|
+
* Tensor2D implementation
|
43
|
+
*************************************************************/
|
44
|
+
|
45
|
+
template <typename T>
|
46
|
+
Tensor2DTemplate<T>::Tensor2DTemplate(size_t n0, size_t n1, const T* data_in)
|
47
|
+
: shape{n0, n1}, v(n0 * n1) {
|
48
|
+
if (data_in) {
|
49
|
+
memcpy(data(), data_in, n0 * n1 * sizeof(T));
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
template <typename T>
|
54
|
+
Tensor2DTemplate<T>& Tensor2DTemplate<T>::operator+=(
|
55
|
+
const Tensor2DTemplate<T>& other) {
|
56
|
+
FAISS_THROW_IF_NOT(shape[0] == other.shape[0]);
|
57
|
+
FAISS_THROW_IF_NOT(shape[1] == other.shape[1]);
|
58
|
+
for (size_t i = 0; i < numel(); i++) {
|
59
|
+
v[i] += other.v[i];
|
60
|
+
}
|
61
|
+
return *this;
|
62
|
+
}
|
63
|
+
|
64
|
+
template <typename T>
|
65
|
+
Tensor2DTemplate<T> Tensor2DTemplate<T>::column(size_t j) const {
|
66
|
+
size_t n = shape[0], d = shape[1];
|
67
|
+
Tensor2DTemplate<T> out(n, 1);
|
68
|
+
for (size_t i = 0; i < n; i++) {
|
69
|
+
out.v[i] = v[i * d + j];
|
70
|
+
}
|
71
|
+
return out;
|
72
|
+
}
|
73
|
+
|
74
|
+
// explicit template instanciation
|
75
|
+
template struct Tensor2DTemplate<float>;
|
76
|
+
template struct Tensor2DTemplate<int32_t>;
|
77
|
+
|
78
|
+
/*************************************************************
|
79
|
+
* Layers implementation
|
80
|
+
*************************************************************/
|
81
|
+
|
82
|
+
Linear::Linear(size_t in_features, size_t out_features, bool bias)
|
83
|
+
: in_features(in_features),
|
84
|
+
out_features(out_features),
|
85
|
+
weight(in_features * out_features) {
|
86
|
+
if (bias) {
|
87
|
+
this->bias.resize(out_features);
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
Tensor2D Linear::operator()(const Tensor2D& x) const {
|
92
|
+
FAISS_THROW_IF_NOT(x.shape[1] == in_features);
|
93
|
+
size_t n = x.shape[0];
|
94
|
+
Tensor2D output(n, out_features);
|
95
|
+
|
96
|
+
float one = 1, zero = 0;
|
97
|
+
FINTEGER nbiti = out_features, ni = n, di = in_features;
|
98
|
+
|
99
|
+
sgemm_("Transposed",
|
100
|
+
"Not transposed",
|
101
|
+
&nbiti,
|
102
|
+
&ni,
|
103
|
+
&di,
|
104
|
+
&one,
|
105
|
+
weight.data(),
|
106
|
+
&di,
|
107
|
+
x.data(),
|
108
|
+
&di,
|
109
|
+
&zero,
|
110
|
+
output.data(),
|
111
|
+
&nbiti);
|
112
|
+
|
113
|
+
if (bias.size() > 0) {
|
114
|
+
FAISS_THROW_IF_NOT(bias.size() == out_features);
|
115
|
+
for (size_t i = 0; i < n; i++) {
|
116
|
+
for (size_t j = 0; j < out_features; j++) {
|
117
|
+
output.v[i * out_features + j] += bias[j];
|
118
|
+
}
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
return output;
|
123
|
+
}
|
124
|
+
|
125
|
+
Embedding::Embedding(size_t num_embeddings, size_t embedding_dim)
|
126
|
+
: num_embeddings(num_embeddings), embedding_dim(embedding_dim) {
|
127
|
+
weight.resize(num_embeddings * embedding_dim);
|
128
|
+
}
|
129
|
+
|
130
|
+
Tensor2D Embedding::operator()(const Int32Tensor2D& code) const {
|
131
|
+
FAISS_THROW_IF_NOT(code.shape[1] == 1);
|
132
|
+
size_t n = code.shape[0];
|
133
|
+
Tensor2D output(n, embedding_dim);
|
134
|
+
for (size_t i = 0; i < n; ++i) {
|
135
|
+
size_t ci = code.v[i];
|
136
|
+
FAISS_THROW_IF_NOT(ci < num_embeddings);
|
137
|
+
memcpy(output.data() + i * embedding_dim,
|
138
|
+
weight.data() + ci * embedding_dim,
|
139
|
+
sizeof(float) * embedding_dim);
|
140
|
+
}
|
141
|
+
return output; // TODO figure out how std::move works
|
142
|
+
}
|
143
|
+
|
144
|
+
namespace {
|
145
|
+
|
146
|
+
void inplace_relu(Tensor2D& x) {
|
147
|
+
for (size_t i = 0; i < x.numel(); i++) {
|
148
|
+
x.v[i] = std::max(0.0f, x.v[i]);
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
Tensor2D concatenate_rows(const Tensor2D& x, const Tensor2D& y) {
|
153
|
+
size_t n = x.shape[0], d1 = x.shape[1], d2 = y.shape[1];
|
154
|
+
FAISS_THROW_IF_NOT(n == y.shape[0]);
|
155
|
+
Tensor2D out(n, d1 + d2);
|
156
|
+
for (size_t i = 0; i < n; i++) {
|
157
|
+
memcpy(out.data() + i * (d1 + d2),
|
158
|
+
x.data() + i * d1,
|
159
|
+
sizeof(float) * d1);
|
160
|
+
memcpy(out.data() + i * (d1 + d2) + d1,
|
161
|
+
y.data() + i * d2,
|
162
|
+
sizeof(float) * d2);
|
163
|
+
}
|
164
|
+
return out;
|
165
|
+
}
|
166
|
+
|
167
|
+
} // anonymous namespace
|
168
|
+
|
169
|
+
Tensor2D FFN::operator()(const Tensor2D& x_in) const {
|
170
|
+
Tensor2D x = linear1(x_in);
|
171
|
+
inplace_relu(x);
|
172
|
+
return linear2(x);
|
173
|
+
}
|
174
|
+
|
175
|
+
} // namespace nn
|
176
|
+
|
177
|
+
/*************************************************************
|
178
|
+
* QINCoStep implementation
|
179
|
+
*************************************************************/
|
180
|
+
|
181
|
+
using namespace nn;
|
182
|
+
|
183
|
+
QINCoStep::QINCoStep(int d, int K, int L, int h)
|
184
|
+
: d(d), K(K), L(L), h(h), codebook(K, d), MLPconcat(2 * d, d) {
|
185
|
+
for (int i = 0; i < L; i++) {
|
186
|
+
residual_blocks.emplace_back(d, h);
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
nn::Tensor2D QINCoStep::decode(
|
191
|
+
const nn::Tensor2D& xhat,
|
192
|
+
const nn::Int32Tensor2D& codes) const {
|
193
|
+
size_t n = xhat.shape[0];
|
194
|
+
FAISS_THROW_IF_NOT(n == codes.shape[0]);
|
195
|
+
Tensor2D zqs = codebook(codes);
|
196
|
+
Tensor2D cc = concatenate_rows(zqs, xhat);
|
197
|
+
zqs += MLPconcat(cc);
|
198
|
+
for (int i = 0; i < L; i++) {
|
199
|
+
zqs += residual_blocks[i](zqs);
|
200
|
+
}
|
201
|
+
return zqs;
|
202
|
+
}
|
203
|
+
|
204
|
+
nn::Int32Tensor2D QINCoStep::encode(
|
205
|
+
const nn::Tensor2D& xhat,
|
206
|
+
const nn::Tensor2D& x,
|
207
|
+
nn::Tensor2D* residuals) const {
|
208
|
+
size_t n = xhat.shape[0];
|
209
|
+
FAISS_THROW_IF_NOT(
|
210
|
+
n == x.shape[0] && xhat.shape[1] == d && x.shape[1] == d);
|
211
|
+
|
212
|
+
// repeated codebook
|
213
|
+
Tensor2D zqs_r(n * K, d); // size n, K, d
|
214
|
+
Tensor2D cc(n * K, d * 2); // size n, K, d * 2
|
215
|
+
|
216
|
+
size_t local_d = this->d;
|
217
|
+
|
218
|
+
auto copy_row =
|
219
|
+
[local_d](Tensor2D& t, size_t i, size_t j, const float* data) {
|
220
|
+
assert(i <= t.shape[0] && j <= t.shape[1]);
|
221
|
+
memcpy(t.data() + i * t.shape[1] + j,
|
222
|
+
data,
|
223
|
+
sizeof(float) * local_d);
|
224
|
+
};
|
225
|
+
|
226
|
+
// manual broadcasting
|
227
|
+
for (size_t i = 0; i < n; i++) {
|
228
|
+
for (size_t j = 0; j < K; j++) {
|
229
|
+
copy_row(zqs_r, i * K + j, 0, codebook.data() + j * d);
|
230
|
+
copy_row(cc, i * K + j, 0, codebook.data() + j * d);
|
231
|
+
copy_row(cc, i * K + j, d, xhat.data() + i * d);
|
232
|
+
}
|
233
|
+
}
|
234
|
+
|
235
|
+
zqs_r += MLPconcat(cc);
|
236
|
+
|
237
|
+
// residual blocks
|
238
|
+
for (int i = 0; i < L; i++) {
|
239
|
+
zqs_r += residual_blocks[i](zqs_r);
|
240
|
+
}
|
241
|
+
|
242
|
+
// add the xhat
|
243
|
+
for (size_t i = 0; i < n; i++) {
|
244
|
+
float* zqs_r_row = zqs_r.data() + i * K * d;
|
245
|
+
const float* xhat_row = xhat.data() + i * d;
|
246
|
+
for (size_t l = 0; l < K; l++) {
|
247
|
+
for (size_t j = 0; j < d; j++) {
|
248
|
+
zqs_r_row[j] += xhat_row[j];
|
249
|
+
}
|
250
|
+
zqs_r_row += d;
|
251
|
+
}
|
252
|
+
}
|
253
|
+
|
254
|
+
// perform assignment, finding the nearest
|
255
|
+
nn::Int32Tensor2D codes(n, 1);
|
256
|
+
float* res = nullptr;
|
257
|
+
if (residuals) {
|
258
|
+
FAISS_THROW_IF_NOT(
|
259
|
+
residuals->shape[0] == n && residuals->shape[1] == d);
|
260
|
+
res = residuals->data();
|
261
|
+
}
|
262
|
+
|
263
|
+
for (size_t i = 0; i < n; i++) {
|
264
|
+
const float* q = x.data() + i * d;
|
265
|
+
const float* db = zqs_r.data() + i * K * d;
|
266
|
+
float dis_min = HUGE_VALF;
|
267
|
+
int64_t idx = -1;
|
268
|
+
for (size_t j = 0; j < K; j++) {
|
269
|
+
float dis = fvec_L2sqr(q, db, d);
|
270
|
+
if (dis < dis_min) {
|
271
|
+
dis_min = dis;
|
272
|
+
idx = j;
|
273
|
+
}
|
274
|
+
db += d;
|
275
|
+
}
|
276
|
+
codes.v[i] = idx;
|
277
|
+
if (res) {
|
278
|
+
const float* xhat_row = xhat.data() + i * d;
|
279
|
+
const float* xhat_next_row = zqs_r.data() + (i * K + idx) * d;
|
280
|
+
for (size_t j = 0; j < d; j++) {
|
281
|
+
res[j] = xhat_next_row[j] - xhat_row[j];
|
282
|
+
}
|
283
|
+
res += d;
|
284
|
+
}
|
285
|
+
}
|
286
|
+
return codes;
|
287
|
+
}
|
288
|
+
|
289
|
+
/*************************************************************
|
290
|
+
* QINCo implementation
|
291
|
+
*************************************************************/
|
292
|
+
|
293
|
+
QINCo::QINCo(int d, int K, int L, int M, int h)
|
294
|
+
: NeuralNetCodec(d, M), K(K), L(L), h(h), codebook0(K, d) {
|
295
|
+
for (int i = 1; i < M; i++) {
|
296
|
+
steps.emplace_back(d, K, L, h);
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
300
|
+
nn::Tensor2D QINCo::decode(const nn::Int32Tensor2D& codes) const {
|
301
|
+
FAISS_THROW_IF_NOT(codes.shape[1] == M);
|
302
|
+
Tensor2D xhat = codebook0(codes.column(0));
|
303
|
+
for (int i = 1; i < M; i++) {
|
304
|
+
xhat += steps[i - 1].decode(xhat, codes.column(i));
|
305
|
+
}
|
306
|
+
return xhat;
|
307
|
+
}
|
308
|
+
|
309
|
+
nn::Int32Tensor2D QINCo::encode(const nn::Tensor2D& x) const {
|
310
|
+
FAISS_THROW_IF_NOT(x.shape[1] == d);
|
311
|
+
size_t n = x.shape[0];
|
312
|
+
Int32Tensor2D codes(n, M);
|
313
|
+
Tensor2D xhat(n, d);
|
314
|
+
{
|
315
|
+
// assign to first codebook as a batch
|
316
|
+
std::vector<float> dis(n);
|
317
|
+
std::vector<int64_t> codes64(n);
|
318
|
+
knn_L2sqr(
|
319
|
+
x.data(),
|
320
|
+
codebook0.data(),
|
321
|
+
d,
|
322
|
+
n,
|
323
|
+
K,
|
324
|
+
1,
|
325
|
+
dis.data(),
|
326
|
+
codes64.data());
|
327
|
+
for (size_t i = 0; i < n; i++) {
|
328
|
+
codes.v[i * M] = codes64[i];
|
329
|
+
memcpy(xhat.data() + i * d,
|
330
|
+
codebook0.data() + codes64[i] * d,
|
331
|
+
sizeof(float) * d);
|
332
|
+
}
|
333
|
+
}
|
334
|
+
|
335
|
+
Tensor2D toadd(n, d);
|
336
|
+
for (int i = 1; i < M; i++) {
|
337
|
+
Int32Tensor2D ci = steps[i - 1].encode(xhat, x, &toadd);
|
338
|
+
for (size_t j = 0; j < n; j++) {
|
339
|
+
codes.v[j * M + i] = ci.v[j];
|
340
|
+
}
|
341
|
+
xhat += toadd;
|
342
|
+
}
|
343
|
+
return codes;
|
344
|
+
}
|
345
|
+
|
346
|
+
} // namespace faiss
|
@@ -0,0 +1,147 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*/
|
7
|
+
|
8
|
+
/** Implements a few neural net layers, mainly to support QINCo */
|
9
|
+
|
10
|
+
#pragma once
|
11
|
+
|
12
|
+
#include <cstdint>
|
13
|
+
#include <cstdio>
|
14
|
+
#include <vector>
|
15
|
+
|
16
|
+
namespace faiss {
|
17
|
+
|
18
|
+
// the names are based on the Pytorch names (more or less)
|
19
|
+
namespace nn {
|
20
|
+
|
21
|
+
// container for intermediate steps of the neural net
|
22
|
+
template <typename T>
|
23
|
+
struct Tensor2DTemplate {
|
24
|
+
size_t shape[2];
|
25
|
+
std::vector<T> v;
|
26
|
+
|
27
|
+
Tensor2DTemplate(size_t n0, size_t n1, const T* data = nullptr);
|
28
|
+
|
29
|
+
Tensor2DTemplate& operator+=(const Tensor2DTemplate&);
|
30
|
+
|
31
|
+
/// get column #j as a 1-column Tensor2D
|
32
|
+
Tensor2DTemplate column(size_t j) const;
|
33
|
+
|
34
|
+
size_t numel() const {
|
35
|
+
return shape[0] * shape[1];
|
36
|
+
}
|
37
|
+
T* data() {
|
38
|
+
return v.data();
|
39
|
+
}
|
40
|
+
const T* data() const {
|
41
|
+
return v.data();
|
42
|
+
}
|
43
|
+
};
|
44
|
+
|
45
|
+
using Tensor2D = Tensor2DTemplate<float>;
|
46
|
+
using Int32Tensor2D = Tensor2DTemplate<int32_t>;
|
47
|
+
|
48
|
+
/// minimal translation of nn.Linear
|
49
|
+
struct Linear {
|
50
|
+
size_t in_features, out_features;
|
51
|
+
std::vector<float> weight;
|
52
|
+
std::vector<float> bias;
|
53
|
+
|
54
|
+
Linear(size_t in_features, size_t out_features, bool bias = true);
|
55
|
+
|
56
|
+
Tensor2D operator()(const Tensor2D& x) const;
|
57
|
+
};
|
58
|
+
|
59
|
+
/// minimal translation of nn.Embedding
|
60
|
+
struct Embedding {
|
61
|
+
size_t num_embeddings, embedding_dim;
|
62
|
+
std::vector<float> weight;
|
63
|
+
|
64
|
+
Embedding(size_t num_embeddings, size_t embedding_dim);
|
65
|
+
|
66
|
+
Tensor2D operator()(const Int32Tensor2D&) const;
|
67
|
+
|
68
|
+
float* data() {
|
69
|
+
return weight.data();
|
70
|
+
}
|
71
|
+
|
72
|
+
const float* data() const {
|
73
|
+
return weight.data();
|
74
|
+
}
|
75
|
+
};
|
76
|
+
|
77
|
+
/// Feed forward layer that expands to a hidden dimension, applies a ReLU non
|
78
|
+
/// linearity and maps back to the orignal dimension
|
79
|
+
struct FFN {
|
80
|
+
Linear linear1, linear2;
|
81
|
+
|
82
|
+
FFN(int d, int h) : linear1(d, h, false), linear2(h, d, false) {}
|
83
|
+
|
84
|
+
Tensor2D operator()(const Tensor2D& x) const;
|
85
|
+
};
|
86
|
+
|
87
|
+
} // namespace nn
|
88
|
+
|
89
|
+
// Translation of the QINCo implementation from
|
90
|
+
// https://github.com/facebookresearch/Qinco/blob/main/model_qinco.py
|
91
|
+
|
92
|
+
struct QINCoStep {
|
93
|
+
/// d: input dim, K: codebook size, L: # of residual blocks, h: hidden dim
|
94
|
+
int d, K, L, h;
|
95
|
+
|
96
|
+
QINCoStep(int d, int K, int L, int h);
|
97
|
+
|
98
|
+
nn::Embedding codebook;
|
99
|
+
nn::Linear MLPconcat;
|
100
|
+
std::vector<nn::FFN> residual_blocks;
|
101
|
+
|
102
|
+
nn::FFN& get_residual_block(int i) {
|
103
|
+
return residual_blocks[i];
|
104
|
+
}
|
105
|
+
|
106
|
+
/** encode a set of vectors x with intial estimate xhat. Optionally return
|
107
|
+
* the delta to be added to xhat to form the new xhat */
|
108
|
+
nn::Int32Tensor2D encode(
|
109
|
+
const nn::Tensor2D& xhat,
|
110
|
+
const nn::Tensor2D& x,
|
111
|
+
nn::Tensor2D* residuals = nullptr) const;
|
112
|
+
|
113
|
+
nn::Tensor2D decode(
|
114
|
+
const nn::Tensor2D& xhat,
|
115
|
+
const nn::Int32Tensor2D& codes) const;
|
116
|
+
};
|
117
|
+
|
118
|
+
struct NeuralNetCodec {
|
119
|
+
int d, M;
|
120
|
+
|
121
|
+
NeuralNetCodec(int d, int M) : d(d), M(M) {}
|
122
|
+
|
123
|
+
virtual nn::Tensor2D decode(const nn::Int32Tensor2D& codes) const = 0;
|
124
|
+
virtual nn::Int32Tensor2D encode(const nn::Tensor2D& x) const = 0;
|
125
|
+
|
126
|
+
virtual ~NeuralNetCodec() {}
|
127
|
+
};
|
128
|
+
|
129
|
+
struct QINCo : NeuralNetCodec {
|
130
|
+
int K, L, h;
|
131
|
+
nn::Embedding codebook0;
|
132
|
+
std::vector<QINCoStep> steps;
|
133
|
+
|
134
|
+
QINCo(int d, int K, int L, int M, int h);
|
135
|
+
|
136
|
+
QINCoStep& get_step(int i) {
|
137
|
+
return steps[i];
|
138
|
+
}
|
139
|
+
|
140
|
+
nn::Tensor2D decode(const nn::Int32Tensor2D& codes) const override;
|
141
|
+
|
142
|
+
nn::Int32Tensor2D encode(const nn::Tensor2D& x) const override;
|
143
|
+
|
144
|
+
virtual ~QINCo() {}
|
145
|
+
};
|
146
|
+
|
147
|
+
} // namespace faiss
|
@@ -0,0 +1,36 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*/
|
7
|
+
|
8
|
+
#pragma once
|
9
|
+
|
10
|
+
#include <cstdint>
|
11
|
+
|
12
|
+
namespace faiss {
|
13
|
+
|
14
|
+
namespace {
|
15
|
+
|
16
|
+
union fp32_bits {
|
17
|
+
uint32_t as_u32;
|
18
|
+
float as_f32;
|
19
|
+
};
|
20
|
+
|
21
|
+
} // namespace
|
22
|
+
|
23
|
+
inline uint16_t encode_bf16(const float f) {
|
24
|
+
// Round off
|
25
|
+
fp32_bits fp;
|
26
|
+
fp.as_f32 = f;
|
27
|
+
return static_cast<uint16_t>((fp.as_u32 + 0x8000) >> 16);
|
28
|
+
}
|
29
|
+
|
30
|
+
inline float decode_bf16(const uint16_t v) {
|
31
|
+
fp32_bits fp;
|
32
|
+
fp.as_u32 = (uint32_t(v) << 16);
|
33
|
+
return fp.as_f32;
|
34
|
+
}
|
35
|
+
|
36
|
+
} // namespace faiss
|