faiss 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/LICENSE.txt +18 -18
- data/README.md +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/Clustering.cpp +318 -53
- data/vendor/faiss/Clustering.h +39 -11
- data/vendor/faiss/DirectMap.cpp +267 -0
- data/vendor/faiss/DirectMap.h +120 -0
- data/vendor/faiss/IVFlib.cpp +24 -4
- data/vendor/faiss/IVFlib.h +4 -0
- data/vendor/faiss/Index.h +5 -24
- data/vendor/faiss/Index2Layer.cpp +0 -1
- data/vendor/faiss/IndexBinary.h +7 -3
- data/vendor/faiss/IndexBinaryFlat.cpp +5 -0
- data/vendor/faiss/IndexBinaryFlat.h +3 -0
- data/vendor/faiss/IndexBinaryHash.cpp +492 -0
- data/vendor/faiss/IndexBinaryHash.h +116 -0
- data/vendor/faiss/IndexBinaryIVF.cpp +160 -107
- data/vendor/faiss/IndexBinaryIVF.h +14 -4
- data/vendor/faiss/IndexFlat.h +2 -1
- data/vendor/faiss/IndexHNSW.cpp +68 -16
- data/vendor/faiss/IndexHNSW.h +3 -3
- data/vendor/faiss/IndexIVF.cpp +72 -76
- data/vendor/faiss/IndexIVF.h +24 -5
- data/vendor/faiss/IndexIVFFlat.cpp +19 -54
- data/vendor/faiss/IndexIVFFlat.h +1 -11
- data/vendor/faiss/IndexIVFPQ.cpp +49 -26
- data/vendor/faiss/IndexIVFPQ.h +9 -10
- data/vendor/faiss/IndexIVFPQR.cpp +2 -2
- data/vendor/faiss/IndexIVFSpectralHash.cpp +2 -2
- data/vendor/faiss/IndexLSH.h +4 -1
- data/vendor/faiss/IndexPreTransform.cpp +0 -1
- data/vendor/faiss/IndexScalarQuantizer.cpp +8 -1
- data/vendor/faiss/InvertedLists.cpp +0 -2
- data/vendor/faiss/MetaIndexes.cpp +0 -1
- data/vendor/faiss/MetricType.h +36 -0
- data/vendor/faiss/c_api/Clustering_c.cpp +13 -7
- data/vendor/faiss/c_api/Clustering_c.h +11 -5
- data/vendor/faiss/c_api/IndexIVF_c.cpp +7 -0
- data/vendor/faiss/c_api/IndexIVF_c.h +7 -0
- data/vendor/faiss/c_api/IndexPreTransform_c.cpp +21 -0
- data/vendor/faiss/c_api/IndexPreTransform_c.h +32 -0
- data/vendor/faiss/demos/demo_weighted_kmeans.cpp +185 -0
- data/vendor/faiss/gpu/GpuCloner.cpp +4 -0
- data/vendor/faiss/gpu/GpuClonerOptions.cpp +1 -1
- data/vendor/faiss/gpu/GpuDistance.h +93 -0
- data/vendor/faiss/gpu/GpuIndex.h +7 -0
- data/vendor/faiss/gpu/GpuIndexFlat.h +0 -10
- data/vendor/faiss/gpu/GpuIndexIVF.h +1 -0
- data/vendor/faiss/gpu/StandardGpuResources.cpp +8 -0
- data/vendor/faiss/gpu/test/TestGpuIndexFlat.cpp +49 -27
- data/vendor/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +110 -2
- data/vendor/faiss/gpu/utils/DeviceUtils.h +6 -0
- data/vendor/faiss/impl/AuxIndexStructures.cpp +17 -0
- data/vendor/faiss/impl/AuxIndexStructures.h +14 -3
- data/vendor/faiss/impl/HNSW.cpp +0 -1
- data/vendor/faiss/impl/PolysemousTraining.h +5 -5
- data/vendor/faiss/impl/ProductQuantizer-inl.h +138 -0
- data/vendor/faiss/impl/ProductQuantizer.cpp +1 -113
- data/vendor/faiss/impl/ProductQuantizer.h +42 -47
- data/vendor/faiss/impl/index_read.cpp +103 -7
- data/vendor/faiss/impl/index_write.cpp +101 -5
- data/vendor/faiss/impl/io.cpp +111 -1
- data/vendor/faiss/impl/io.h +38 -0
- data/vendor/faiss/index_factory.cpp +0 -1
- data/vendor/faiss/tests/test_merge.cpp +0 -1
- data/vendor/faiss/tests/test_pq_encoding.cpp +6 -6
- data/vendor/faiss/tutorial/cpp/5-Multiple-GPUs.cpp +1 -0
- data/vendor/faiss/utils/distances.cpp +4 -5
- data/vendor/faiss/utils/distances_simd.cpp +0 -1
- data/vendor/faiss/utils/hamming.cpp +85 -3
- data/vendor/faiss/utils/hamming.h +20 -0
- data/vendor/faiss/utils/utils.cpp +0 -96
- data/vendor/faiss/utils/utils.h +0 -15
- metadata +11 -3
- data/lib/faiss/ext.bundle +0 -0
@@ -64,6 +64,12 @@ bool getFullUnifiedMemSupport(int device);
|
|
64
64
|
/// Equivalent to getFullUnifiedMemSupport(getCurrentDevice())
|
65
65
|
bool getFullUnifiedMemSupportCurrentDevice();
|
66
66
|
|
67
|
+
/// Does the given device support tensor core operations?
|
68
|
+
bool getTensorCoreSupport(int device);
|
69
|
+
|
70
|
+
/// Equivalent to getTensorCoreSupport(getCurrentDevice())
|
71
|
+
bool getTensorCoreSupportCurrentDevice();
|
72
|
+
|
67
73
|
/// Returns the maximum k-selection value supported based on the CUDA SDK that
|
68
74
|
/// we were compiled with. .cu files can use DeviceDefs.cuh, but this is for
|
69
75
|
/// non-CUDA files
|
@@ -228,6 +228,23 @@ bool IDSelectorRange::is_member (idx_t id) const
|
|
228
228
|
return id >= imin && id < imax;
|
229
229
|
}
|
230
230
|
|
231
|
+
/***********************************************************************
|
232
|
+
* IDSelectorArray
|
233
|
+
***********************************************************************/
|
234
|
+
|
235
|
+
IDSelectorArray::IDSelectorArray (size_t n, const idx_t *ids):
|
236
|
+
n (n), ids(ids)
|
237
|
+
{
|
238
|
+
}
|
239
|
+
|
240
|
+
bool IDSelectorArray::is_member (idx_t id) const
|
241
|
+
{
|
242
|
+
for (idx_t i = 0; i < n; i++) {
|
243
|
+
if (ids[i] == id) return true;
|
244
|
+
}
|
245
|
+
return false;
|
246
|
+
}
|
247
|
+
|
231
248
|
|
232
249
|
/***********************************************************************
|
233
250
|
* IDSelectorBatch
|
@@ -51,9 +51,7 @@ struct RangeSearchResult {
|
|
51
51
|
};
|
52
52
|
|
53
53
|
|
54
|
-
/**
|
55
|
-
|
56
|
-
Encapsulates a set of ids to remove. */
|
54
|
+
/** Encapsulates a set of ids to remove. */
|
57
55
|
struct IDSelector {
|
58
56
|
typedef Index::idx_t idx_t;
|
59
57
|
virtual bool is_member (idx_t id) const = 0;
|
@@ -71,6 +69,19 @@ struct IDSelectorRange: IDSelector {
|
|
71
69
|
~IDSelectorRange() override {}
|
72
70
|
};
|
73
71
|
|
72
|
+
/** simple list of elements to remove
|
73
|
+
*
|
74
|
+
* this is inefficient in most cases, except for IndexIVF with
|
75
|
+
* maintain_direct_map
|
76
|
+
*/
|
77
|
+
struct IDSelectorArray: IDSelector {
|
78
|
+
size_t n;
|
79
|
+
const idx_t *ids;
|
80
|
+
|
81
|
+
IDSelectorArray (size_t n, const idx_t *ids);
|
82
|
+
bool is_member(idx_t id) const override;
|
83
|
+
~IDSelectorArray() override {}
|
84
|
+
};
|
74
85
|
|
75
86
|
/** Remove ids from a set. Repetitions of ids in the indices set
|
76
87
|
* passed to the constructor does not hurt performance. The hash
|
data/vendor/faiss/impl/HNSW.cpp
CHANGED
@@ -123,15 +123,15 @@ struct PolysemousTraining: SimulatedAnnealingParameters {
|
|
123
123
|
enum Optimization_type_t {
|
124
124
|
OT_None,
|
125
125
|
OT_ReproduceDistances_affine, ///< default
|
126
|
-
OT_Ranking_weighted_diff
|
126
|
+
OT_Ranking_weighted_diff ///< same as _2, but use rank of y+ - rank of y-
|
127
127
|
};
|
128
128
|
Optimization_type_t optimization_type;
|
129
129
|
|
130
|
-
|
131
|
-
|
132
|
-
|
130
|
+
/** use 1/4 of the training points for the optimization, with
|
131
|
+
* max. ntrain_permutation. If ntrain_permutation == 0: train on
|
132
|
+
* centroids */
|
133
133
|
int ntrain_permutation;
|
134
|
-
double dis_weight_factor;
|
134
|
+
double dis_weight_factor; ///< decay of exp that weights distance loss
|
135
135
|
|
136
136
|
// filename pattern for the logging of iterations
|
137
137
|
std::string log_pattern;
|
@@ -0,0 +1,138 @@
|
|
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
|
+
namespace faiss {
|
9
|
+
|
10
|
+
inline
|
11
|
+
PQEncoderGeneric::PQEncoderGeneric(uint8_t *code, int nbits,
|
12
|
+
uint8_t offset)
|
13
|
+
: code(code), offset(offset), nbits(nbits), reg(0)
|
14
|
+
{
|
15
|
+
assert(nbits <= 64);
|
16
|
+
if (offset > 0) {
|
17
|
+
reg = (*code & ((1 << offset) - 1));
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
inline
|
22
|
+
void PQEncoderGeneric::encode(uint64_t x)
|
23
|
+
{
|
24
|
+
reg |= (uint8_t)(x << offset);
|
25
|
+
x >>= (8 - offset);
|
26
|
+
if (offset + nbits >= 8) {
|
27
|
+
*code++ = reg;
|
28
|
+
|
29
|
+
for (int i = 0; i < (nbits - (8 - offset)) / 8; ++i) {
|
30
|
+
*code++ = (uint8_t)x;
|
31
|
+
x >>= 8;
|
32
|
+
}
|
33
|
+
|
34
|
+
offset += nbits;
|
35
|
+
offset &= 7;
|
36
|
+
reg = (uint8_t)x;
|
37
|
+
} else {
|
38
|
+
offset += nbits;
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
inline
|
43
|
+
PQEncoderGeneric::~PQEncoderGeneric()
|
44
|
+
{
|
45
|
+
if (offset > 0) {
|
46
|
+
*code = reg;
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
|
51
|
+
inline
|
52
|
+
PQEncoder8::PQEncoder8(uint8_t *code, int nbits)
|
53
|
+
: code(code) {
|
54
|
+
assert(8 == nbits);
|
55
|
+
}
|
56
|
+
|
57
|
+
inline
|
58
|
+
void PQEncoder8::encode(uint64_t x) {
|
59
|
+
*code++ = (uint8_t)x;
|
60
|
+
}
|
61
|
+
|
62
|
+
inline
|
63
|
+
PQEncoder16::PQEncoder16(uint8_t *code, int nbits)
|
64
|
+
: code((uint16_t *)code) {
|
65
|
+
assert(16 == nbits);
|
66
|
+
}
|
67
|
+
|
68
|
+
inline
|
69
|
+
void PQEncoder16::encode(uint64_t x) {
|
70
|
+
*code++ = (uint16_t)x;
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
inline
|
75
|
+
PQDecoderGeneric::PQDecoderGeneric(const uint8_t *code,
|
76
|
+
int nbits)
|
77
|
+
: code(code),
|
78
|
+
offset(0),
|
79
|
+
nbits(nbits),
|
80
|
+
mask((1ull << nbits) - 1),
|
81
|
+
reg(0) {
|
82
|
+
assert(nbits <= 64);
|
83
|
+
}
|
84
|
+
|
85
|
+
inline
|
86
|
+
uint64_t PQDecoderGeneric::decode() {
|
87
|
+
if (offset == 0) {
|
88
|
+
reg = *code;
|
89
|
+
}
|
90
|
+
uint64_t c = (reg >> offset);
|
91
|
+
|
92
|
+
if (offset + nbits >= 8) {
|
93
|
+
uint64_t e = 8 - offset;
|
94
|
+
++code;
|
95
|
+
for (int i = 0; i < (nbits - (8 - offset)) / 8; ++i) {
|
96
|
+
c |= ((uint64_t)(*code++) << e);
|
97
|
+
e += 8;
|
98
|
+
}
|
99
|
+
|
100
|
+
offset += nbits;
|
101
|
+
offset &= 7;
|
102
|
+
if (offset > 0) {
|
103
|
+
reg = *code;
|
104
|
+
c |= ((uint64_t)reg << e);
|
105
|
+
}
|
106
|
+
} else {
|
107
|
+
offset += nbits;
|
108
|
+
}
|
109
|
+
|
110
|
+
return c & mask;
|
111
|
+
}
|
112
|
+
|
113
|
+
|
114
|
+
inline
|
115
|
+
PQDecoder8::PQDecoder8(const uint8_t *code, int nbits)
|
116
|
+
: code(code) {
|
117
|
+
assert(8 == nbits);
|
118
|
+
}
|
119
|
+
|
120
|
+
inline
|
121
|
+
uint64_t PQDecoder8::decode() {
|
122
|
+
return (uint64_t)(*code++);
|
123
|
+
}
|
124
|
+
|
125
|
+
|
126
|
+
inline
|
127
|
+
PQDecoder16::PQDecoder16(const uint8_t *code, int nbits)
|
128
|
+
: code((uint16_t *)code) {
|
129
|
+
assert(16 == nbits);
|
130
|
+
}
|
131
|
+
|
132
|
+
inline
|
133
|
+
uint64_t PQDecoder16::decode() {
|
134
|
+
return (uint64_t)(*code++);
|
135
|
+
}
|
136
|
+
|
137
|
+
|
138
|
+
} // namespace faiss
|
@@ -151,7 +151,7 @@ static inline void pq_estimators_from_tables_generic(const ProductQuantizer& pq,
|
|
151
151
|
const size_t M = pq.M;
|
152
152
|
const size_t ksub = pq.ksub;
|
153
153
|
for (size_t j = 0; j < ncodes; ++j) {
|
154
|
-
|
154
|
+
PQDecoderGeneric decoder(
|
155
155
|
codes + j * pq.code_size, nbits
|
156
156
|
);
|
157
157
|
float dis = 0;
|
@@ -760,117 +760,5 @@ void ProductQuantizer::search_sdc (const uint8_t * qcodes,
|
|
760
760
|
}
|
761
761
|
|
762
762
|
|
763
|
-
ProductQuantizer::PQEncoderGeneric::PQEncoderGeneric(uint8_t *code, int nbits,
|
764
|
-
uint8_t offset)
|
765
|
-
: code(code), offset(offset), nbits(nbits), reg(0) {
|
766
|
-
assert(nbits <= 64);
|
767
|
-
if (offset > 0) {
|
768
|
-
reg = (*code & ((1 << offset) - 1));
|
769
|
-
}
|
770
|
-
}
|
771
|
-
|
772
|
-
void ProductQuantizer::PQEncoderGeneric::encode(uint64_t x) {
|
773
|
-
reg |= (uint8_t)(x << offset);
|
774
|
-
x >>= (8 - offset);
|
775
|
-
if (offset + nbits >= 8) {
|
776
|
-
*code++ = reg;
|
777
|
-
|
778
|
-
for (int i = 0; i < (nbits - (8 - offset)) / 8; ++i) {
|
779
|
-
*code++ = (uint8_t)x;
|
780
|
-
x >>= 8;
|
781
|
-
}
|
782
|
-
|
783
|
-
offset += nbits;
|
784
|
-
offset &= 7;
|
785
|
-
reg = (uint8_t)x;
|
786
|
-
} else {
|
787
|
-
offset += nbits;
|
788
|
-
}
|
789
|
-
}
|
790
|
-
|
791
|
-
ProductQuantizer::PQEncoderGeneric::~PQEncoderGeneric() {
|
792
|
-
if (offset > 0) {
|
793
|
-
*code = reg;
|
794
|
-
}
|
795
|
-
}
|
796
|
-
|
797
|
-
|
798
|
-
ProductQuantizer::PQEncoder8::PQEncoder8(uint8_t *code, int nbits)
|
799
|
-
: code(code) {
|
800
|
-
assert(8 == nbits);
|
801
|
-
}
|
802
|
-
|
803
|
-
void ProductQuantizer::PQEncoder8::encode(uint64_t x) {
|
804
|
-
*code++ = (uint8_t)x;
|
805
|
-
}
|
806
|
-
|
807
|
-
|
808
|
-
ProductQuantizer::PQEncoder16::PQEncoder16(uint8_t *code, int nbits)
|
809
|
-
: code((uint16_t *)code) {
|
810
|
-
assert(16 == nbits);
|
811
|
-
}
|
812
|
-
|
813
|
-
void ProductQuantizer::PQEncoder16::encode(uint64_t x) {
|
814
|
-
*code++ = (uint16_t)x;
|
815
|
-
}
|
816
|
-
|
817
|
-
|
818
|
-
ProductQuantizer::PQDecoderGeneric::PQDecoderGeneric(const uint8_t *code,
|
819
|
-
int nbits)
|
820
|
-
: code(code),
|
821
|
-
offset(0),
|
822
|
-
nbits(nbits),
|
823
|
-
mask((1ull << nbits) - 1),
|
824
|
-
reg(0) {
|
825
|
-
assert(nbits <= 64);
|
826
|
-
}
|
827
|
-
|
828
|
-
uint64_t ProductQuantizer::PQDecoderGeneric::decode() {
|
829
|
-
if (offset == 0) {
|
830
|
-
reg = *code;
|
831
|
-
}
|
832
|
-
uint64_t c = (reg >> offset);
|
833
|
-
|
834
|
-
if (offset + nbits >= 8) {
|
835
|
-
uint64_t e = 8 - offset;
|
836
|
-
++code;
|
837
|
-
for (int i = 0; i < (nbits - (8 - offset)) / 8; ++i) {
|
838
|
-
c |= ((uint64_t)(*code++) << e);
|
839
|
-
e += 8;
|
840
|
-
}
|
841
|
-
|
842
|
-
offset += nbits;
|
843
|
-
offset &= 7;
|
844
|
-
if (offset > 0) {
|
845
|
-
reg = *code;
|
846
|
-
c |= ((uint64_t)reg << e);
|
847
|
-
}
|
848
|
-
} else {
|
849
|
-
offset += nbits;
|
850
|
-
}
|
851
|
-
|
852
|
-
return c & mask;
|
853
|
-
}
|
854
|
-
|
855
|
-
|
856
|
-
ProductQuantizer::PQDecoder8::PQDecoder8(const uint8_t *code, int nbits)
|
857
|
-
: code(code) {
|
858
|
-
assert(8 == nbits);
|
859
|
-
}
|
860
|
-
|
861
|
-
uint64_t ProductQuantizer::PQDecoder8::decode() {
|
862
|
-
return (uint64_t)(*code++);
|
863
|
-
}
|
864
|
-
|
865
|
-
|
866
|
-
ProductQuantizer::PQDecoder16::PQDecoder16(const uint8_t *code, int nbits)
|
867
|
-
: code((uint16_t *)code) {
|
868
|
-
assert(16 == nbits);
|
869
|
-
}
|
870
|
-
|
871
|
-
uint64_t ProductQuantizer::PQDecoder16::decode() {
|
872
|
-
return (uint64_t)(*code++);
|
873
|
-
}
|
874
|
-
|
875
763
|
|
876
764
|
} // namespace faiss
|
@@ -173,70 +173,65 @@ struct ProductQuantizer {
|
|
173
173
|
float_maxheap_array_t * res,
|
174
174
|
bool init_finalize_heap = true) const;
|
175
175
|
|
176
|
-
|
177
|
-
uint8_t *code; ///< code for this vector
|
178
|
-
uint8_t offset;
|
179
|
-
const int nbits; ///< number of bits per subquantizer index
|
180
|
-
|
181
|
-
uint8_t reg;
|
182
|
-
|
183
|
-
PQEncoderGeneric(uint8_t *code, int nbits, uint8_t offset = 0);
|
184
|
-
|
185
|
-
void encode(uint64_t x);
|
186
|
-
|
187
|
-
~PQEncoderGeneric();
|
188
|
-
};
|
189
|
-
|
190
|
-
|
191
|
-
struct PQEncoder8 {
|
192
|
-
uint8_t *code;
|
193
|
-
|
194
|
-
PQEncoder8(uint8_t *code, int nbits);
|
195
|
-
|
196
|
-
void encode(uint64_t x);
|
197
|
-
};
|
198
|
-
|
199
|
-
struct PQEncoder16 {
|
200
|
-
uint16_t *code;
|
176
|
+
};
|
201
177
|
|
202
|
-
PQEncoder16(uint8_t *code, int nbits);
|
203
178
|
|
204
|
-
|
205
|
-
|
179
|
+
/*************************************************
|
180
|
+
* Objects to encode / decode strings of bits
|
181
|
+
*************************************************/
|
206
182
|
|
183
|
+
struct PQEncoderGeneric {
|
184
|
+
uint8_t *code; ///< code for this vector
|
185
|
+
uint8_t offset;
|
186
|
+
const int nbits; ///< number of bits per subquantizer index
|
207
187
|
|
208
|
-
|
209
|
-
const uint8_t *code;
|
210
|
-
uint8_t offset;
|
211
|
-
const int nbits;
|
212
|
-
const uint64_t mask;
|
213
|
-
uint8_t reg;
|
188
|
+
uint8_t reg;
|
214
189
|
|
215
|
-
|
190
|
+
PQEncoderGeneric(uint8_t *code, int nbits, uint8_t offset = 0);
|
216
191
|
|
217
|
-
|
218
|
-
};
|
192
|
+
void encode(uint64_t x);
|
219
193
|
|
220
|
-
|
221
|
-
|
194
|
+
~PQEncoderGeneric();
|
195
|
+
};
|
222
196
|
|
223
|
-
PQDecoder8(const uint8_t *code, int nbits);
|
224
197
|
|
225
|
-
|
226
|
-
|
198
|
+
struct PQEncoder8 {
|
199
|
+
uint8_t *code;
|
200
|
+
PQEncoder8(uint8_t *code, int nbits);
|
201
|
+
void encode(uint64_t x);
|
202
|
+
};
|
227
203
|
|
228
|
-
|
229
|
-
|
204
|
+
struct PQEncoder16 {
|
205
|
+
uint16_t *code;
|
206
|
+
PQEncoder16(uint8_t *code, int nbits);
|
207
|
+
void encode(uint64_t x);
|
208
|
+
};
|
230
209
|
|
231
|
-
PQDecoder16(const uint8_t *code, int nbits);
|
232
210
|
|
233
|
-
|
234
|
-
|
211
|
+
struct PQDecoderGeneric {
|
212
|
+
const uint8_t *code;
|
213
|
+
uint8_t offset;
|
214
|
+
const int nbits;
|
215
|
+
const uint64_t mask;
|
216
|
+
uint8_t reg;
|
217
|
+
PQDecoderGeneric(const uint8_t *code, int nbits);
|
218
|
+
uint64_t decode();
|
219
|
+
};
|
235
220
|
|
221
|
+
struct PQDecoder8 {
|
222
|
+
const uint8_t *code;
|
223
|
+
PQDecoder8(const uint8_t *code, int nbits);
|
224
|
+
uint64_t decode();
|
236
225
|
};
|
237
226
|
|
227
|
+
struct PQDecoder16 {
|
228
|
+
const uint16_t *code;
|
229
|
+
PQDecoder16(const uint8_t *code, int nbits);
|
230
|
+
uint64_t decode();
|
231
|
+
};
|
238
232
|
|
239
233
|
} // namespace faiss
|
240
234
|
|
235
|
+
#include <faiss/impl/ProductQuantizer-inl.h>
|
241
236
|
|
242
237
|
#endif
|