faiss 0.2.6 → 0.2.7
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 +4 -0
- data/ext/faiss/extconf.rb +1 -1
- data/lib/faiss/version.rb +1 -1
- data/lib/faiss.rb +2 -2
- data/vendor/faiss/faiss/AutoTune.cpp +15 -4
- data/vendor/faiss/faiss/AutoTune.h +0 -1
- data/vendor/faiss/faiss/Clustering.cpp +1 -5
- data/vendor/faiss/faiss/Clustering.h +0 -2
- data/vendor/faiss/faiss/IVFlib.h +0 -2
- data/vendor/faiss/faiss/Index.h +1 -2
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +17 -3
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +10 -1
- data/vendor/faiss/faiss/IndexBinary.h +0 -1
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +2 -1
- data/vendor/faiss/faiss/IndexBinaryFlat.h +4 -0
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +1 -3
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +273 -48
- data/vendor/faiss/faiss/IndexBinaryIVF.h +18 -11
- data/vendor/faiss/faiss/IndexFastScan.cpp +13 -10
- data/vendor/faiss/faiss/IndexFastScan.h +5 -1
- data/vendor/faiss/faiss/IndexFlat.cpp +16 -3
- data/vendor/faiss/faiss/IndexFlat.h +1 -1
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +5 -0
- data/vendor/faiss/faiss/IndexFlatCodes.h +7 -2
- data/vendor/faiss/faiss/IndexHNSW.cpp +3 -6
- data/vendor/faiss/faiss/IndexHNSW.h +0 -1
- data/vendor/faiss/faiss/IndexIDMap.cpp +4 -4
- data/vendor/faiss/faiss/IndexIDMap.h +0 -2
- data/vendor/faiss/faiss/IndexIVF.cpp +155 -129
- data/vendor/faiss/faiss/IndexIVF.h +121 -61
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +2 -2
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +12 -11
- data/vendor/faiss/faiss/IndexIVFFastScan.h +6 -1
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +221 -165
- data/vendor/faiss/faiss/IndexIVFPQ.h +1 -0
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +6 -1
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +0 -2
- data/vendor/faiss/faiss/IndexNNDescent.cpp +1 -2
- data/vendor/faiss/faiss/IndexNNDescent.h +0 -1
- data/vendor/faiss/faiss/IndexNSG.cpp +1 -2
- data/vendor/faiss/faiss/IndexPQ.cpp +7 -9
- data/vendor/faiss/faiss/IndexRefine.cpp +1 -1
- data/vendor/faiss/faiss/IndexReplicas.cpp +3 -4
- data/vendor/faiss/faiss/IndexReplicas.h +0 -1
- data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +8 -1
- data/vendor/faiss/faiss/IndexRowwiseMinMax.h +7 -0
- data/vendor/faiss/faiss/IndexShards.cpp +26 -109
- data/vendor/faiss/faiss/IndexShards.h +2 -3
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +246 -0
- data/vendor/faiss/faiss/IndexShardsIVF.h +42 -0
- data/vendor/faiss/faiss/MetaIndexes.cpp +86 -0
- data/vendor/faiss/faiss/MetaIndexes.h +29 -0
- data/vendor/faiss/faiss/MetricType.h +14 -0
- data/vendor/faiss/faiss/VectorTransform.cpp +8 -10
- data/vendor/faiss/faiss/VectorTransform.h +1 -3
- data/vendor/faiss/faiss/clone_index.cpp +232 -18
- data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +25 -3
- data/vendor/faiss/faiss/cppcontrib/detail/CoarseBitType.h +7 -0
- data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +78 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +20 -6
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +7 -1
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +21 -7
- data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMax-inl.h +7 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMaxFP16-inl.h +7 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +10 -3
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +7 -1
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +11 -3
- data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +25 -2
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +76 -29
- data/vendor/faiss/faiss/gpu/GpuCloner.h +2 -2
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +14 -13
- data/vendor/faiss/faiss/gpu/GpuDistance.h +18 -6
- data/vendor/faiss/faiss/gpu/GpuIndex.h +23 -21
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +10 -10
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +11 -12
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +29 -50
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +3 -3
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +8 -8
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +4 -4
- data/vendor/faiss/faiss/gpu/impl/IndexUtils.h +2 -5
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +9 -7
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +4 -4
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +2 -2
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +1 -1
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +55 -6
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +20 -6
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +95 -25
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +67 -16
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +4 -4
- data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +7 -7
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +4 -4
- data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +1 -1
- data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +6 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +0 -7
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +9 -9
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +1 -1
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +2 -7
- data/vendor/faiss/faiss/impl/CodePacker.cpp +67 -0
- data/vendor/faiss/faiss/impl/CodePacker.h +71 -0
- data/vendor/faiss/faiss/impl/DistanceComputer.h +0 -2
- data/vendor/faiss/faiss/impl/HNSW.cpp +3 -7
- data/vendor/faiss/faiss/impl/HNSW.h +6 -9
- data/vendor/faiss/faiss/impl/IDSelector.cpp +1 -1
- data/vendor/faiss/faiss/impl/IDSelector.h +39 -1
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +62 -51
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +11 -12
- data/vendor/faiss/faiss/impl/NNDescent.cpp +3 -9
- data/vendor/faiss/faiss/impl/NNDescent.h +10 -10
- data/vendor/faiss/faiss/impl/NSG.cpp +1 -6
- data/vendor/faiss/faiss/impl/NSG.h +4 -7
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +1 -15
- data/vendor/faiss/faiss/impl/PolysemousTraining.h +11 -10
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +0 -7
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +25 -12
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +2 -4
- data/vendor/faiss/faiss/impl/Quantizer.h +6 -3
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +796 -174
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +16 -8
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +3 -5
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +4 -4
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +3 -3
- data/vendor/faiss/faiss/impl/ThreadedIndex.h +4 -4
- data/vendor/faiss/faiss/impl/code_distance/code_distance-avx2.h +291 -0
- data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +74 -0
- data/vendor/faiss/faiss/impl/code_distance/code_distance.h +123 -0
- data/vendor/faiss/faiss/impl/code_distance/code_distance_avx512.h +102 -0
- data/vendor/faiss/faiss/impl/index_read.cpp +13 -10
- data/vendor/faiss/faiss/impl/index_write.cpp +3 -4
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +0 -1
- data/vendor/faiss/faiss/impl/kmeans1d.h +3 -3
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +1 -1
- data/vendor/faiss/faiss/impl/platform_macros.h +61 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +48 -4
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +18 -4
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +2 -2
- data/vendor/faiss/faiss/index_factory.cpp +8 -10
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +29 -12
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +8 -2
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -1
- data/vendor/faiss/faiss/invlists/DirectMap.h +2 -4
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +118 -18
- data/vendor/faiss/faiss/invlists/InvertedLists.h +44 -4
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +3 -3
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
- data/vendor/faiss/faiss/python/python_callbacks.cpp +1 -1
- data/vendor/faiss/faiss/python/python_callbacks.h +1 -1
- data/vendor/faiss/faiss/utils/AlignedTable.h +3 -1
- data/vendor/faiss/faiss/utils/Heap.cpp +139 -3
- data/vendor/faiss/faiss/utils/Heap.h +35 -1
- data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +84 -0
- data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +196 -0
- data/vendor/faiss/faiss/utils/approx_topk/generic.h +138 -0
- data/vendor/faiss/faiss/utils/approx_topk/mode.h +34 -0
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +367 -0
- data/vendor/faiss/faiss/utils/distances.cpp +61 -7
- data/vendor/faiss/faiss/utils/distances.h +11 -0
- data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +346 -0
- data/vendor/faiss/faiss/utils/distances_fused/avx512.h +36 -0
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +42 -0
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +40 -0
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +352 -0
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.h +32 -0
- data/vendor/faiss/faiss/utils/distances_simd.cpp +515 -327
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +17 -1
- data/vendor/faiss/faiss/utils/extra_distances.cpp +37 -8
- data/vendor/faiss/faiss/utils/extra_distances.h +2 -1
- data/vendor/faiss/faiss/utils/fp16-fp16c.h +7 -0
- data/vendor/faiss/faiss/utils/fp16-inl.h +7 -0
- data/vendor/faiss/faiss/utils/fp16.h +7 -0
- data/vendor/faiss/faiss/utils/hamming-inl.h +0 -456
- data/vendor/faiss/faiss/utils/hamming.cpp +104 -120
- data/vendor/faiss/faiss/utils/hamming.h +21 -10
- data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +535 -0
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +48 -0
- data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +519 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +26 -0
- data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +614 -0
- data/vendor/faiss/faiss/utils/partitioning.cpp +21 -25
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +344 -3
- data/vendor/faiss/faiss/utils/simdlib_emulated.h +390 -0
- data/vendor/faiss/faiss/utils/simdlib_neon.h +655 -130
- data/vendor/faiss/faiss/utils/sorting.cpp +692 -0
- data/vendor/faiss/faiss/utils/sorting.h +71 -0
- data/vendor/faiss/faiss/utils/transpose/transpose-avx2-inl.h +165 -0
- data/vendor/faiss/faiss/utils/utils.cpp +4 -176
- data/vendor/faiss/faiss/utils/utils.h +2 -9
- metadata +29 -3
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.cpp +0 -26
|
@@ -135,7 +135,7 @@ int dgesvd_(
|
|
|
135
135
|
* VectorTransform
|
|
136
136
|
*********************************************/
|
|
137
137
|
|
|
138
|
-
float* VectorTransform::apply(
|
|
138
|
+
float* VectorTransform::apply(idx_t n, const float* x) const {
|
|
139
139
|
float* xt = new float[n * d_out];
|
|
140
140
|
apply_noalloc(n, x, xt);
|
|
141
141
|
return xt;
|
|
@@ -166,8 +166,7 @@ LinearTransform::LinearTransform(int d_in, int d_out, bool have_bias)
|
|
|
166
166
|
is_trained = false; // will be trained when A and b are initialized
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
void LinearTransform::apply_noalloc(
|
|
170
|
-
const {
|
|
169
|
+
void LinearTransform::apply_noalloc(idx_t n, const float* x, float* xt) const {
|
|
171
170
|
FAISS_THROW_IF_NOT_MSG(is_trained, "Transformation not trained yet");
|
|
172
171
|
|
|
173
172
|
float c_factor;
|
|
@@ -348,7 +347,7 @@ void RandomRotationMatrix::init(int seed) {
|
|
|
348
347
|
is_trained = true;
|
|
349
348
|
}
|
|
350
349
|
|
|
351
|
-
void RandomRotationMatrix::train(
|
|
350
|
+
void RandomRotationMatrix::train(idx_t /*n*/, const float* /*x*/) {
|
|
352
351
|
// initialize with some arbitrary seed
|
|
353
352
|
init(12345);
|
|
354
353
|
}
|
|
@@ -442,7 +441,7 @@ void eig(size_t d_in, double* cov, double* eigenvalues, int verbose) {
|
|
|
442
441
|
|
|
443
442
|
} // namespace
|
|
444
443
|
|
|
445
|
-
void PCAMatrix::train(
|
|
444
|
+
void PCAMatrix::train(idx_t n, const float* x) {
|
|
446
445
|
const float* x_in = x;
|
|
447
446
|
|
|
448
447
|
x = fvecs_maybe_subsample(
|
|
@@ -733,7 +732,7 @@ ITQMatrix::ITQMatrix(int d)
|
|
|
733
732
|
: LinearTransform(d, d, false), max_iter(50), seed(123) {}
|
|
734
733
|
|
|
735
734
|
/** translated from fbcode/deeplearning/catalyzer/catalyzer/quantizers.py */
|
|
736
|
-
void ITQMatrix::train(
|
|
735
|
+
void ITQMatrix::train(idx_t n, const float* xf) {
|
|
737
736
|
size_t d = d_in;
|
|
738
737
|
std::vector<double> rotation(d * d);
|
|
739
738
|
|
|
@@ -957,8 +956,7 @@ void ITQTransform::train(idx_t n, const float* x) {
|
|
|
957
956
|
is_trained = true;
|
|
958
957
|
}
|
|
959
958
|
|
|
960
|
-
void ITQTransform::apply_noalloc(
|
|
961
|
-
const {
|
|
959
|
+
void ITQTransform::apply_noalloc(idx_t n, const float* x, float* xt) const {
|
|
962
960
|
FAISS_THROW_IF_NOT_MSG(is_trained, "Transformation not trained yet");
|
|
963
961
|
|
|
964
962
|
std::unique_ptr<float[]> x_norm(new float[n * d_in]);
|
|
@@ -1003,7 +1001,7 @@ OPQMatrix::OPQMatrix(int d, int M, int d2)
|
|
|
1003
1001
|
pq = nullptr;
|
|
1004
1002
|
}
|
|
1005
1003
|
|
|
1006
|
-
void OPQMatrix::train(
|
|
1004
|
+
void OPQMatrix::train(idx_t n, const float* x) {
|
|
1007
1005
|
const float* x_in = x;
|
|
1008
1006
|
|
|
1009
1007
|
x = fvecs_maybe_subsample(d_in, (size_t*)&n, max_train_points, x, verbose);
|
|
@@ -1261,7 +1259,7 @@ CenteringTransform::CenteringTransform(int d) : VectorTransform(d, d) {
|
|
|
1261
1259
|
is_trained = false;
|
|
1262
1260
|
}
|
|
1263
1261
|
|
|
1264
|
-
void CenteringTransform::train(
|
|
1262
|
+
void CenteringTransform::train(idx_t n, const float* x) {
|
|
1265
1263
|
FAISS_THROW_IF_NOT_MSG(n > 0, "need at least one training vector");
|
|
1266
1264
|
mean.resize(d_in, 0);
|
|
1267
1265
|
for (idx_t i = 0; i < n; i++) {
|
|
@@ -23,8 +23,6 @@ namespace faiss {
|
|
|
23
23
|
|
|
24
24
|
/** Any transformation applied on a set of vectors */
|
|
25
25
|
struct VectorTransform {
|
|
26
|
-
typedef Index::idx_t idx_t;
|
|
27
|
-
|
|
28
26
|
int d_in; ///! input dimension
|
|
29
27
|
int d_out; ///! output dimension
|
|
30
28
|
|
|
@@ -122,7 +120,7 @@ struct RandomRotationMatrix : LinearTransform {
|
|
|
122
120
|
/// must be called before the transform is used
|
|
123
121
|
void init(int seed);
|
|
124
122
|
|
|
125
|
-
//
|
|
123
|
+
// initializes with an arbitrary seed
|
|
126
124
|
void train(idx_t n, const float* x) override;
|
|
127
125
|
|
|
128
126
|
RandomRotationMatrix() {}
|
|
@@ -16,18 +16,24 @@
|
|
|
16
16
|
|
|
17
17
|
#include <faiss/Index2Layer.h>
|
|
18
18
|
#include <faiss/IndexAdditiveQuantizer.h>
|
|
19
|
+
#include <faiss/IndexAdditiveQuantizerFastScan.h>
|
|
19
20
|
#include <faiss/IndexFlat.h>
|
|
20
21
|
#include <faiss/IndexHNSW.h>
|
|
21
22
|
#include <faiss/IndexIVF.h>
|
|
23
|
+
#include <faiss/IndexIVFAdditiveQuantizerFastScan.h>
|
|
22
24
|
#include <faiss/IndexIVFFlat.h>
|
|
23
25
|
#include <faiss/IndexIVFPQ.h>
|
|
26
|
+
#include <faiss/IndexIVFPQFastScan.h>
|
|
24
27
|
#include <faiss/IndexIVFPQR.h>
|
|
25
28
|
#include <faiss/IndexIVFSpectralHash.h>
|
|
26
29
|
#include <faiss/IndexLSH.h>
|
|
27
30
|
#include <faiss/IndexLattice.h>
|
|
28
31
|
#include <faiss/IndexNSG.h>
|
|
29
32
|
#include <faiss/IndexPQ.h>
|
|
33
|
+
#include <faiss/IndexPQFastScan.h>
|
|
30
34
|
#include <faiss/IndexPreTransform.h>
|
|
35
|
+
#include <faiss/IndexRefine.h>
|
|
36
|
+
#include <faiss/IndexRowwiseMinMax.h>
|
|
31
37
|
#include <faiss/IndexScalarQuantizer.h>
|
|
32
38
|
#include <faiss/MetaIndexes.h>
|
|
33
39
|
#include <faiss/VectorTransform.h>
|
|
@@ -36,6 +42,9 @@
|
|
|
36
42
|
#include <faiss/impl/ProductQuantizer.h>
|
|
37
43
|
#include <faiss/impl/ResidualQuantizer.h>
|
|
38
44
|
#include <faiss/impl/ScalarQuantizer.h>
|
|
45
|
+
#include <faiss/impl/pq4_fast_scan.h>
|
|
46
|
+
|
|
47
|
+
#include <faiss/invlists/BlockInvertedLists.h>
|
|
39
48
|
|
|
40
49
|
namespace faiss {
|
|
41
50
|
|
|
@@ -71,39 +80,220 @@ VectorTransform* Cloner::clone_VectorTransform(const VectorTransform* vt) {
|
|
|
71
80
|
IndexIVF* Cloner::clone_IndexIVF(const IndexIVF* ivf) {
|
|
72
81
|
TRYCLONE(IndexIVFPQR, ivf)
|
|
73
82
|
TRYCLONE(IndexIVFPQ, ivf)
|
|
83
|
+
|
|
84
|
+
TRYCLONE(IndexIVFLocalSearchQuantizer, ivf)
|
|
85
|
+
TRYCLONE(IndexIVFProductLocalSearchQuantizer, ivf)
|
|
86
|
+
TRYCLONE(IndexIVFProductResidualQuantizer, ivf)
|
|
87
|
+
TRYCLONE(IndexIVFResidualQuantizer, ivf)
|
|
88
|
+
|
|
89
|
+
TRYCLONE(IndexIVFLocalSearchQuantizerFastScan, ivf)
|
|
90
|
+
TRYCLONE(IndexIVFProductLocalSearchQuantizerFastScan, ivf)
|
|
91
|
+
TRYCLONE(IndexIVFProductResidualQuantizerFastScan, ivf)
|
|
92
|
+
TRYCLONE(IndexIVFResidualQuantizerFastScan, ivf)
|
|
93
|
+
TRYCLONE(IndexIVFPQFastScan, ivf)
|
|
94
|
+
|
|
95
|
+
TRYCLONE(IndexIVFFlatDedup, ivf)
|
|
74
96
|
TRYCLONE(IndexIVFFlat, ivf)
|
|
97
|
+
|
|
98
|
+
TRYCLONE(IndexIVFSpectralHash, ivf)
|
|
99
|
+
|
|
75
100
|
TRYCLONE(IndexIVFScalarQuantizer, ivf) {
|
|
76
101
|
FAISS_THROW_MSG("clone not supported for this type of IndexIVF");
|
|
77
102
|
}
|
|
78
103
|
return nullptr;
|
|
79
104
|
}
|
|
80
105
|
|
|
106
|
+
IndexRefine* clone_IndexRefine(const IndexRefine* ir) {
|
|
107
|
+
TRYCLONE(IndexRefineFlat, ir)
|
|
108
|
+
TRYCLONE(IndexRefine, ir) {
|
|
109
|
+
FAISS_THROW_MSG("clone not supported for this type of IndexRefine");
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
IndexIDMap* clone_IndexIDMap(const IndexIDMap* im) {
|
|
114
|
+
TRYCLONE(IndexIDMap2, im)
|
|
115
|
+
TRYCLONE(IndexIDMap, im) {
|
|
116
|
+
FAISS_THROW_MSG("clone not supported for this type of IndexIDMap");
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
IndexHNSW* clone_IndexHNSW(const IndexHNSW* ihnsw) {
|
|
121
|
+
TRYCLONE(IndexHNSW2Level, ihnsw)
|
|
122
|
+
TRYCLONE(IndexHNSWFlat, ihnsw)
|
|
123
|
+
TRYCLONE(IndexHNSWPQ, ihnsw)
|
|
124
|
+
TRYCLONE(IndexHNSWSQ, ihnsw)
|
|
125
|
+
TRYCLONE(IndexHNSW, ihnsw) {
|
|
126
|
+
FAISS_THROW_MSG("clone not supported for this type of IndexHNSW");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
IndexNNDescent* clone_IndexNNDescent(const IndexNNDescent* innd) {
|
|
131
|
+
TRYCLONE(IndexNNDescentFlat, innd)
|
|
132
|
+
TRYCLONE(IndexNNDescent, innd) {
|
|
133
|
+
FAISS_THROW_MSG("clone not supported for this type of IndexNNDescent");
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
IndexNSG* clone_IndexNSG(const IndexNSG* insg) {
|
|
138
|
+
TRYCLONE(IndexNSGFlat, insg)
|
|
139
|
+
TRYCLONE(IndexNSGPQ, insg)
|
|
140
|
+
TRYCLONE(IndexNSGSQ, insg)
|
|
141
|
+
TRYCLONE(IndexNSG, insg) {
|
|
142
|
+
FAISS_THROW_MSG("clone not supported for this type of IndexNNDescent");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
IndexRowwiseMinMaxBase* clone_IndexRowwiseMinMax(
|
|
147
|
+
const IndexRowwiseMinMaxBase* irmmb) {
|
|
148
|
+
TRYCLONE(IndexRowwiseMinMaxFP16, irmmb)
|
|
149
|
+
TRYCLONE(IndexRowwiseMinMax, irmmb) {
|
|
150
|
+
FAISS_THROW_MSG(
|
|
151
|
+
"clone not supported for this type of IndexRowwiseMinMax");
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
#define TRYCAST(classname) classname* res = dynamic_cast<classname*>(index)
|
|
156
|
+
|
|
157
|
+
void reset_AdditiveQuantizerIndex(Index* index) {
|
|
158
|
+
auto clone_ProductQuantizers =
|
|
159
|
+
[](std::vector<AdditiveQuantizer*>& quantizers) {
|
|
160
|
+
for (auto& q : quantizers) {
|
|
161
|
+
q = dynamic_cast<AdditiveQuantizer*>(clone_Quantizer(q));
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
if (TRYCAST(IndexIVFLocalSearchQuantizerFastScan)) {
|
|
165
|
+
res->aq = &res->lsq;
|
|
166
|
+
} else if (TRYCAST(IndexIVFResidualQuantizerFastScan)) {
|
|
167
|
+
res->aq = &res->rq;
|
|
168
|
+
} else if (TRYCAST(IndexIVFProductLocalSearchQuantizerFastScan)) {
|
|
169
|
+
res->aq = &res->plsq;
|
|
170
|
+
clone_ProductQuantizers(res->plsq.quantizers);
|
|
171
|
+
} else if (TRYCAST(IndexIVFProductResidualQuantizerFastScan)) {
|
|
172
|
+
res->aq = &res->prq;
|
|
173
|
+
clone_ProductQuantizers(res->prq.quantizers);
|
|
174
|
+
} else if (TRYCAST(IndexIVFLocalSearchQuantizer)) {
|
|
175
|
+
res->aq = &res->lsq;
|
|
176
|
+
} else if (TRYCAST(IndexIVFResidualQuantizer)) {
|
|
177
|
+
res->aq = &res->rq;
|
|
178
|
+
} else if (TRYCAST(IndexIVFProductLocalSearchQuantizer)) {
|
|
179
|
+
res->aq = &res->plsq;
|
|
180
|
+
clone_ProductQuantizers(res->plsq.quantizers);
|
|
181
|
+
} else if (TRYCAST(IndexIVFProductResidualQuantizer)) {
|
|
182
|
+
res->aq = &res->prq;
|
|
183
|
+
clone_ProductQuantizers(res->prq.quantizers);
|
|
184
|
+
} else if (TRYCAST(IndexLocalSearchQuantizerFastScan)) {
|
|
185
|
+
res->aq = &res->lsq;
|
|
186
|
+
} else if (TRYCAST(IndexResidualQuantizerFastScan)) {
|
|
187
|
+
res->aq = &res->rq;
|
|
188
|
+
} else if (TRYCAST(IndexProductLocalSearchQuantizerFastScan)) {
|
|
189
|
+
res->aq = &res->plsq;
|
|
190
|
+
clone_ProductQuantizers(res->plsq.quantizers);
|
|
191
|
+
} else if (TRYCAST(IndexProductResidualQuantizerFastScan)) {
|
|
192
|
+
res->aq = &res->prq;
|
|
193
|
+
clone_ProductQuantizers(res->prq.quantizers);
|
|
194
|
+
} else if (TRYCAST(IndexLocalSearchQuantizer)) {
|
|
195
|
+
res->aq = &res->lsq;
|
|
196
|
+
} else if (TRYCAST(IndexResidualQuantizer)) {
|
|
197
|
+
res->aq = &res->rq;
|
|
198
|
+
} else if (TRYCAST(IndexProductLocalSearchQuantizer)) {
|
|
199
|
+
res->aq = &res->plsq;
|
|
200
|
+
clone_ProductQuantizers(res->plsq.quantizers);
|
|
201
|
+
} else if (TRYCAST(IndexProductResidualQuantizer)) {
|
|
202
|
+
res->aq = &res->prq;
|
|
203
|
+
clone_ProductQuantizers(res->prq.quantizers);
|
|
204
|
+
} else if (TRYCAST(LocalSearchCoarseQuantizer)) {
|
|
205
|
+
res->aq = &res->lsq;
|
|
206
|
+
} else if (TRYCAST(ResidualCoarseQuantizer)) {
|
|
207
|
+
res->aq = &res->rq;
|
|
208
|
+
} else {
|
|
209
|
+
FAISS_THROW_MSG(
|
|
210
|
+
"clone not supported for this type of additive quantizer index");
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
Index* clone_AdditiveQuantizerIndex(const Index* index) {
|
|
215
|
+
// IndexAdditiveQuantizer
|
|
216
|
+
TRYCLONE(IndexResidualQuantizer, index)
|
|
217
|
+
TRYCLONE(IndexProductResidualQuantizer, index)
|
|
218
|
+
TRYCLONE(IndexLocalSearchQuantizer, index)
|
|
219
|
+
TRYCLONE(IndexProductLocalSearchQuantizer, index)
|
|
220
|
+
|
|
221
|
+
// IndexFastScan
|
|
222
|
+
TRYCLONE(IndexResidualQuantizerFastScan, index)
|
|
223
|
+
TRYCLONE(IndexLocalSearchQuantizerFastScan, index)
|
|
224
|
+
TRYCLONE(IndexProductResidualQuantizerFastScan, index)
|
|
225
|
+
TRYCLONE(IndexProductLocalSearchQuantizerFastScan, index)
|
|
226
|
+
|
|
227
|
+
// AdditiveCoarseQuantizer
|
|
228
|
+
TRYCLONE(ResidualCoarseQuantizer, index)
|
|
229
|
+
TRYCLONE(LocalSearchCoarseQuantizer, index) {
|
|
230
|
+
FAISS_THROW_MSG(
|
|
231
|
+
"clone not supported for this type of additive quantizer index");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
namespace {
|
|
236
|
+
|
|
237
|
+
IndexHNSW* clone_HNSW(const IndexHNSW* ihnsw) {
|
|
238
|
+
TRYCLONE(IndexHNSWFlat, ihnsw)
|
|
239
|
+
TRYCLONE(IndexHNSWPQ, ihnsw)
|
|
240
|
+
TRYCLONE(IndexHNSWSQ, ihnsw)
|
|
241
|
+
return new IndexHNSW(*ihnsw);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
InvertedLists* clone_InvertedLists(const InvertedLists* invlists) {
|
|
245
|
+
if (auto* ails = dynamic_cast<const ArrayInvertedLists*>(invlists)) {
|
|
246
|
+
return new ArrayInvertedLists(*ails);
|
|
247
|
+
}
|
|
248
|
+
if (auto* bils = dynamic_cast<const BlockInvertedLists*>(invlists)) {
|
|
249
|
+
auto* bils2 = new BlockInvertedLists(*bils);
|
|
250
|
+
if (bils->packer) {
|
|
251
|
+
auto* packerPQ4 = dynamic_cast<const CodePackerPQ4*>(bils->packer);
|
|
252
|
+
FAISS_THROW_IF_NOT(packerPQ4);
|
|
253
|
+
bils2->packer = new CodePackerPQ4(*packerPQ4);
|
|
254
|
+
}
|
|
255
|
+
return bils2;
|
|
256
|
+
}
|
|
257
|
+
FAISS_THROW_FMT(
|
|
258
|
+
"clone not supported for this type of inverted lists %s",
|
|
259
|
+
typeid(*invlists).name());
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
} // anonymous namespace
|
|
263
|
+
|
|
81
264
|
Index* Cloner::clone_Index(const Index* index) {
|
|
82
265
|
TRYCLONE(IndexPQ, index)
|
|
83
266
|
TRYCLONE(IndexLSH, index)
|
|
267
|
+
|
|
268
|
+
// IndexFlat
|
|
269
|
+
TRYCLONE(IndexFlat1D, index)
|
|
84
270
|
TRYCLONE(IndexFlatL2, index)
|
|
85
271
|
TRYCLONE(IndexFlatIP, index)
|
|
86
272
|
TRYCLONE(IndexFlat, index)
|
|
273
|
+
|
|
87
274
|
TRYCLONE(IndexLattice, index)
|
|
88
|
-
TRYCLONE(
|
|
275
|
+
TRYCLONE(IndexRandom, index)
|
|
276
|
+
TRYCLONE(IndexPQFastScan, index)
|
|
277
|
+
|
|
89
278
|
TRYCLONE(IndexScalarQuantizer, index)
|
|
90
279
|
TRYCLONE(MultiIndexQuantizer, index)
|
|
91
|
-
|
|
280
|
+
|
|
92
281
|
if (const IndexIVF* ivf = dynamic_cast<const IndexIVF*>(index)) {
|
|
93
282
|
IndexIVF* res = clone_IndexIVF(ivf);
|
|
94
283
|
if (ivf->invlists == nullptr) {
|
|
95
284
|
res->invlists = nullptr;
|
|
96
|
-
} else if (
|
|
97
|
-
auto* ails = dynamic_cast<const ArrayInvertedLists*>(
|
|
98
|
-
ivf->invlists)) {
|
|
99
|
-
res->invlists = new ArrayInvertedLists(*ails);
|
|
100
|
-
res->own_invlists = true;
|
|
101
285
|
} else {
|
|
102
|
-
|
|
103
|
-
|
|
286
|
+
res->invlists = clone_InvertedLists(ivf->invlists);
|
|
287
|
+
res->own_invlists = true;
|
|
104
288
|
}
|
|
289
|
+
|
|
105
290
|
res->own_fields = true;
|
|
106
291
|
res->quantizer = clone_Index(ivf->quantizer);
|
|
292
|
+
|
|
293
|
+
if (dynamic_cast<const IndexIVFAdditiveQuantizerFastScan*>(res) ||
|
|
294
|
+
dynamic_cast<const IndexIVFAdditiveQuantizer*>(res)) {
|
|
295
|
+
reset_AdditiveQuantizerIndex(res);
|
|
296
|
+
}
|
|
107
297
|
return res;
|
|
108
298
|
} else if (
|
|
109
299
|
const IndexPreTransform* ipt =
|
|
@@ -122,19 +312,18 @@ Index* Cloner::clone_Index(const Index* index) {
|
|
|
122
312
|
return res;
|
|
123
313
|
} else if (
|
|
124
314
|
const IndexIDMap* idmap = dynamic_cast<const IndexIDMap*>(index)) {
|
|
125
|
-
|
|
126
|
-
IndexIDMap* res =
|
|
127
|
-
idmap2 ? new IndexIDMap2(*idmap2) : new IndexIDMap(*idmap);
|
|
315
|
+
IndexIDMap* res = clone_IndexIDMap(idmap);
|
|
128
316
|
res->own_fields = true;
|
|
129
317
|
res->index = clone_Index(idmap->index);
|
|
130
318
|
return res;
|
|
131
319
|
} else if (const IndexHNSW* ihnsw = dynamic_cast<const IndexHNSW*>(index)) {
|
|
132
|
-
IndexHNSW* res =
|
|
320
|
+
IndexHNSW* res = clone_IndexHNSW(ihnsw);
|
|
133
321
|
res->own_fields = true;
|
|
134
|
-
|
|
322
|
+
// make sure we don't get a GPU index here
|
|
323
|
+
res->storage = Cloner::clone_Index(ihnsw->storage);
|
|
135
324
|
return res;
|
|
136
325
|
} else if (const IndexNSG* insg = dynamic_cast<const IndexNSG*>(index)) {
|
|
137
|
-
IndexNSG* res =
|
|
326
|
+
IndexNSG* res = clone_IndexNSG(insg);
|
|
138
327
|
|
|
139
328
|
// copy the dynamic allocated graph
|
|
140
329
|
auto& new_graph = res->nsg.final_graph;
|
|
@@ -147,7 +336,7 @@ Index* Cloner::clone_Index(const Index* index) {
|
|
|
147
336
|
} else if (
|
|
148
337
|
const IndexNNDescent* innd =
|
|
149
338
|
dynamic_cast<const IndexNNDescent*>(index)) {
|
|
150
|
-
IndexNNDescent* res =
|
|
339
|
+
IndexNNDescent* res = clone_IndexNNDescent(innd);
|
|
151
340
|
res->own_fields = true;
|
|
152
341
|
res->storage = clone_Index(innd->storage);
|
|
153
342
|
return res;
|
|
@@ -157,11 +346,36 @@ Index* Cloner::clone_Index(const Index* index) {
|
|
|
157
346
|
res->q1.own_fields = true;
|
|
158
347
|
res->q1.quantizer = clone_Index(i2l->q1.quantizer);
|
|
159
348
|
return res;
|
|
349
|
+
} else if (
|
|
350
|
+
const IndexRefine* ir = dynamic_cast<const IndexRefine*>(index)) {
|
|
351
|
+
IndexRefine* res = clone_IndexRefine(ir);
|
|
352
|
+
res->own_fields = true;
|
|
353
|
+
res->base_index = clone_Index(ir->base_index);
|
|
354
|
+
if (ir->refine_index != nullptr) {
|
|
355
|
+
res->own_refine_index = true;
|
|
356
|
+
res->refine_index = clone_Index(ir->refine_index);
|
|
357
|
+
}
|
|
358
|
+
return res;
|
|
359
|
+
} else if (
|
|
360
|
+
const IndexRowwiseMinMaxBase* irmmb =
|
|
361
|
+
dynamic_cast<const IndexRowwiseMinMaxBase*>(index)) {
|
|
362
|
+
IndexRowwiseMinMaxBase* res = clone_IndexRowwiseMinMax(irmmb);
|
|
363
|
+
res->own_fields = true;
|
|
364
|
+
res->index = clone_Index(irmmb->index);
|
|
365
|
+
} else if (
|
|
366
|
+
dynamic_cast<const IndexAdditiveQuantizerFastScan*>(index) ||
|
|
367
|
+
dynamic_cast<const IndexAdditiveQuantizer*>(index) ||
|
|
368
|
+
dynamic_cast<const AdditiveCoarseQuantizer*>(index)) {
|
|
369
|
+
Index* res = clone_AdditiveQuantizerIndex(index);
|
|
370
|
+
reset_AdditiveQuantizerIndex(res);
|
|
371
|
+
return res;
|
|
160
372
|
} else {
|
|
161
|
-
|
|
373
|
+
FAISS_THROW_FMT(
|
|
374
|
+
"clone not supported for this Index type %s",
|
|
375
|
+
typeid(*index).name());
|
|
162
376
|
}
|
|
163
377
|
return nullptr;
|
|
164
|
-
}
|
|
378
|
+
} // namespace
|
|
165
379
|
|
|
166
380
|
Quantizer* clone_Quantizer(const Quantizer* quant) {
|
|
167
381
|
TRYCLONE(ResidualQuantizer, quant)
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its 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
|
+
*/
|
|
2
7
|
|
|
3
8
|
#pragma once
|
|
4
9
|
|
|
@@ -11,19 +16,32 @@
|
|
|
11
16
|
// * PQ[1]x8
|
|
12
17
|
// Additionally, AVX2 and ARM versions support
|
|
13
18
|
// * Residual[1]x8,PQ[2]x10
|
|
19
|
+
// * Residual[1]x8,PQ[2]x12
|
|
14
20
|
// * Residual[1]x8,PQ[2]x16
|
|
15
21
|
// * Residual[1]x10,PQ[2]x10
|
|
22
|
+
// * Residual[1]x10,PQ[2]x12
|
|
16
23
|
// * Residual[1]x10,PQ[2]x16
|
|
24
|
+
// * Residual[1]x12,PQ[2]x10
|
|
25
|
+
// * Residual[1]x12,PQ[2]x12
|
|
26
|
+
// * Residual[1]x12,PQ[2]x16
|
|
17
27
|
// * Residual[1]x16,PQ[2]x10
|
|
28
|
+
// * Residual[1]x16,PQ[2]x12
|
|
18
29
|
// * Residual[1]x16,PQ[2]x16
|
|
19
30
|
// * Residual1x[9-16 bit],PQ[1]x10 (such as Residual1x9,PQ16x10)
|
|
20
31
|
// * * (use with COARSE_BITS=16)
|
|
32
|
+
// * Residual1x[9-16 bit],PQ[1]x12 (such as Residual1x9,PQ16x12)
|
|
33
|
+
// * * (use with COARSE_BITS=16)
|
|
21
34
|
// * Residual1x[9-16 bit],PQ[1]x16 (such as Residual1x9,PQ16x16)
|
|
22
35
|
// * * (use with COARSE_BITS=16)
|
|
23
36
|
// * PQ[1]x10
|
|
37
|
+
// * PQ[1]x12
|
|
24
38
|
// * PQ[1]x16
|
|
25
|
-
//
|
|
26
|
-
// IVF256,
|
|
39
|
+
// * IVF256,PQ[1]x10 (such as IVF256,PQ16x10np)
|
|
40
|
+
// * IVF256,PQ[1]x12 (such as IVF256,PQ16x12np)
|
|
41
|
+
// * IVF256,PQ[1]x16 (such as IVF256,PQ16x16np)
|
|
42
|
+
// * IVF[2^9-2^16 bit],PQ[1]x10 (such as IVF1024,PQ16x10np)
|
|
43
|
+
// * IVF[2^9-2^16 bit],PQ[1]x12 (such as IVF1024,PQ16x12np)
|
|
44
|
+
// * IVF[2^9-2^16 bit],PQ[1]x16 (such as IVF1024,PQ16x16np)
|
|
27
45
|
//
|
|
28
46
|
// The goal was to achieve the maximum performance, so the template version it
|
|
29
47
|
// is. The provided index families share the same code for sa_decode.
|
|
@@ -57,6 +75,10 @@
|
|
|
57
75
|
// decoder.
|
|
58
76
|
// For example, "Residual4x10,PQ16x10np" for 256-dim data translates into
|
|
59
77
|
// Index2LevelDecoder<256,64,16,10,10>
|
|
78
|
+
// For example, "IVF1024,PQ16x10np" for 256-dim data translates into
|
|
79
|
+
// Index2LevelDecoder<256,256,16,10,10>. But as there are only 1 coarse code
|
|
80
|
+
// element, Index2LevelDecoder<256,256,16,16,10> can be used as a faster
|
|
81
|
+
// decoder.
|
|
60
82
|
//
|
|
61
83
|
// Additional supported values for COARSE_BITS and FINE_BITS may be added later.
|
|
62
84
|
//
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its 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
|
+
|
|
1
8
|
#pragma once
|
|
2
9
|
|
|
3
10
|
#include <cstdint>
|
|
@@ -120,6 +127,72 @@ struct Uint10Reader {
|
|
|
120
127
|
}
|
|
121
128
|
};
|
|
122
129
|
|
|
130
|
+
// reduces the number of read operations from RAM
|
|
131
|
+
///////////////////////////////////////////////
|
|
132
|
+
// 76543210 76543210 76543210 76543210 76543210 76543210
|
|
133
|
+
// 00000000 0000
|
|
134
|
+
// 1111 11111111
|
|
135
|
+
// 22222222 2222
|
|
136
|
+
// 3333 33333333
|
|
137
|
+
template <intptr_t N_ELEMENTS, intptr_t CPOS>
|
|
138
|
+
struct Uint12Reader {
|
|
139
|
+
static_assert(CPOS < N_ELEMENTS, "CPOS should be less than N_ELEMENTS");
|
|
140
|
+
|
|
141
|
+
static intptr_t get(const uint8_t* const __restrict codes) {
|
|
142
|
+
// Read using 4-bytes or 2-bytes.
|
|
143
|
+
|
|
144
|
+
constexpr intptr_t ELEMENT_TO_READ = CPOS / 4;
|
|
145
|
+
constexpr intptr_t SUB_ELEMENT = CPOS % 4;
|
|
146
|
+
|
|
147
|
+
switch (SUB_ELEMENT) {
|
|
148
|
+
case 0: {
|
|
149
|
+
if (N_ELEMENTS > CPOS + 2) {
|
|
150
|
+
const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
|
151
|
+
codes + ELEMENT_TO_READ * 6);
|
|
152
|
+
return (code32 & 0b0000111111111111);
|
|
153
|
+
} else {
|
|
154
|
+
const uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
|
155
|
+
codes + ELEMENT_TO_READ * 6 + 0);
|
|
156
|
+
return (code16 & 0b0000111111111111);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
case 1: {
|
|
160
|
+
if (N_ELEMENTS > CPOS + 1) {
|
|
161
|
+
const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
|
162
|
+
codes + ELEMENT_TO_READ * 6);
|
|
163
|
+
return (code32 & 0b111111111111000000000000) >> 12;
|
|
164
|
+
} else {
|
|
165
|
+
const uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
|
166
|
+
codes + ELEMENT_TO_READ * 6 + 1);
|
|
167
|
+
return (code16 & 0b1111111111110000) >> 4;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
case 2: {
|
|
171
|
+
if (N_ELEMENTS > CPOS + 1) {
|
|
172
|
+
const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
|
173
|
+
codes + ELEMENT_TO_READ * 6 + 2);
|
|
174
|
+
return (code32 & 0b000011111111111100000000) >> 8;
|
|
175
|
+
} else {
|
|
176
|
+
const uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
|
177
|
+
codes + ELEMENT_TO_READ * 6 + 3);
|
|
178
|
+
return (code16 & 0b0000111111111111);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
case 3: {
|
|
182
|
+
if (N_ELEMENTS > CPOS) {
|
|
183
|
+
const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
|
184
|
+
codes + ELEMENT_TO_READ * 6 + 2);
|
|
185
|
+
return (code32 & 0b11111111111100000000000000000000) >> 20;
|
|
186
|
+
} else {
|
|
187
|
+
const uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
|
188
|
+
codes + ELEMENT_TO_READ * 6 + 4);
|
|
189
|
+
return (code16 & 0b1111111111110000) >> 4;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
123
196
|
// reduces the number of read operations from RAM
|
|
124
197
|
template <intptr_t N_ELEMENTS, intptr_t CPOS>
|
|
125
198
|
struct Uint16Reader {
|
|
@@ -173,6 +246,11 @@ struct UintReaderImplType<N_ELEMENTS, 10, CPOS> {
|
|
|
173
246
|
using reader_type = Uint10Reader<N_ELEMENTS, CPOS>;
|
|
174
247
|
};
|
|
175
248
|
|
|
249
|
+
template <intptr_t N_ELEMENTS, intptr_t CPOS>
|
|
250
|
+
struct UintReaderImplType<N_ELEMENTS, 12, CPOS> {
|
|
251
|
+
using reader_type = Uint12Reader<N_ELEMENTS, CPOS>;
|
|
252
|
+
};
|
|
253
|
+
|
|
176
254
|
template <intptr_t N_ELEMENTS, intptr_t CPOS>
|
|
177
255
|
struct UintReaderImplType<N_ELEMENTS, 16, CPOS> {
|
|
178
256
|
using reader_type = Uint16Reader<N_ELEMENTS, CPOS>;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its 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
|
+
|
|
2
8
|
#ifndef LEVEL2_AVX2_INL_H
|
|
3
9
|
#define LEVEL2_AVX2_INL_H
|
|
4
10
|
|
|
@@ -1851,8 +1857,14 @@ struct Index2LevelDecoderImpl<
|
|
|
1851
1857
|
} // namespace
|
|
1852
1858
|
|
|
1853
1859
|
// Suitable for IVF256,PQ[1]x8
|
|
1860
|
+
// Subtable for IVF256,PQ[1]x10 (such as IVF256,PQ16x10np)
|
|
1861
|
+
// Subtable for IVF256,PQ[1]x12 (such as IVF256,PQ16x12np)
|
|
1862
|
+
// Suitable for IVF256,PQ[1]x16 (such as IVF256,PQ16x16np)
|
|
1854
1863
|
// Suitable for Residual[1]x8,PQ[2]x8
|
|
1855
|
-
// Suitable for IVF[9-16 bit],PQ[1]x8 (such as IVF1024,PQ16np)
|
|
1864
|
+
// Suitable for IVF[2^9-2^16 bit],PQ[1]x8 (such as IVF1024,PQ16np)
|
|
1865
|
+
// Suitable for IVF[2^9-2^16 bit],PQ[1]x10 (such as IVF1024,PQ16x10np)
|
|
1866
|
+
// Suitable for IVF[2^9-2^16 bit],PQ[1]x12 (such as IVF1024,PQ16x12np)
|
|
1867
|
+
// Suitable for IVF[2^9-2^16 bit],PQ[1]x16 (such as IVF1024,PQ16x16np)
|
|
1856
1868
|
// Suitable for Residual[1]x[9-16 bit],PQ[2]x[3] (such as Residual2x9,PQ8)
|
|
1857
1869
|
template <
|
|
1858
1870
|
intptr_t DIM,
|
|
@@ -1862,11 +1874,13 @@ template <
|
|
|
1862
1874
|
intptr_t FINE_BITS = 8>
|
|
1863
1875
|
struct Index2LevelDecoder {
|
|
1864
1876
|
static_assert(
|
|
1865
|
-
COARSE_BITS == 8 || COARSE_BITS == 10 || COARSE_BITS ==
|
|
1866
|
-
|
|
1877
|
+
COARSE_BITS == 8 || COARSE_BITS == 10 || COARSE_BITS == 12 ||
|
|
1878
|
+
COARSE_BITS == 16,
|
|
1879
|
+
"Only 8, 10, 12 or 16 bits are currently supported for COARSE_BITS");
|
|
1867
1880
|
static_assert(
|
|
1868
|
-
FINE_BITS == 8 || FINE_BITS == 10 || FINE_BITS ==
|
|
1869
|
-
|
|
1881
|
+
FINE_BITS == 8 || FINE_BITS == 10 || FINE_BITS == 12 ||
|
|
1882
|
+
FINE_BITS == 16,
|
|
1883
|
+
"Only 8, 10, 12 or 16 bits are currently supported for FINE_BITS");
|
|
1870
1884
|
|
|
1871
1885
|
static constexpr intptr_t dim = DIM;
|
|
1872
1886
|
static constexpr intptr_t coarseSize = COARSE_SIZE;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its 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
|
+
|
|
2
8
|
#ifndef LEVEL2_INL_H
|
|
3
9
|
#define LEVEL2_INL_H
|
|
4
10
|
|