faiss 0.5.2 → 0.6.0
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 +16 -0
- data/LICENSE.txt +1 -1
- data/ext/faiss/ext.cpp +1 -1
- data/ext/faiss/extconf.rb +5 -6
- data/ext/faiss/index_binary.cpp +76 -17
- data/ext/faiss/{index.cpp → index_rb.cpp} +108 -35
- data/ext/faiss/kmeans.cpp +12 -9
- data/ext/faiss/numo.hpp +11 -9
- data/ext/faiss/pca_matrix.cpp +10 -8
- data/ext/faiss/product_quantizer.cpp +14 -12
- data/ext/faiss/{utils.cpp → utils_rb.cpp} +10 -3
- data/ext/faiss/{utils.h → utils_rb.h} +6 -0
- data/lib/faiss/version.rb +1 -1
- data/lib/faiss.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +130 -11
- data/vendor/faiss/faiss/AutoTune.h +14 -1
- data/vendor/faiss/faiss/Clustering.cpp +59 -10
- data/vendor/faiss/faiss/Clustering.h +12 -0
- data/vendor/faiss/faiss/IVFlib.cpp +31 -28
- data/vendor/faiss/faiss/Index.cpp +20 -8
- data/vendor/faiss/faiss/Index.h +25 -3
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +19 -24
- data/vendor/faiss/faiss/IndexBinary.cpp +1 -0
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +9 -4
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +45 -11
- data/vendor/faiss/faiss/IndexFastScan.cpp +35 -22
- data/vendor/faiss/faiss/IndexFastScan.h +10 -1
- data/vendor/faiss/faiss/IndexFlat.cpp +193 -136
- data/vendor/faiss/faiss/IndexFlat.h +16 -1
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +46 -22
- data/vendor/faiss/faiss/IndexFlatCodes.h +7 -1
- data/vendor/faiss/faiss/IndexHNSW.cpp +24 -50
- data/vendor/faiss/faiss/IndexHNSW.h +14 -12
- data/vendor/faiss/faiss/IndexIDMap.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVF.cpp +76 -49
- data/vendor/faiss/faiss/IndexIVF.h +14 -4
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +11 -8
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +2 -2
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +25 -14
- data/vendor/faiss/faiss/IndexIVFFastScan.h +26 -22
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +10 -61
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +39 -111
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +89 -147
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +37 -5
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +2 -1
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +42 -30
- data/vendor/faiss/faiss/IndexIVFRaBitQ.h +2 -2
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +246 -97
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +32 -29
- data/vendor/faiss/faiss/IndexLSH.cpp +8 -6
- data/vendor/faiss/faiss/IndexLattice.cpp +29 -24
- data/vendor/faiss/faiss/IndexNNDescent.cpp +1 -0
- data/vendor/faiss/faiss/IndexNSG.cpp +2 -1
- data/vendor/faiss/faiss/IndexNSG.h +0 -2
- data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +1 -1
- data/vendor/faiss/faiss/IndexPQ.cpp +19 -10
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +26 -13
- data/vendor/faiss/faiss/IndexRaBitQ.h +2 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +132 -78
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +14 -12
- data/vendor/faiss/faiss/IndexRefine.cpp +0 -30
- data/vendor/faiss/faiss/IndexShards.cpp +3 -4
- data/vendor/faiss/faiss/MetricType.h +16 -0
- data/vendor/faiss/faiss/VectorTransform.cpp +120 -0
- data/vendor/faiss/faiss/VectorTransform.h +23 -0
- data/vendor/faiss/faiss/clone_index.cpp +7 -4
- data/vendor/faiss/faiss/{cppcontrib/factory_tools.cpp → factory_tools.cpp} +1 -1
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +1 -1
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +37 -11
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +0 -28
- data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +367 -0
- data/vendor/faiss/faiss/impl/ClusteringInitialization.h +107 -0
- data/vendor/faiss/faiss/impl/CodePacker.cpp +4 -0
- data/vendor/faiss/faiss/impl/CodePacker.h +11 -3
- data/vendor/faiss/faiss/impl/CodePackerRaBitQ.cpp +83 -0
- data/vendor/faiss/faiss/impl/CodePackerRaBitQ.h +47 -0
- data/vendor/faiss/faiss/impl/FaissAssert.h +60 -2
- data/vendor/faiss/faiss/impl/HNSW.cpp +25 -34
- data/vendor/faiss/faiss/impl/HNSW.h +8 -6
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +34 -27
- data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -1
- data/vendor/faiss/faiss/impl/NSG.cpp +6 -5
- data/vendor/faiss/faiss/impl/NSG.h +17 -7
- data/vendor/faiss/faiss/impl/Panorama.cpp +53 -46
- data/vendor/faiss/faiss/impl/Panorama.h +22 -6
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +16 -5
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +70 -58
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +92 -0
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +93 -31
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +12 -28
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +3 -10
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +15 -41
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.h +0 -4
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +14 -9
- data/vendor/faiss/faiss/impl/ResultHandler.h +131 -50
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +67 -2358
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +0 -2
- data/vendor/faiss/faiss/impl/VisitedTable.cpp +42 -0
- data/vendor/faiss/faiss/impl/VisitedTable.h +69 -0
- data/vendor/faiss/faiss/impl/expanded_scanners.h +158 -0
- data/vendor/faiss/faiss/impl/index_read.cpp +829 -471
- data/vendor/faiss/faiss/impl/index_read_utils.h +0 -1
- data/vendor/faiss/faiss/impl/index_write.cpp +17 -8
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +47 -20
- data/vendor/faiss/faiss/impl/mapped_io.cpp +9 -2
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +7 -2
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +11 -3
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +19 -13
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +29 -21
- data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx2.h → pq_code_distance/pq_code_distance-avx2.cpp} +42 -215
- data/vendor/faiss/faiss/impl/{code_distance/code_distance-avx512.h → pq_code_distance/pq_code_distance-avx512.cpp} +68 -107
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +141 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +23 -0
- data/vendor/faiss/faiss/impl/{code_distance/code_distance-sve.h → pq_code_distance/pq_code_distance-sve.cpp} +57 -144
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +9 -6
- data/vendor/faiss/faiss/impl/scalar_quantizer/codecs.h +121 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +136 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +280 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +164 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/similarities.h +94 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +455 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +430 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +329 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +467 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +203 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/training.h +42 -0
- data/vendor/faiss/faiss/impl/simd_dispatch.h +139 -0
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +18 -18
- data/vendor/faiss/faiss/index_factory.cpp +35 -16
- data/vendor/faiss/faiss/index_io.h +29 -3
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +7 -4
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +9 -19
- data/vendor/faiss/faiss/svs/IndexSVSFlat.h +2 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +2 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +9 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +9 -0
- data/vendor/faiss/faiss/utils/Heap.cpp +46 -0
- data/vendor/faiss/faiss/utils/Heap.h +21 -0
- data/vendor/faiss/faiss/utils/NeuralNet.cpp +10 -7
- data/vendor/faiss/faiss/utils/distances.cpp +141 -23
- data/vendor/faiss/faiss/utils/distances.h +98 -0
- data/vendor/faiss/faiss/utils/distances_dispatch.h +170 -0
- data/vendor/faiss/faiss/utils/distances_simd.cpp +74 -3511
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +164 -157
- data/vendor/faiss/faiss/utils/extra_distances.cpp +52 -95
- data/vendor/faiss/faiss/utils/extra_distances.h +47 -1
- data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +0 -1
- data/vendor/faiss/faiss/utils/partitioning.cpp +1 -1
- data/vendor/faiss/faiss/utils/pq_code_distance.h +251 -0
- data/vendor/faiss/faiss/utils/rabitq_simd.h +260 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +150 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +568 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_autovec-inl.h +153 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +1185 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +1092 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_sse-inl.h +391 -0
- data/vendor/faiss/faiss/utils/simd_levels.cpp +322 -0
- data/vendor/faiss/faiss/utils/simd_levels.h +91 -0
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +12 -1
- data/vendor/faiss/faiss/utils/simdlib_avx512.h +69 -0
- data/vendor/faiss/faiss/utils/simdlib_neon.h +6 -0
- data/vendor/faiss/faiss/utils/sorting.cpp +4 -4
- data/vendor/faiss/faiss/utils/utils.cpp +16 -9
- metadata +47 -18
- data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +0 -81
- data/vendor/faiss/faiss/impl/code_distance/code_distance.h +0 -186
- /data/vendor/faiss/faiss/{cppcontrib/factory_tools.h → factory_tools.h} +0 -0
|
@@ -0,0 +1,280 @@
|
|
|
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 <faiss/impl/ScalarQuantizer.h>
|
|
11
|
+
#include <faiss/utils/bf16.h>
|
|
12
|
+
#include <faiss/utils/fp16.h>
|
|
13
|
+
#include <faiss/utils/simd_levels.h>
|
|
14
|
+
#include <faiss/utils/simdlib.h>
|
|
15
|
+
|
|
16
|
+
namespace faiss {
|
|
17
|
+
|
|
18
|
+
namespace scalar_quantizer {
|
|
19
|
+
|
|
20
|
+
using QuantizerType = ScalarQuantizer::QuantizerType;
|
|
21
|
+
|
|
22
|
+
/*******************************************************************
|
|
23
|
+
* Quantizer: normalizes scalar vector components, then passes them
|
|
24
|
+
* through a codec
|
|
25
|
+
*******************************************************************/
|
|
26
|
+
|
|
27
|
+
enum class QuantizerTemplateScaling { UNIFORM = 0, NON_UNIFORM = 1 };
|
|
28
|
+
|
|
29
|
+
template <class Codec, QuantizerTemplateScaling SCALING, SIMDLevel SL>
|
|
30
|
+
struct QuantizerTemplate {};
|
|
31
|
+
|
|
32
|
+
template <class Codec>
|
|
33
|
+
struct QuantizerTemplate<
|
|
34
|
+
Codec,
|
|
35
|
+
QuantizerTemplateScaling::UNIFORM,
|
|
36
|
+
SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
|
|
37
|
+
const size_t d;
|
|
38
|
+
const float vmin, vdiff;
|
|
39
|
+
|
|
40
|
+
QuantizerTemplate(size_t d, const std::vector<float>& trained)
|
|
41
|
+
: d(d), vmin(trained[0]), vdiff(trained[1]) {}
|
|
42
|
+
|
|
43
|
+
void encode_vector(const float* x, uint8_t* code) const final {
|
|
44
|
+
for (size_t i = 0; i < d; i++) {
|
|
45
|
+
float xi = 0;
|
|
46
|
+
if (vdiff != 0) {
|
|
47
|
+
xi = (x[i] - vmin) / vdiff;
|
|
48
|
+
if (xi < 0) {
|
|
49
|
+
xi = 0;
|
|
50
|
+
}
|
|
51
|
+
if (xi > 1.0) {
|
|
52
|
+
xi = 1.0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
Codec::encode_component(xi, code, i);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
void decode_vector(const uint8_t* code, float* x) const final {
|
|
60
|
+
for (size_t i = 0; i < d; i++) {
|
|
61
|
+
float xi = Codec::decode_component(code, i);
|
|
62
|
+
x[i] = vmin + xi * vdiff;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
FAISS_ALWAYS_INLINE float reconstruct_component(
|
|
67
|
+
const uint8_t* code,
|
|
68
|
+
size_t i) const {
|
|
69
|
+
float xi = Codec::decode_component(code, i);
|
|
70
|
+
return vmin + xi * vdiff;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
template <class Codec>
|
|
75
|
+
struct QuantizerTemplate<
|
|
76
|
+
Codec,
|
|
77
|
+
QuantizerTemplateScaling::NON_UNIFORM,
|
|
78
|
+
SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
|
|
79
|
+
const size_t d;
|
|
80
|
+
const float *vmin, *vdiff;
|
|
81
|
+
|
|
82
|
+
QuantizerTemplate(size_t d, const std::vector<float>& trained)
|
|
83
|
+
: d(d), vmin(trained.data()), vdiff(trained.data() + d) {}
|
|
84
|
+
|
|
85
|
+
void encode_vector(const float* x, uint8_t* code) const final {
|
|
86
|
+
for (size_t i = 0; i < d; i++) {
|
|
87
|
+
float xi = 0;
|
|
88
|
+
if (vdiff[i] != 0) {
|
|
89
|
+
xi = (x[i] - vmin[i]) / vdiff[i];
|
|
90
|
+
if (xi < 0) {
|
|
91
|
+
xi = 0;
|
|
92
|
+
}
|
|
93
|
+
if (xi > 1.0) {
|
|
94
|
+
xi = 1.0;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
Codec::encode_component(xi, code, i);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
void decode_vector(const uint8_t* code, float* x) const final {
|
|
102
|
+
for (size_t i = 0; i < d; i++) {
|
|
103
|
+
float xi = Codec::decode_component(code, i);
|
|
104
|
+
x[i] = vmin[i] + xi * vdiff[i];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
FAISS_ALWAYS_INLINE float reconstruct_component(
|
|
109
|
+
const uint8_t* code,
|
|
110
|
+
size_t i) const {
|
|
111
|
+
float xi = Codec::decode_component(code, i);
|
|
112
|
+
return vmin[i] + xi * vdiff[i];
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/*******************************************************************
|
|
117
|
+
* FP16 quantizer
|
|
118
|
+
*******************************************************************/
|
|
119
|
+
|
|
120
|
+
template <SIMDLevel SL>
|
|
121
|
+
struct QuantizerFP16;
|
|
122
|
+
|
|
123
|
+
template <>
|
|
124
|
+
struct QuantizerFP16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
|
|
125
|
+
const size_t d;
|
|
126
|
+
|
|
127
|
+
QuantizerFP16(size_t d, const std::vector<float>& /* unused */) : d(d) {}
|
|
128
|
+
|
|
129
|
+
void encode_vector(const float* x, uint8_t* code) const final {
|
|
130
|
+
for (size_t i = 0; i < d; i++) {
|
|
131
|
+
((uint16_t*)code)[i] = encode_fp16(x[i]);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
void decode_vector(const uint8_t* code, float* x) const final {
|
|
136
|
+
for (size_t i = 0; i < d; i++) {
|
|
137
|
+
x[i] = decode_fp16(((uint16_t*)code)[i]);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
FAISS_ALWAYS_INLINE float reconstruct_component(
|
|
142
|
+
const uint8_t* code,
|
|
143
|
+
size_t i) const {
|
|
144
|
+
return decode_fp16(((uint16_t*)code)[i]);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
template <SIMDLevel SL>
|
|
149
|
+
struct QuantizerFP16 : QuantizerFP16<SIMDLevel::NONE> {
|
|
150
|
+
using QuantizerFP16<SIMDLevel::NONE>::QuantizerFP16;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/*******************************************************************
|
|
154
|
+
* BF16 quantizer
|
|
155
|
+
*******************************************************************/
|
|
156
|
+
|
|
157
|
+
template <SIMDLevel SL>
|
|
158
|
+
struct QuantizerBF16;
|
|
159
|
+
|
|
160
|
+
template <>
|
|
161
|
+
struct QuantizerBF16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
|
|
162
|
+
const size_t d;
|
|
163
|
+
|
|
164
|
+
QuantizerBF16(size_t d, const std::vector<float>& /* unused */) : d(d) {}
|
|
165
|
+
|
|
166
|
+
void encode_vector(const float* x, uint8_t* code) const final {
|
|
167
|
+
for (size_t i = 0; i < d; i++) {
|
|
168
|
+
((uint16_t*)code)[i] = encode_bf16(x[i]);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
void decode_vector(const uint8_t* code, float* x) const final {
|
|
173
|
+
for (size_t i = 0; i < d; i++) {
|
|
174
|
+
x[i] = decode_bf16(((uint16_t*)code)[i]);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
FAISS_ALWAYS_INLINE float reconstruct_component(
|
|
179
|
+
const uint8_t* code,
|
|
180
|
+
size_t i) const {
|
|
181
|
+
return decode_bf16(((uint16_t*)code)[i]);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
template <SIMDLevel SL>
|
|
186
|
+
struct QuantizerBF16 : QuantizerBF16<SIMDLevel::NONE> {
|
|
187
|
+
using QuantizerBF16<SIMDLevel::NONE>::QuantizerBF16;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/*******************************************************************
|
|
191
|
+
* 8bit_direct quantizer
|
|
192
|
+
*******************************************************************/
|
|
193
|
+
|
|
194
|
+
template <SIMDLevel SL>
|
|
195
|
+
struct Quantizer8bitDirect;
|
|
196
|
+
|
|
197
|
+
template <>
|
|
198
|
+
struct Quantizer8bitDirect<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
|
|
199
|
+
const size_t d;
|
|
200
|
+
|
|
201
|
+
Quantizer8bitDirect(size_t d, const std::vector<float>& /* unused */)
|
|
202
|
+
: d(d) {}
|
|
203
|
+
|
|
204
|
+
void encode_vector(const float* x, uint8_t* code) const final {
|
|
205
|
+
for (size_t i = 0; i < d; i++) {
|
|
206
|
+
code[i] = (uint8_t)x[i];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
void decode_vector(const uint8_t* code, float* x) const final {
|
|
211
|
+
for (size_t i = 0; i < d; i++) {
|
|
212
|
+
x[i] = code[i];
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
FAISS_ALWAYS_INLINE float reconstruct_component(
|
|
217
|
+
const uint8_t* code,
|
|
218
|
+
size_t i) const {
|
|
219
|
+
return code[i];
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
template <SIMDLevel SL>
|
|
224
|
+
struct Quantizer8bitDirect : Quantizer8bitDirect<SIMDLevel::NONE> {
|
|
225
|
+
using Quantizer8bitDirect<SIMDLevel::NONE>::Quantizer8bitDirect;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/*******************************************************************
|
|
229
|
+
* 8bit_direct_signed quantizer
|
|
230
|
+
*******************************************************************/
|
|
231
|
+
|
|
232
|
+
template <SIMDLevel SL>
|
|
233
|
+
struct Quantizer8bitDirectSigned;
|
|
234
|
+
|
|
235
|
+
template <>
|
|
236
|
+
struct Quantizer8bitDirectSigned<SIMDLevel::NONE>
|
|
237
|
+
: ScalarQuantizer::SQuantizer {
|
|
238
|
+
const size_t d;
|
|
239
|
+
|
|
240
|
+
Quantizer8bitDirectSigned(size_t d, const std::vector<float>& /* unused */)
|
|
241
|
+
: d(d) {}
|
|
242
|
+
|
|
243
|
+
void encode_vector(const float* x, uint8_t* code) const final {
|
|
244
|
+
for (size_t i = 0; i < d; i++) {
|
|
245
|
+
code[i] = (uint8_t)(x[i] + 128);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
void decode_vector(const uint8_t* code, float* x) const final {
|
|
250
|
+
for (size_t i = 0; i < d; i++) {
|
|
251
|
+
x[i] = code[i] - 128;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
FAISS_ALWAYS_INLINE float reconstruct_component(
|
|
256
|
+
const uint8_t* code,
|
|
257
|
+
size_t i) const {
|
|
258
|
+
return code[i] - 128;
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
template <SIMDLevel SL>
|
|
263
|
+
struct Quantizer8bitDirectSigned : Quantizer8bitDirectSigned<SIMDLevel::NONE> {
|
|
264
|
+
using Quantizer8bitDirectSigned<SIMDLevel::NONE>::Quantizer8bitDirectSigned;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
/*******************************************************************
|
|
268
|
+
* Selection function
|
|
269
|
+
*******************************************************************/
|
|
270
|
+
|
|
271
|
+
// declare for all levels
|
|
272
|
+
template <SIMDLevel SL>
|
|
273
|
+
ScalarQuantizer::SQuantizer* sq_select_quantizer(
|
|
274
|
+
QuantizerType qtype,
|
|
275
|
+
size_t d,
|
|
276
|
+
const std::vector<float>& trained);
|
|
277
|
+
|
|
278
|
+
} // namespace scalar_quantizer
|
|
279
|
+
|
|
280
|
+
} // namespace faiss
|
|
@@ -0,0 +1,164 @@
|
|
|
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
|
+
// Private implementation header for per-SIMD scalar quantizer TUs.
|
|
9
|
+
// Do not include in public APIs.
|
|
10
|
+
|
|
11
|
+
#pragma once
|
|
12
|
+
|
|
13
|
+
#include <faiss/impl/ScalarQuantizer.h>
|
|
14
|
+
#include <faiss/utils/simd_levels.h>
|
|
15
|
+
#include <faiss/utils/simdlib.h>
|
|
16
|
+
|
|
17
|
+
#include <faiss/impl/simd_dispatch.h>
|
|
18
|
+
|
|
19
|
+
#include <faiss/IndexIVF.h>
|
|
20
|
+
#include <faiss/impl/FaissAssert.h>
|
|
21
|
+
#include <faiss/impl/IDSelector.h>
|
|
22
|
+
#include <faiss/impl/expanded_scanners.h>
|
|
23
|
+
#include <faiss/utils/bf16.h>
|
|
24
|
+
#include <faiss/utils/fp16.h>
|
|
25
|
+
|
|
26
|
+
#include <faiss/impl/scalar_quantizer/codecs.h>
|
|
27
|
+
#include <faiss/impl/scalar_quantizer/distance_computers.h>
|
|
28
|
+
#include <faiss/impl/scalar_quantizer/quantizers.h>
|
|
29
|
+
#include <faiss/impl/scalar_quantizer/similarities.h>
|
|
30
|
+
|
|
31
|
+
namespace faiss {
|
|
32
|
+
|
|
33
|
+
namespace scalar_quantizer {
|
|
34
|
+
|
|
35
|
+
using QuantizerType = ScalarQuantizer::QuantizerType;
|
|
36
|
+
using SQDistanceComputer = ScalarQuantizer::SQDistanceComputer;
|
|
37
|
+
|
|
38
|
+
/*******************************************************************
|
|
39
|
+
* IVFSQScannerIP / IVFSQScannerL2 — moved from anonymous namespace
|
|
40
|
+
* in ScalarQuantizer.cpp
|
|
41
|
+
*******************************************************************/
|
|
42
|
+
|
|
43
|
+
template <class DCClass>
|
|
44
|
+
struct IVFSQScannerIP : InvertedListScanner {
|
|
45
|
+
DCClass dc;
|
|
46
|
+
bool by_residual;
|
|
47
|
+
|
|
48
|
+
float accu0; /// added to all distances
|
|
49
|
+
|
|
50
|
+
IVFSQScannerIP(
|
|
51
|
+
int d,
|
|
52
|
+
const std::vector<float>& trained,
|
|
53
|
+
size_t code_size,
|
|
54
|
+
bool store_pairs,
|
|
55
|
+
const IDSelector* sel,
|
|
56
|
+
bool by_residual)
|
|
57
|
+
: dc(d, trained), by_residual(by_residual), accu0(0) {
|
|
58
|
+
this->store_pairs = store_pairs;
|
|
59
|
+
this->sel = sel;
|
|
60
|
+
this->code_size = code_size;
|
|
61
|
+
this->keep_max = true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
void set_query(const float* query) override {
|
|
65
|
+
dc.set_query(query);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void set_list(idx_t list_no, float coarse_dis) override {
|
|
69
|
+
this->list_no = list_no;
|
|
70
|
+
accu0 = by_residual ? coarse_dis : 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
float distance_to_code(const uint8_t* code) const final {
|
|
74
|
+
return accu0 + dc.query_to_code(code);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
size_t scan_codes(
|
|
78
|
+
size_t list_size,
|
|
79
|
+
const uint8_t* codes,
|
|
80
|
+
const idx_t* ids,
|
|
81
|
+
ResultHandler& handler) const override {
|
|
82
|
+
return run_scan_codes_fix_C<CMin<float, idx_t>>(
|
|
83
|
+
*this, list_size, codes, ids, handler);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
template <class DCClass>
|
|
88
|
+
struct IVFSQScannerL2 : InvertedListScanner {
|
|
89
|
+
DCClass dc;
|
|
90
|
+
|
|
91
|
+
bool by_residual;
|
|
92
|
+
const Index* quantizer;
|
|
93
|
+
const float* x; /// current query
|
|
94
|
+
|
|
95
|
+
std::vector<float> tmp;
|
|
96
|
+
|
|
97
|
+
IVFSQScannerL2(
|
|
98
|
+
int d,
|
|
99
|
+
const std::vector<float>& trained,
|
|
100
|
+
size_t code_size,
|
|
101
|
+
const Index* quantizer,
|
|
102
|
+
bool store_pairs,
|
|
103
|
+
const IDSelector* sel,
|
|
104
|
+
bool by_residual)
|
|
105
|
+
: dc(d, trained),
|
|
106
|
+
by_residual(by_residual),
|
|
107
|
+
quantizer(quantizer),
|
|
108
|
+
x(nullptr),
|
|
109
|
+
tmp(d) {
|
|
110
|
+
this->store_pairs = store_pairs;
|
|
111
|
+
this->sel = sel;
|
|
112
|
+
this->code_size = code_size;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
void set_query(const float* query) override {
|
|
116
|
+
x = query;
|
|
117
|
+
if (!quantizer) {
|
|
118
|
+
dc.set_query(query);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
void set_list(idx_t list_no, float /*coarse_dis*/) override {
|
|
123
|
+
this->list_no = list_no;
|
|
124
|
+
if (by_residual) {
|
|
125
|
+
quantizer->compute_residual(x, tmp.data(), list_no);
|
|
126
|
+
dc.set_query(tmp.data());
|
|
127
|
+
} else {
|
|
128
|
+
dc.set_query(x);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
float distance_to_code(const uint8_t* code) const final {
|
|
133
|
+
return dc.query_to_code(code);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
size_t scan_codes(
|
|
137
|
+
size_t list_size,
|
|
138
|
+
const uint8_t* codes,
|
|
139
|
+
const idx_t* ids,
|
|
140
|
+
ResultHandler& handler) const override {
|
|
141
|
+
return run_scan_codes_fix_C<CMax<float, idx_t>>(
|
|
142
|
+
*this, list_size, codes, ids, handler);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/*******************************************************************
|
|
147
|
+
* Forward declaration of inverts list scanner
|
|
148
|
+
*******************************************************************/
|
|
149
|
+
|
|
150
|
+
template <SIMDLevel SL>
|
|
151
|
+
InvertedListScanner* sq_select_InvertedListScanner(
|
|
152
|
+
QuantizerType qtype,
|
|
153
|
+
MetricType mt,
|
|
154
|
+
size_t d,
|
|
155
|
+
size_t code_size,
|
|
156
|
+
const std::vector<float>& trained,
|
|
157
|
+
const Index* quantizer,
|
|
158
|
+
bool store_pairs,
|
|
159
|
+
const IDSelector* sel,
|
|
160
|
+
bool by_residual);
|
|
161
|
+
|
|
162
|
+
} // namespace scalar_quantizer
|
|
163
|
+
|
|
164
|
+
} // namespace faiss
|
|
@@ -0,0 +1,94 @@
|
|
|
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 <faiss/impl/ScalarQuantizer.h>
|
|
11
|
+
#include <faiss/utils/simd_levels.h>
|
|
12
|
+
#include <faiss/utils/simdlib.h>
|
|
13
|
+
|
|
14
|
+
namespace faiss {
|
|
15
|
+
|
|
16
|
+
namespace scalar_quantizer {
|
|
17
|
+
|
|
18
|
+
/*******************************************************************
|
|
19
|
+
* Similarity: gets vector components and computes a similarity wrt. a
|
|
20
|
+
* query vector stored in the object. The data fields just encapsulate
|
|
21
|
+
* an accumulator.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
template <SIMDLevel SL>
|
|
25
|
+
struct SimilarityL2 {};
|
|
26
|
+
|
|
27
|
+
template <>
|
|
28
|
+
struct SimilarityL2<SIMDLevel::NONE> {
|
|
29
|
+
static constexpr int simdwidth = 1;
|
|
30
|
+
static constexpr SIMDLevel simd_level = SIMDLevel::NONE;
|
|
31
|
+
static constexpr MetricType metric_type = METRIC_L2;
|
|
32
|
+
|
|
33
|
+
const float *y, *yi;
|
|
34
|
+
|
|
35
|
+
explicit SimilarityL2(const float* y) : y(y), yi(nullptr), accu(0) {}
|
|
36
|
+
|
|
37
|
+
/******* scalar accumulator *******/
|
|
38
|
+
|
|
39
|
+
float accu;
|
|
40
|
+
|
|
41
|
+
FAISS_ALWAYS_INLINE void begin() {
|
|
42
|
+
accu = 0;
|
|
43
|
+
yi = y;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
FAISS_ALWAYS_INLINE void add_component(float x) {
|
|
47
|
+
float tmp = *yi++ - x;
|
|
48
|
+
accu += tmp * tmp;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
FAISS_ALWAYS_INLINE void add_component_2(float x1, float x2) {
|
|
52
|
+
float tmp = x1 - x2;
|
|
53
|
+
accu += tmp * tmp;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
FAISS_ALWAYS_INLINE float result() {
|
|
57
|
+
return accu;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
template <SIMDLevel SL>
|
|
62
|
+
struct SimilarityIP {};
|
|
63
|
+
|
|
64
|
+
template <>
|
|
65
|
+
struct SimilarityIP<SIMDLevel::NONE> {
|
|
66
|
+
static constexpr int simdwidth = 1;
|
|
67
|
+
static constexpr SIMDLevel simd_level = SIMDLevel::NONE;
|
|
68
|
+
static constexpr MetricType metric_type = METRIC_INNER_PRODUCT;
|
|
69
|
+
const float *y, *yi;
|
|
70
|
+
|
|
71
|
+
float accu;
|
|
72
|
+
|
|
73
|
+
explicit SimilarityIP(const float* y) : y(y), yi(nullptr), accu(0) {}
|
|
74
|
+
|
|
75
|
+
FAISS_ALWAYS_INLINE void begin() {
|
|
76
|
+
accu = 0;
|
|
77
|
+
yi = y;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
FAISS_ALWAYS_INLINE void add_component(float x) {
|
|
81
|
+
accu += *yi++ * x;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
FAISS_ALWAYS_INLINE void add_component_2(float x1, float x2) {
|
|
85
|
+
accu += x1 * x2;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
FAISS_ALWAYS_INLINE float result() {
|
|
89
|
+
return accu;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
} // namespace scalar_quantizer
|
|
94
|
+
} // namespace faiss
|