faiss 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.h +1 -1
- data/vendor/faiss/faiss/Clustering.cpp +35 -4
- data/vendor/faiss/faiss/Clustering.h +10 -1
- data/vendor/faiss/faiss/IVFlib.cpp +4 -1
- data/vendor/faiss/faiss/Index.h +21 -6
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +1 -1
- data/vendor/faiss/faiss/IndexFastScan.cpp +22 -4
- data/vendor/faiss/faiss/IndexFlat.cpp +11 -7
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +159 -5
- data/vendor/faiss/faiss/IndexFlatCodes.h +20 -3
- data/vendor/faiss/faiss/IndexHNSW.cpp +143 -90
- data/vendor/faiss/faiss/IndexHNSW.h +52 -3
- data/vendor/faiss/faiss/IndexIVF.cpp +3 -3
- data/vendor/faiss/faiss/IndexIVF.h +9 -1
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +15 -0
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +3 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +130 -57
- data/vendor/faiss/faiss/IndexIVFFastScan.h +14 -7
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +1 -3
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +21 -2
- data/vendor/faiss/faiss/IndexLattice.cpp +1 -19
- data/vendor/faiss/faiss/IndexLattice.h +3 -22
- data/vendor/faiss/faiss/IndexNNDescent.cpp +0 -29
- data/vendor/faiss/faiss/IndexNNDescent.h +1 -1
- data/vendor/faiss/faiss/IndexNSG.h +1 -1
- data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +56 -0
- data/vendor/faiss/faiss/IndexNeuralNetCodec.h +49 -0
- data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
- data/vendor/faiss/faiss/IndexRefine.cpp +5 -5
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +3 -1
- data/vendor/faiss/faiss/MetricType.h +7 -2
- data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +95 -17
- data/vendor/faiss/faiss/cppcontrib/factory_tools.cpp +152 -0
- data/vendor/faiss/faiss/cppcontrib/factory_tools.h +24 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +83 -30
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +36 -4
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +6 -0
- data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -1
- data/vendor/faiss/faiss/gpu/GpuIndex.h +2 -8
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +282 -0
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +6 -0
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +2 -0
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +25 -0
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +26 -21
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +6 -0
- data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +8 -5
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +65 -0
- 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/gpu/utils/Timer.cpp +4 -1
- data/vendor/faiss/faiss/gpu/utils/Timer.h +1 -1
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +25 -0
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +9 -1
- data/vendor/faiss/faiss/impl/DistanceComputer.h +46 -0
- data/vendor/faiss/faiss/impl/FaissAssert.h +4 -2
- data/vendor/faiss/faiss/impl/HNSW.cpp +358 -190
- data/vendor/faiss/faiss/impl/HNSW.h +43 -22
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +8 -8
- data/vendor/faiss/faiss/impl/LookupTableScaler.h +34 -0
- data/vendor/faiss/faiss/impl/NNDescent.cpp +13 -8
- data/vendor/faiss/faiss/impl/NSG.cpp +0 -29
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +1 -0
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +5 -1
- data/vendor/faiss/faiss/impl/ResultHandler.h +151 -32
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +719 -102
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +3 -0
- data/vendor/faiss/faiss/impl/code_distance/code_distance-avx2.h +5 -0
- data/vendor/faiss/faiss/impl/code_distance/code_distance-avx512.h +248 -0
- data/vendor/faiss/faiss/impl/index_read.cpp +29 -15
- data/vendor/faiss/faiss/impl/index_read_utils.h +37 -0
- data/vendor/faiss/faiss/impl/index_write.cpp +28 -10
- data/vendor/faiss/faiss/impl/io.cpp +13 -5
- data/vendor/faiss/faiss/impl/io.h +4 -4
- data/vendor/faiss/faiss/impl/io_macros.h +6 -0
- data/vendor/faiss/faiss/impl/platform_macros.h +22 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +11 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +1 -1
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +448 -1
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +5 -5
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +1 -1
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +143 -59
- data/vendor/faiss/faiss/index_factory.cpp +31 -13
- data/vendor/faiss/faiss/index_io.h +12 -5
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +28 -8
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +3 -0
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +9 -1
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +55 -17
- data/vendor/faiss/faiss/invlists/InvertedLists.h +18 -9
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +21 -6
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +2 -1
- data/vendor/faiss/faiss/python/python_callbacks.cpp +3 -3
- data/vendor/faiss/faiss/utils/Heap.h +105 -0
- data/vendor/faiss/faiss/utils/NeuralNet.cpp +342 -0
- data/vendor/faiss/faiss/utils/NeuralNet.h +147 -0
- data/vendor/faiss/faiss/utils/bf16.h +36 -0
- data/vendor/faiss/faiss/utils/distances.cpp +58 -88
- data/vendor/faiss/faiss/utils/distances.h +5 -5
- data/vendor/faiss/faiss/utils/distances_simd.cpp +997 -9
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +70 -0
- data/vendor/faiss/faiss/utils/extra_distances.cpp +85 -137
- data/vendor/faiss/faiss/utils/extra_distances.h +3 -2
- data/vendor/faiss/faiss/utils/hamming.cpp +1 -1
- data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +4 -1
- data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +2 -1
- data/vendor/faiss/faiss/utils/random.cpp +43 -0
- data/vendor/faiss/faiss/utils/random.h +25 -0
- data/vendor/faiss/faiss/utils/simdlib.h +10 -1
- data/vendor/faiss/faiss/utils/simdlib_avx512.h +296 -0
- data/vendor/faiss/faiss/utils/simdlib_neon.h +5 -2
- data/vendor/faiss/faiss/utils/simdlib_ppc64.h +1084 -0
- data/vendor/faiss/faiss/utils/transpose/transpose-avx512-inl.h +176 -0
- data/vendor/faiss/faiss/utils/utils.cpp +10 -3
- data/vendor/faiss/faiss/utils/utils.h +3 -0
- metadata +16 -4
- data/vendor/faiss/faiss/impl/code_distance/code_distance_avx512.h +0 -102
@@ -58,35 +58,6 @@ using storage_idx_t = NNDescent::storage_idx_t;
|
|
58
58
|
|
59
59
|
namespace {
|
60
60
|
|
61
|
-
/* Wrap the distance computer into one that negates the
|
62
|
-
distances. This makes supporting INNER_PRODUCE search easier */
|
63
|
-
|
64
|
-
struct NegativeDistanceComputer : DistanceComputer {
|
65
|
-
/// owned by this
|
66
|
-
DistanceComputer* basedis;
|
67
|
-
|
68
|
-
explicit NegativeDistanceComputer(DistanceComputer* basedis)
|
69
|
-
: basedis(basedis) {}
|
70
|
-
|
71
|
-
void set_query(const float* x) override {
|
72
|
-
basedis->set_query(x);
|
73
|
-
}
|
74
|
-
|
75
|
-
/// compute distance of vector i to current query
|
76
|
-
float operator()(idx_t i) override {
|
77
|
-
return -(*basedis)(i);
|
78
|
-
}
|
79
|
-
|
80
|
-
/// compute distance between two stored vectors
|
81
|
-
float symmetric_dis(idx_t i, idx_t j) override {
|
82
|
-
return -basedis->symmetric_dis(i, j);
|
83
|
-
}
|
84
|
-
|
85
|
-
~NegativeDistanceComputer() override {
|
86
|
-
delete basedis;
|
87
|
-
}
|
88
|
-
};
|
89
|
-
|
90
61
|
DistanceComputer* storage_distance_computer(const Index* storage) {
|
91
62
|
if (is_similarity_metric(storage->metric_type)) {
|
92
63
|
return new NegativeDistanceComputer(storage->get_distance_computer());
|
@@ -0,0 +1,56 @@
|
|
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
|
+
|
8
|
+
#include <faiss/IndexNeuralNetCodec.h>
|
9
|
+
#include <faiss/impl/FaissAssert.h>
|
10
|
+
#include <faiss/utils/hamming.h>
|
11
|
+
|
12
|
+
namespace faiss {
|
13
|
+
|
14
|
+
/*********************************************************
|
15
|
+
* IndexNeuralNetCodec implementation
|
16
|
+
*********************************************************/
|
17
|
+
|
18
|
+
IndexNeuralNetCodec::IndexNeuralNetCodec(
|
19
|
+
int d,
|
20
|
+
int M,
|
21
|
+
int nbits,
|
22
|
+
MetricType metric)
|
23
|
+
: IndexFlatCodes((M * nbits + 7) / 8, d, metric), M(M), nbits(nbits) {
|
24
|
+
is_trained = false;
|
25
|
+
}
|
26
|
+
|
27
|
+
void IndexNeuralNetCodec::train(idx_t n, const float* x) {
|
28
|
+
FAISS_THROW_MSG("Training not implemented in C++, use Pytorch");
|
29
|
+
}
|
30
|
+
|
31
|
+
void IndexNeuralNetCodec::sa_encode(idx_t n, const float* x, uint8_t* codes)
|
32
|
+
const {
|
33
|
+
nn::Tensor2D x_tensor(n, d, x);
|
34
|
+
nn::Int32Tensor2D codes_tensor = net->encode(x_tensor);
|
35
|
+
pack_bitstrings(n, M, nbits, codes_tensor.data(), codes, code_size);
|
36
|
+
}
|
37
|
+
|
38
|
+
void IndexNeuralNetCodec::sa_decode(idx_t n, const uint8_t* codes, float* x)
|
39
|
+
const {
|
40
|
+
nn::Int32Tensor2D codes_tensor(n, M);
|
41
|
+
unpack_bitstrings(n, M, nbits, codes, code_size, codes_tensor.data());
|
42
|
+
nn::Tensor2D x_tensor = net->decode(codes_tensor);
|
43
|
+
memcpy(x, x_tensor.data(), d * n * sizeof(float));
|
44
|
+
}
|
45
|
+
|
46
|
+
/*********************************************************
|
47
|
+
* IndexQINeuralNetCodec implementation
|
48
|
+
*********************************************************/
|
49
|
+
|
50
|
+
IndexQINCo::IndexQINCo(int d, int M, int nbits, int L, int h, MetricType metric)
|
51
|
+
: IndexNeuralNetCodec(d, M, nbits, metric),
|
52
|
+
qinco(d, 1 << nbits, L, M, h) {
|
53
|
+
net = &qinco;
|
54
|
+
}
|
55
|
+
|
56
|
+
} // namespace faiss
|
@@ -0,0 +1,49 @@
|
|
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
|
+
|
8
|
+
#pragma once
|
9
|
+
|
10
|
+
#include <vector>
|
11
|
+
|
12
|
+
#include <faiss/IndexFlatCodes.h>
|
13
|
+
#include <faiss/utils/NeuralNet.h>
|
14
|
+
|
15
|
+
namespace faiss {
|
16
|
+
|
17
|
+
struct IndexNeuralNetCodec : IndexFlatCodes {
|
18
|
+
NeuralNetCodec* net = nullptr;
|
19
|
+
size_t M, nbits;
|
20
|
+
|
21
|
+
explicit IndexNeuralNetCodec(
|
22
|
+
int d = 0,
|
23
|
+
int M = 0,
|
24
|
+
int nbits = 0,
|
25
|
+
MetricType metric = METRIC_L2);
|
26
|
+
|
27
|
+
void train(idx_t n, const float* x) override;
|
28
|
+
|
29
|
+
void sa_encode(idx_t n, const float* x, uint8_t* codes) const override;
|
30
|
+
void sa_decode(idx_t n, const uint8_t* codes, float* x) const override;
|
31
|
+
|
32
|
+
~IndexNeuralNetCodec() {}
|
33
|
+
};
|
34
|
+
|
35
|
+
struct IndexQINCo : IndexNeuralNetCodec {
|
36
|
+
QINCo qinco;
|
37
|
+
|
38
|
+
IndexQINCo(
|
39
|
+
int d,
|
40
|
+
int M,
|
41
|
+
int nbits,
|
42
|
+
int L,
|
43
|
+
int h,
|
44
|
+
MetricType metric = METRIC_L2);
|
45
|
+
|
46
|
+
~IndexQINCo() {}
|
47
|
+
};
|
48
|
+
|
49
|
+
} // namespace faiss
|
@@ -23,7 +23,7 @@ struct SearchParametersPreTransform : SearchParameters {
|
|
23
23
|
/** Index that applies a LinearTransform transform on vectors before
|
24
24
|
* handing them over to a sub-index */
|
25
25
|
struct IndexPreTransform : Index {
|
26
|
-
std::vector<VectorTransform*> chain; ///! chain of
|
26
|
+
std::vector<VectorTransform*> chain; ///! chain of transforms
|
27
27
|
Index* index; ///! the sub-index
|
28
28
|
|
29
29
|
bool own_fields; ///! whether pointers are deleted in destructor
|
@@ -68,12 +68,12 @@ template <class C>
|
|
68
68
|
static void reorder_2_heaps(
|
69
69
|
idx_t n,
|
70
70
|
idx_t k,
|
71
|
-
idx_t* labels,
|
72
|
-
float* distances,
|
71
|
+
idx_t* __restrict labels,
|
72
|
+
float* __restrict distances,
|
73
73
|
idx_t k_base,
|
74
|
-
const idx_t* base_labels,
|
75
|
-
const float* base_distances) {
|
76
|
-
#pragma omp parallel for
|
74
|
+
const idx_t* __restrict base_labels,
|
75
|
+
const float* __restrict base_distances) {
|
76
|
+
#pragma omp parallel for if (n > 1)
|
77
77
|
for (idx_t i = 0; i < n; i++) {
|
78
78
|
idx_t* idxo = labels + i * k;
|
79
79
|
float* diso = distances + i * k;
|
@@ -32,7 +32,9 @@ IndexScalarQuantizer::IndexScalarQuantizer(
|
|
32
32
|
MetricType metric)
|
33
33
|
: IndexFlatCodes(0, d, metric), sq(d, qtype) {
|
34
34
|
is_trained = qtype == ScalarQuantizer::QT_fp16 ||
|
35
|
-
qtype == ScalarQuantizer::QT_8bit_direct
|
35
|
+
qtype == ScalarQuantizer::QT_8bit_direct ||
|
36
|
+
qtype == ScalarQuantizer::QT_bf16 ||
|
37
|
+
qtype == ScalarQuantizer::QT_8bit_direct_signed;
|
36
38
|
code_size = sq.code_size;
|
37
39
|
}
|
38
40
|
|
@@ -31,8 +31,13 @@ enum MetricType {
|
|
31
31
|
METRIC_Canberra = 20,
|
32
32
|
METRIC_BrayCurtis,
|
33
33
|
METRIC_JensenShannon,
|
34
|
-
|
35
|
-
|
34
|
+
|
35
|
+
/// sum_i(min(a_i, b_i)) / sum_i(max(a_i, b_i)) where a_i, b_i > 0
|
36
|
+
METRIC_Jaccard,
|
37
|
+
/// Squared Eucliden distance, ignoring NaNs
|
38
|
+
METRIC_NaNEuclidean,
|
39
|
+
/// abs(x | y): the distance to a hyperplane
|
40
|
+
METRIC_ABS_INNER_PRODUCT,
|
36
41
|
};
|
37
42
|
|
38
43
|
/// all vector indices are this type
|
@@ -7,6 +7,7 @@
|
|
7
7
|
|
8
8
|
#pragma once
|
9
9
|
|
10
|
+
#include <faiss/impl/platform_macros.h>
|
10
11
|
#include <cstdint>
|
11
12
|
|
12
13
|
namespace faiss {
|
@@ -31,7 +32,11 @@ struct Uint8Reader {
|
|
31
32
|
if (N_ELEMENTS > CPOS + 3) {
|
32
33
|
const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
33
34
|
codes + ELEMENT_TO_READ * 4);
|
35
|
+
#ifdef FAISS_BIG_ENDIAN
|
36
|
+
return (code32) >> 24;
|
37
|
+
#else
|
34
38
|
return (code32 & 0x000000FF);
|
39
|
+
#endif
|
35
40
|
} else {
|
36
41
|
return codes[CPOS];
|
37
42
|
}
|
@@ -40,7 +45,11 @@ struct Uint8Reader {
|
|
40
45
|
if (N_ELEMENTS > CPOS + 2) {
|
41
46
|
const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
42
47
|
codes + ELEMENT_TO_READ * 4);
|
48
|
+
#ifdef FAISS_BIG_ENDIAN
|
49
|
+
return (code32 & 0x00FF0000) >> 16;
|
50
|
+
#else
|
43
51
|
return (code32 & 0x0000FF00) >> 8;
|
52
|
+
#endif
|
44
53
|
} else {
|
45
54
|
return codes[CPOS];
|
46
55
|
}
|
@@ -49,7 +58,11 @@ struct Uint8Reader {
|
|
49
58
|
if (N_ELEMENTS > CPOS + 1) {
|
50
59
|
const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
51
60
|
codes + ELEMENT_TO_READ * 4);
|
61
|
+
#ifdef FAISS_BIG_ENDIAN
|
62
|
+
return (code32 & 0x0000FF00) >> 8;
|
63
|
+
#else
|
52
64
|
return (code32 & 0x00FF0000) >> 16;
|
65
|
+
#endif
|
53
66
|
} else {
|
54
67
|
return codes[CPOS];
|
55
68
|
}
|
@@ -58,7 +71,11 @@ struct Uint8Reader {
|
|
58
71
|
if (N_ELEMENTS > CPOS) {
|
59
72
|
const uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
60
73
|
codes + ELEMENT_TO_READ * 4);
|
74
|
+
#ifdef FAISS_BIG_ENDIAN
|
75
|
+
return (code32 & 0x000000FF);
|
76
|
+
#else
|
61
77
|
return (code32) >> 24;
|
78
|
+
#endif
|
62
79
|
} else {
|
63
80
|
return codes[CPOS];
|
64
81
|
}
|
@@ -87,40 +104,61 @@ struct Uint10Reader {
|
|
87
104
|
switch (SUB_ELEMENT) {
|
88
105
|
case 0: {
|
89
106
|
if (N_ELEMENTS > CPOS + 2) {
|
90
|
-
|
107
|
+
uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
91
108
|
codes + ELEMENT_TO_READ * 5);
|
109
|
+
#ifdef FAISS_BIG_ENDIAN
|
110
|
+
code32 = Swap4Bytes(code32);
|
111
|
+
#endif
|
92
112
|
return (code32 & 0b0000001111111111);
|
93
113
|
} else {
|
94
|
-
|
114
|
+
uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
95
115
|
codes + ELEMENT_TO_READ * 5 + 0);
|
116
|
+
#ifdef FAISS_BIG_ENDIAN
|
117
|
+
code16 = Swap2Bytes(code16);
|
118
|
+
#endif
|
96
119
|
return (code16 & 0b0000001111111111);
|
97
120
|
}
|
98
121
|
}
|
99
122
|
case 1: {
|
100
123
|
if (N_ELEMENTS > CPOS + 1) {
|
101
|
-
|
124
|
+
uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
102
125
|
codes + ELEMENT_TO_READ * 5);
|
126
|
+
#ifdef FAISS_BIG_ENDIAN
|
127
|
+
code32 = Swap4Bytes(code32);
|
128
|
+
#endif
|
103
129
|
return (code32 & 0b000011111111110000000000) >> 10;
|
104
130
|
} else {
|
105
|
-
|
131
|
+
uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
106
132
|
codes + ELEMENT_TO_READ * 5 + 1);
|
133
|
+
#ifdef FAISS_BIG_ENDIAN
|
134
|
+
code16 = Swap2Bytes(code16);
|
135
|
+
#endif
|
107
136
|
return (code16 & 0b0000111111111100) >> 2;
|
108
137
|
}
|
109
138
|
}
|
110
139
|
case 2: {
|
111
140
|
if (N_ELEMENTS > CPOS) {
|
112
|
-
|
141
|
+
uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
113
142
|
codes + ELEMENT_TO_READ * 5);
|
143
|
+
#ifdef FAISS_BIG_ENDIAN
|
144
|
+
code32 = Swap4Bytes(code32);
|
145
|
+
#endif
|
114
146
|
return (code32 & 0b00111111111100000000000000000000) >> 20;
|
115
147
|
} else {
|
116
|
-
|
148
|
+
uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
117
149
|
codes + ELEMENT_TO_READ * 5 + 2);
|
150
|
+
#ifdef FAISS_BIG_ENDIAN
|
151
|
+
code16 = Swap2Bytes(code16);
|
152
|
+
#endif
|
118
153
|
return (code16 & 0b0011111111110000) >> 4;
|
119
154
|
}
|
120
155
|
}
|
121
156
|
case 3: {
|
122
|
-
|
157
|
+
uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
123
158
|
codes + ELEMENT_TO_READ * 5 + 3);
|
159
|
+
#ifdef FAISS_BIG_ENDIAN
|
160
|
+
code16 = Swap2Bytes(code16);
|
161
|
+
#endif
|
124
162
|
return (code16 & 0b1111111111000000) >> 6;
|
125
163
|
}
|
126
164
|
}
|
@@ -147,45 +185,69 @@ struct Uint12Reader {
|
|
147
185
|
switch (SUB_ELEMENT) {
|
148
186
|
case 0: {
|
149
187
|
if (N_ELEMENTS > CPOS + 2) {
|
150
|
-
|
188
|
+
uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
151
189
|
codes + ELEMENT_TO_READ * 6);
|
190
|
+
#ifdef FAISS_BIG_ENDIAN
|
191
|
+
code32 = Swap4Bytes(code32);
|
192
|
+
#endif
|
152
193
|
return (code32 & 0b0000111111111111);
|
153
194
|
} else {
|
154
|
-
|
195
|
+
uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
155
196
|
codes + ELEMENT_TO_READ * 6 + 0);
|
197
|
+
#ifdef FAISS_BIG_ENDIAN
|
198
|
+
code16 = Swap2Bytes(code16);
|
199
|
+
#endif
|
156
200
|
return (code16 & 0b0000111111111111);
|
157
201
|
}
|
158
202
|
}
|
159
203
|
case 1: {
|
160
204
|
if (N_ELEMENTS > CPOS + 1) {
|
161
|
-
|
205
|
+
uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
162
206
|
codes + ELEMENT_TO_READ * 6);
|
207
|
+
#ifdef FAISS_BIG_ENDIAN
|
208
|
+
code32 = Swap4Bytes(code32);
|
209
|
+
#endif
|
163
210
|
return (code32 & 0b111111111111000000000000) >> 12;
|
164
211
|
} else {
|
165
|
-
|
212
|
+
uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
166
213
|
codes + ELEMENT_TO_READ * 6 + 1);
|
214
|
+
#ifdef FAISS_BIG_ENDIAN
|
215
|
+
code16 = Swap2Bytes(code16);
|
216
|
+
#endif
|
167
217
|
return (code16 & 0b1111111111110000) >> 4;
|
168
218
|
}
|
169
219
|
}
|
170
220
|
case 2: {
|
171
221
|
if (N_ELEMENTS > CPOS + 1) {
|
172
|
-
|
222
|
+
uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
173
223
|
codes + ELEMENT_TO_READ * 6 + 2);
|
224
|
+
#ifdef FAISS_BIG_ENDIAN
|
225
|
+
code32 = Swap4Bytes(code32);
|
226
|
+
#endif
|
174
227
|
return (code32 & 0b000011111111111100000000) >> 8;
|
175
228
|
} else {
|
176
|
-
|
229
|
+
uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
177
230
|
codes + ELEMENT_TO_READ * 6 + 3);
|
231
|
+
#ifdef FAISS_BIG_ENDIAN
|
232
|
+
code16 = Swap2Bytes(code16);
|
233
|
+
#endif
|
178
234
|
return (code16 & 0b0000111111111111);
|
179
235
|
}
|
180
236
|
}
|
181
237
|
case 3: {
|
182
238
|
if (N_ELEMENTS > CPOS) {
|
183
|
-
|
239
|
+
uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
184
240
|
codes + ELEMENT_TO_READ * 6 + 2);
|
241
|
+
#ifdef FAISS_BIG_ENDIAN
|
242
|
+
code32 = Swap4Bytes(code32);
|
243
|
+
#endif
|
185
244
|
return (code32 & 0b11111111111100000000000000000000) >> 20;
|
186
245
|
} else {
|
187
|
-
|
246
|
+
uint16_t code16 = *reinterpret_cast<const uint16_t*>(
|
188
247
|
codes + ELEMENT_TO_READ * 6 + 4);
|
248
|
+
#ifdef FAISS_BIG_ENDIAN
|
249
|
+
code16 = Swap2Bytes(code16);
|
250
|
+
#endif
|
189
251
|
return (code16 & 0b1111111111110000) >> 4;
|
190
252
|
}
|
191
253
|
}
|
@@ -208,23 +270,39 @@ struct Uint16Reader {
|
|
208
270
|
switch (SUB_ELEMENT) {
|
209
271
|
case 0: {
|
210
272
|
if (N_ELEMENTS > CPOS + 1) {
|
211
|
-
|
273
|
+
uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
212
274
|
codes + ELEMENT_TO_READ * 4);
|
275
|
+
#ifdef FAISS_BIG_ENDIAN
|
276
|
+
code32 = Swap4Bytes(code32);
|
277
|
+
#endif
|
213
278
|
return (code32 & 0x0000FFFF);
|
214
279
|
} else {
|
215
280
|
const uint16_t* const __restrict codesFp16 =
|
216
281
|
reinterpret_cast<const uint16_t*>(codes);
|
282
|
+
#ifdef FAISS_BIG_ENDIAN
|
283
|
+
uint16_t rt = codesFp16[CPOS];
|
284
|
+
rt = Swap2Bytes(rt);
|
285
|
+
return rt;
|
286
|
+
#endif
|
217
287
|
return codesFp16[CPOS];
|
218
288
|
}
|
219
289
|
}
|
220
290
|
case 1: {
|
221
291
|
if (N_ELEMENTS > CPOS) {
|
222
|
-
|
292
|
+
uint32_t code32 = *reinterpret_cast<const uint32_t*>(
|
223
293
|
codes + ELEMENT_TO_READ * 4);
|
294
|
+
#ifdef FAISS_BIG_ENDIAN
|
295
|
+
code32 = Swap4Bytes(code32);
|
296
|
+
#endif
|
224
297
|
return code32 >> 16;
|
225
298
|
} else {
|
226
299
|
const uint16_t* const __restrict codesFp16 =
|
227
300
|
reinterpret_cast<const uint16_t*>(codes);
|
301
|
+
#ifdef FAISS_BIG_ENDIAN
|
302
|
+
uint16_t rt = codesFp16[CPOS];
|
303
|
+
rt = Swap2Bytes(rt);
|
304
|
+
return rt;
|
305
|
+
#endif
|
228
306
|
return codesFp16[CPOS];
|
229
307
|
}
|
230
308
|
}
|
@@ -0,0 +1,152 @@
|
|
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
|
+
|
8
|
+
// -*- c++ -*-
|
9
|
+
|
10
|
+
#include <faiss/cppcontrib/factory_tools.h>
|
11
|
+
#include <map>
|
12
|
+
|
13
|
+
namespace faiss {
|
14
|
+
|
15
|
+
namespace {
|
16
|
+
|
17
|
+
const std::map<faiss::ScalarQuantizer::QuantizerType, std::string> sq_types = {
|
18
|
+
{faiss::ScalarQuantizer::QT_8bit, "SQ8"},
|
19
|
+
{faiss::ScalarQuantizer::QT_4bit, "SQ4"},
|
20
|
+
{faiss::ScalarQuantizer::QT_6bit, "SQ6"},
|
21
|
+
{faiss::ScalarQuantizer::QT_fp16, "SQfp16"},
|
22
|
+
{faiss::ScalarQuantizer::QT_bf16, "SQbf16"},
|
23
|
+
{faiss::ScalarQuantizer::QT_8bit_direct_signed, "SQ8_direct_signed"},
|
24
|
+
{faiss::ScalarQuantizer::QT_8bit_direct, "SQ8_direct"},
|
25
|
+
};
|
26
|
+
|
27
|
+
int get_hnsw_M(const faiss::IndexHNSW* index) {
|
28
|
+
if (index->hnsw.cum_nneighbor_per_level.size() >= 1) {
|
29
|
+
return index->hnsw.cum_nneighbor_per_level[1] / 2;
|
30
|
+
}
|
31
|
+
// Avoid runtime error, just return 0.
|
32
|
+
return 0;
|
33
|
+
}
|
34
|
+
|
35
|
+
} // namespace
|
36
|
+
|
37
|
+
// Reference for reverse_index_factory:
|
38
|
+
// https://github.com/facebookresearch/faiss/blob/838612c9d7f2f619811434ec9209c020f44107cb/contrib/factory_tools.py#L81
|
39
|
+
std::string reverse_index_factory(const faiss::Index* index) {
|
40
|
+
std::string prefix;
|
41
|
+
if (dynamic_cast<const faiss::IndexFlat*>(index)) {
|
42
|
+
return "Flat";
|
43
|
+
} else if (
|
44
|
+
const faiss::IndexIVF* ivf_index =
|
45
|
+
dynamic_cast<const faiss::IndexIVF*>(index)) {
|
46
|
+
const faiss::Index* quantizer = ivf_index->quantizer;
|
47
|
+
|
48
|
+
if (dynamic_cast<const faiss::IndexFlat*>(quantizer)) {
|
49
|
+
prefix = "IVF" + std::to_string(ivf_index->nlist);
|
50
|
+
} else if (
|
51
|
+
const faiss::MultiIndexQuantizer* miq =
|
52
|
+
dynamic_cast<const faiss::MultiIndexQuantizer*>(
|
53
|
+
quantizer)) {
|
54
|
+
prefix = "IMI" + std::to_string(miq->pq.M) + "x" +
|
55
|
+
std::to_string(miq->pq.nbits);
|
56
|
+
} else if (
|
57
|
+
const faiss::IndexHNSW* hnsw_index =
|
58
|
+
dynamic_cast<const faiss::IndexHNSW*>(quantizer)) {
|
59
|
+
prefix = "IVF" + std::to_string(ivf_index->nlist) + "_HNSW" +
|
60
|
+
std::to_string(get_hnsw_M(hnsw_index));
|
61
|
+
} else {
|
62
|
+
prefix = "IVF" + std::to_string(ivf_index->nlist) + "(" +
|
63
|
+
reverse_index_factory(quantizer) + ")";
|
64
|
+
}
|
65
|
+
|
66
|
+
if (dynamic_cast<const faiss::IndexIVFFlat*>(ivf_index)) {
|
67
|
+
return prefix + ",Flat";
|
68
|
+
} else if (
|
69
|
+
auto sq_index =
|
70
|
+
dynamic_cast<const faiss::IndexIVFScalarQuantizer*>(
|
71
|
+
ivf_index)) {
|
72
|
+
return prefix + "," + sq_types.at(sq_index->sq.qtype);
|
73
|
+
} else if (
|
74
|
+
const faiss::IndexIVFPQ* ivfpq_index =
|
75
|
+
dynamic_cast<const faiss::IndexIVFPQ*>(ivf_index)) {
|
76
|
+
return prefix + ",PQ" + std::to_string(ivfpq_index->pq.M) + "x" +
|
77
|
+
std::to_string(ivfpq_index->pq.nbits);
|
78
|
+
} else if (
|
79
|
+
const faiss::IndexIVFPQFastScan* ivfpqfs_index =
|
80
|
+
dynamic_cast<const faiss::IndexIVFPQFastScan*>(
|
81
|
+
ivf_index)) {
|
82
|
+
return prefix + ",PQ" + std::to_string(ivfpqfs_index->pq.M) + "x" +
|
83
|
+
std::to_string(ivfpqfs_index->pq.nbits) + "fs";
|
84
|
+
}
|
85
|
+
} else if (
|
86
|
+
const faiss::IndexPreTransform* pretransform_index =
|
87
|
+
dynamic_cast<const faiss::IndexPreTransform*>(index)) {
|
88
|
+
if (pretransform_index->chain.size() != 1) {
|
89
|
+
// Avoid runtime error, just return empty string for logging.
|
90
|
+
return "";
|
91
|
+
}
|
92
|
+
const faiss::VectorTransform* vt = pretransform_index->chain.at(0);
|
93
|
+
if (const faiss::OPQMatrix* opq_matrix =
|
94
|
+
dynamic_cast<const faiss::OPQMatrix*>(vt)) {
|
95
|
+
prefix = "OPQ" + std::to_string(opq_matrix->M) + "_" +
|
96
|
+
std::to_string(opq_matrix->d_out);
|
97
|
+
} else if (
|
98
|
+
const faiss::ITQTransform* itq_transform =
|
99
|
+
dynamic_cast<const faiss::ITQTransform*>(vt)) {
|
100
|
+
prefix = "ITQ" + std::to_string(itq_transform->itq.d_out);
|
101
|
+
} else if (
|
102
|
+
const faiss::PCAMatrix* pca_matrix =
|
103
|
+
dynamic_cast<const faiss::PCAMatrix*>(vt)) {
|
104
|
+
assert(pca_matrix->eigen_power == 0);
|
105
|
+
prefix = "PCA" +
|
106
|
+
std::string(pca_matrix->random_rotation ? "R" : "") +
|
107
|
+
std::to_string(pca_matrix->d_out);
|
108
|
+
} else {
|
109
|
+
// Avoid runtime error, just return empty string for logging.
|
110
|
+
return "";
|
111
|
+
}
|
112
|
+
return prefix + "," + reverse_index_factory(pretransform_index->index);
|
113
|
+
} else if (
|
114
|
+
const faiss::IndexHNSW* hnsw_index =
|
115
|
+
dynamic_cast<const faiss::IndexHNSW*>(index)) {
|
116
|
+
return "HNSW" + std::to_string(get_hnsw_M(hnsw_index));
|
117
|
+
} else if (
|
118
|
+
const faiss::IndexRefine* refine_index =
|
119
|
+
dynamic_cast<const faiss::IndexRefine*>(index)) {
|
120
|
+
return reverse_index_factory(refine_index->base_index) + ",Refine(" +
|
121
|
+
reverse_index_factory(refine_index->refine_index) + ")";
|
122
|
+
} else if (
|
123
|
+
const faiss::IndexPQFastScan* pqfs_index =
|
124
|
+
dynamic_cast<const faiss::IndexPQFastScan*>(index)) {
|
125
|
+
return std::string("PQ") + std::to_string(pqfs_index->pq.M) + "x" +
|
126
|
+
std::to_string(pqfs_index->pq.nbits) + "fs";
|
127
|
+
} else if (
|
128
|
+
const faiss::IndexPQ* pq_index =
|
129
|
+
dynamic_cast<const faiss::IndexPQ*>(index)) {
|
130
|
+
return std::string("PQ") + std::to_string(pq_index->pq.M) + "x" +
|
131
|
+
std::to_string(pq_index->pq.nbits);
|
132
|
+
} else if (
|
133
|
+
const faiss::IndexLSH* lsh_index =
|
134
|
+
dynamic_cast<const faiss::IndexLSH*>(index)) {
|
135
|
+
std::string result = "LSH";
|
136
|
+
if (lsh_index->rotate_data) {
|
137
|
+
result += "r";
|
138
|
+
}
|
139
|
+
if (lsh_index->train_thresholds) {
|
140
|
+
result += "t";
|
141
|
+
}
|
142
|
+
return result;
|
143
|
+
} else if (
|
144
|
+
const faiss::IndexScalarQuantizer* sq_index =
|
145
|
+
dynamic_cast<const faiss::IndexScalarQuantizer*>(index)) {
|
146
|
+
return std::string("SQ") + sq_types.at(sq_index->sq.qtype);
|
147
|
+
}
|
148
|
+
// Avoid runtime error, just return empty string for logging.
|
149
|
+
return "";
|
150
|
+
}
|
151
|
+
|
152
|
+
} // namespace faiss
|
@@ -0,0 +1,24 @@
|
|
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
|
+
|
8
|
+
// -*- c++ -*-
|
9
|
+
|
10
|
+
#pragma once
|
11
|
+
|
12
|
+
#include <faiss/IndexHNSW.h>
|
13
|
+
#include <faiss/IndexIVFFlat.h>
|
14
|
+
#include <faiss/IndexIVFPQFastScan.h>
|
15
|
+
#include <faiss/IndexLSH.h>
|
16
|
+
#include <faiss/IndexPQFastScan.h>
|
17
|
+
#include <faiss/IndexPreTransform.h>
|
18
|
+
#include <faiss/IndexRefine.h>
|
19
|
+
|
20
|
+
namespace faiss {
|
21
|
+
|
22
|
+
std::string reverse_index_factory(const faiss::Index* index);
|
23
|
+
|
24
|
+
} // namespace faiss
|