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,329 @@
|
|
|
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/scalar_quantizer/codecs.h>
|
|
11
|
+
#include <faiss/impl/scalar_quantizer/distance_computers.h>
|
|
12
|
+
#include <faiss/impl/scalar_quantizer/quantizers.h>
|
|
13
|
+
#include <faiss/impl/scalar_quantizer/scanners.h>
|
|
14
|
+
#include <faiss/impl/scalar_quantizer/similarities.h>
|
|
15
|
+
|
|
16
|
+
#ifndef THE_LEVEL_TO_DISPATCH
|
|
17
|
+
#error "THE_LEVEL_TO_DISPATCH should be set on input to this header"
|
|
18
|
+
#endif
|
|
19
|
+
|
|
20
|
+
namespace faiss {
|
|
21
|
+
|
|
22
|
+
namespace scalar_quantizer {
|
|
23
|
+
|
|
24
|
+
// Define SL as alias for THE_LEVEL_TO_DISPATCH for use in this file
|
|
25
|
+
constexpr SIMDLevel SL = THE_LEVEL_TO_DISPATCH;
|
|
26
|
+
|
|
27
|
+
// Returns true if dimension d is compatible with the given SIMD level
|
|
28
|
+
template <SIMDLevel SL2>
|
|
29
|
+
constexpr bool is_dimension_compatible(size_t d) {
|
|
30
|
+
if constexpr (SL2 == SIMDLevel::AVX512) {
|
|
31
|
+
return d % 16 == 0;
|
|
32
|
+
} else if constexpr (SL2 == SIMDLevel::AVX2 || SL2 == SIMDLevel::ARM_NEON) {
|
|
33
|
+
return d % 8 == 0;
|
|
34
|
+
} else {
|
|
35
|
+
return true; // SIMDLevel::NONE has no alignment requirements
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/*******************************************************************
|
|
40
|
+
* sq_select_quantizer: the big switch returning SQuantizer*
|
|
41
|
+
*******************************************************************/
|
|
42
|
+
|
|
43
|
+
template <>
|
|
44
|
+
ScalarQuantizer::SQuantizer* sq_select_quantizer<THE_LEVEL_TO_DISPATCH>(
|
|
45
|
+
QuantizerType qtype,
|
|
46
|
+
size_t d,
|
|
47
|
+
const std::vector<float>& trained) {
|
|
48
|
+
// Return nullptr for incompatible dimensions in SIMD cases
|
|
49
|
+
if constexpr (SL != SIMDLevel::NONE) {
|
|
50
|
+
if (!is_dimension_compatible<SL>(d)) {
|
|
51
|
+
return nullptr;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
switch (qtype) {
|
|
55
|
+
case ScalarQuantizer::QT_8bit:
|
|
56
|
+
return new QuantizerTemplate<
|
|
57
|
+
Codec8bit<SL>,
|
|
58
|
+
QuantizerTemplateScaling::NON_UNIFORM,
|
|
59
|
+
SL>(d, trained);
|
|
60
|
+
case ScalarQuantizer::QT_6bit:
|
|
61
|
+
return new QuantizerTemplate<
|
|
62
|
+
Codec6bit<SL>,
|
|
63
|
+
QuantizerTemplateScaling::NON_UNIFORM,
|
|
64
|
+
SL>(d, trained);
|
|
65
|
+
case ScalarQuantizer::QT_4bit:
|
|
66
|
+
return new QuantizerTemplate<
|
|
67
|
+
Codec4bit<SL>,
|
|
68
|
+
QuantizerTemplateScaling::NON_UNIFORM,
|
|
69
|
+
SL>(d, trained);
|
|
70
|
+
case ScalarQuantizer::QT_8bit_uniform:
|
|
71
|
+
return new QuantizerTemplate<
|
|
72
|
+
Codec8bit<SL>,
|
|
73
|
+
QuantizerTemplateScaling::UNIFORM,
|
|
74
|
+
SL>(d, trained);
|
|
75
|
+
case ScalarQuantizer::QT_4bit_uniform:
|
|
76
|
+
return new QuantizerTemplate<
|
|
77
|
+
Codec4bit<SL>,
|
|
78
|
+
QuantizerTemplateScaling::UNIFORM,
|
|
79
|
+
SL>(d, trained);
|
|
80
|
+
case ScalarQuantizer::QT_fp16:
|
|
81
|
+
return new QuantizerFP16<SL>(d, trained);
|
|
82
|
+
case ScalarQuantizer::QT_bf16:
|
|
83
|
+
return new QuantizerBF16<SL>(d, trained);
|
|
84
|
+
case ScalarQuantizer::QT_8bit_direct:
|
|
85
|
+
return new Quantizer8bitDirect<SL>(d, trained);
|
|
86
|
+
case ScalarQuantizer::QT_8bit_direct_signed:
|
|
87
|
+
return new Quantizer8bitDirectSigned<SL>(d, trained);
|
|
88
|
+
default:
|
|
89
|
+
FAISS_THROW_MSG("unknown qtype");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/*******************************************************************
|
|
94
|
+
* select_distance_computer_body: helper for sq_select_distance_computer
|
|
95
|
+
*******************************************************************/
|
|
96
|
+
|
|
97
|
+
template <class Sim, SIMDLevel SL2>
|
|
98
|
+
SQDistanceComputer* select_distance_computer_body(
|
|
99
|
+
ScalarQuantizer::QuantizerType qtype,
|
|
100
|
+
size_t d,
|
|
101
|
+
const std::vector<float>& trained) {
|
|
102
|
+
// Return nullptr for incompatible dimensions in SIMD cases
|
|
103
|
+
if constexpr (SL2 != SIMDLevel::NONE) {
|
|
104
|
+
if (!is_dimension_compatible<SL2>(d)) {
|
|
105
|
+
return nullptr;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
switch (qtype) {
|
|
109
|
+
case ScalarQuantizer::QT_8bit_uniform:
|
|
110
|
+
return new DCTemplate<
|
|
111
|
+
QuantizerTemplate<
|
|
112
|
+
Codec8bit<SL2>,
|
|
113
|
+
QuantizerTemplateScaling::UNIFORM,
|
|
114
|
+
SL2>,
|
|
115
|
+
Sim,
|
|
116
|
+
SL2>(d, trained);
|
|
117
|
+
|
|
118
|
+
case ScalarQuantizer::QT_4bit_uniform:
|
|
119
|
+
return new DCTemplate<
|
|
120
|
+
QuantizerTemplate<
|
|
121
|
+
Codec4bit<SL2>,
|
|
122
|
+
QuantizerTemplateScaling::UNIFORM,
|
|
123
|
+
SL2>,
|
|
124
|
+
Sim,
|
|
125
|
+
SL2>(d, trained);
|
|
126
|
+
|
|
127
|
+
case ScalarQuantizer::QT_8bit:
|
|
128
|
+
return new DCTemplate<
|
|
129
|
+
QuantizerTemplate<
|
|
130
|
+
Codec8bit<SL2>,
|
|
131
|
+
QuantizerTemplateScaling::NON_UNIFORM,
|
|
132
|
+
SL2>,
|
|
133
|
+
Sim,
|
|
134
|
+
SL2>(d, trained);
|
|
135
|
+
|
|
136
|
+
case ScalarQuantizer::QT_6bit:
|
|
137
|
+
return new DCTemplate<
|
|
138
|
+
QuantizerTemplate<
|
|
139
|
+
Codec6bit<SL2>,
|
|
140
|
+
QuantizerTemplateScaling::NON_UNIFORM,
|
|
141
|
+
SL2>,
|
|
142
|
+
Sim,
|
|
143
|
+
SL2>(d, trained);
|
|
144
|
+
|
|
145
|
+
case ScalarQuantizer::QT_4bit:
|
|
146
|
+
return new DCTemplate<
|
|
147
|
+
QuantizerTemplate<
|
|
148
|
+
Codec4bit<SL2>,
|
|
149
|
+
QuantizerTemplateScaling::NON_UNIFORM,
|
|
150
|
+
SL2>,
|
|
151
|
+
Sim,
|
|
152
|
+
SL2>(d, trained);
|
|
153
|
+
|
|
154
|
+
case ScalarQuantizer::QT_fp16:
|
|
155
|
+
return new DCTemplate<QuantizerFP16<SL2>, Sim, SL2>(d, trained);
|
|
156
|
+
|
|
157
|
+
case ScalarQuantizer::QT_bf16:
|
|
158
|
+
return new DCTemplate<QuantizerBF16<SL2>, Sim, SL2>(d, trained);
|
|
159
|
+
|
|
160
|
+
case ScalarQuantizer::QT_8bit_direct:
|
|
161
|
+
if constexpr (SL2 == SIMDLevel::AVX512) {
|
|
162
|
+
if (d % 32 == 0) {
|
|
163
|
+
return new DistanceComputerByte<Sim, SL2>(
|
|
164
|
+
static_cast<int>(d), trained);
|
|
165
|
+
}
|
|
166
|
+
} else if constexpr (SL2 == SIMDLevel::AVX2) {
|
|
167
|
+
if (d % 16 == 0) {
|
|
168
|
+
return new DistanceComputerByte<Sim, SL2>(
|
|
169
|
+
static_cast<int>(d), trained);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return new DCTemplate<Quantizer8bitDirect<SL2>, Sim, SL2>(
|
|
173
|
+
d, trained);
|
|
174
|
+
|
|
175
|
+
case ScalarQuantizer::QT_8bit_direct_signed:
|
|
176
|
+
return new DCTemplate<Quantizer8bitDirectSigned<SL2>, Sim, SL2>(
|
|
177
|
+
d, trained);
|
|
178
|
+
default:
|
|
179
|
+
FAISS_THROW_MSG("unknown qtype");
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/*******************************************************************
|
|
184
|
+
* sq_select_distance_computer: returns SQDistanceComputer*
|
|
185
|
+
*******************************************************************/
|
|
186
|
+
|
|
187
|
+
template <>
|
|
188
|
+
SQDistanceComputer* sq_select_distance_computer<THE_LEVEL_TO_DISPATCH>(
|
|
189
|
+
MetricType metric,
|
|
190
|
+
ScalarQuantizer::QuantizerType qtype,
|
|
191
|
+
size_t d,
|
|
192
|
+
const std::vector<float>& trained) {
|
|
193
|
+
if (metric == METRIC_L2) {
|
|
194
|
+
return select_distance_computer_body<SimilarityL2<SL>, SL>(
|
|
195
|
+
qtype, d, trained);
|
|
196
|
+
} else {
|
|
197
|
+
return select_distance_computer_body<SimilarityIP<SL>, SL>(
|
|
198
|
+
qtype, d, trained);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/*******************************************************************
|
|
203
|
+
* sq_select_InvertedListScanner: returns InvertedListScanner*
|
|
204
|
+
*******************************************************************/
|
|
205
|
+
|
|
206
|
+
template <>
|
|
207
|
+
InvertedListScanner* sq_select_InvertedListScanner<THE_LEVEL_TO_DISPATCH>(
|
|
208
|
+
QuantizerType qtype,
|
|
209
|
+
MetricType mt,
|
|
210
|
+
size_t d,
|
|
211
|
+
size_t code_size,
|
|
212
|
+
const std::vector<float>& trained,
|
|
213
|
+
const Index* quantizer,
|
|
214
|
+
bool store_pairs,
|
|
215
|
+
const IDSelector* sel,
|
|
216
|
+
bool by_residual) {
|
|
217
|
+
auto scan = [&]<class DCClass>() -> InvertedListScanner* {
|
|
218
|
+
if constexpr (DCClass::Sim::metric_type == METRIC_L2) {
|
|
219
|
+
return new IVFSQScannerL2<DCClass>(
|
|
220
|
+
int(d),
|
|
221
|
+
trained,
|
|
222
|
+
code_size,
|
|
223
|
+
quantizer,
|
|
224
|
+
store_pairs,
|
|
225
|
+
sel,
|
|
226
|
+
by_residual);
|
|
227
|
+
} else if constexpr (
|
|
228
|
+
DCClass::Sim::metric_type == METRIC_INNER_PRODUCT) {
|
|
229
|
+
return new IVFSQScannerIP<DCClass>(
|
|
230
|
+
int(d), trained, code_size, store_pairs, sel, by_residual);
|
|
231
|
+
} else {
|
|
232
|
+
FAISS_THROW_MSG("unsupported metric type");
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
auto select_by_simd_and_metric =
|
|
237
|
+
[&]<SIMDLevel SL2, class Similarity>() -> InvertedListScanner* {
|
|
238
|
+
// Return nullptr for incompatible dimensions in SIMD cases
|
|
239
|
+
if constexpr (SL2 != SIMDLevel::NONE) {
|
|
240
|
+
if (!is_dimension_compatible<SL2>(d)) {
|
|
241
|
+
return nullptr;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
switch (qtype) {
|
|
245
|
+
case ScalarQuantizer::QT_8bit_uniform:
|
|
246
|
+
return scan.template operator()<DCTemplate<
|
|
247
|
+
QuantizerTemplate<
|
|
248
|
+
Codec8bit<SL2>,
|
|
249
|
+
QuantizerTemplateScaling::UNIFORM,
|
|
250
|
+
SL2>,
|
|
251
|
+
Similarity,
|
|
252
|
+
SL2>>();
|
|
253
|
+
case ScalarQuantizer::QT_4bit_uniform:
|
|
254
|
+
return scan.template operator()<DCTemplate<
|
|
255
|
+
QuantizerTemplate<
|
|
256
|
+
Codec4bit<SL2>,
|
|
257
|
+
QuantizerTemplateScaling::UNIFORM,
|
|
258
|
+
SL2>,
|
|
259
|
+
Similarity,
|
|
260
|
+
SL2>>();
|
|
261
|
+
case ScalarQuantizer::QT_8bit:
|
|
262
|
+
return scan.template operator()<DCTemplate<
|
|
263
|
+
QuantizerTemplate<
|
|
264
|
+
Codec8bit<SL2>,
|
|
265
|
+
QuantizerTemplateScaling::NON_UNIFORM,
|
|
266
|
+
SL2>,
|
|
267
|
+
Similarity,
|
|
268
|
+
SL2>>();
|
|
269
|
+
case ScalarQuantizer::QT_4bit:
|
|
270
|
+
return scan.template operator()<DCTemplate<
|
|
271
|
+
QuantizerTemplate<
|
|
272
|
+
Codec4bit<SL2>,
|
|
273
|
+
QuantizerTemplateScaling::NON_UNIFORM,
|
|
274
|
+
SL2>,
|
|
275
|
+
Similarity,
|
|
276
|
+
SL2>>();
|
|
277
|
+
case ScalarQuantizer::QT_6bit:
|
|
278
|
+
return scan.template operator()<DCTemplate<
|
|
279
|
+
QuantizerTemplate<
|
|
280
|
+
Codec6bit<SL2>,
|
|
281
|
+
QuantizerTemplateScaling::NON_UNIFORM,
|
|
282
|
+
SL2>,
|
|
283
|
+
Similarity,
|
|
284
|
+
SL2>>();
|
|
285
|
+
case ScalarQuantizer::QT_fp16:
|
|
286
|
+
return scan.template
|
|
287
|
+
operator()<DCTemplate<QuantizerFP16<SL2>, Similarity, SL2>>();
|
|
288
|
+
case ScalarQuantizer::QT_bf16:
|
|
289
|
+
return scan.template
|
|
290
|
+
operator()<DCTemplate<QuantizerBF16<SL2>, Similarity, SL2>>();
|
|
291
|
+
case ScalarQuantizer::QT_8bit_direct:
|
|
292
|
+
if constexpr (SL2 == SIMDLevel::AVX512) {
|
|
293
|
+
if (d % 32 == 0) {
|
|
294
|
+
return scan.template
|
|
295
|
+
operator()<DistanceComputerByte<Similarity, SL2>>();
|
|
296
|
+
}
|
|
297
|
+
} else if constexpr (SL2 == SIMDLevel::AVX2) {
|
|
298
|
+
if (d % 16 == 0) {
|
|
299
|
+
return scan.template
|
|
300
|
+
operator()<DistanceComputerByte<Similarity, SL2>>();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return scan.template operator()<DCTemplate<
|
|
304
|
+
Quantizer8bitDirect<SL2>,
|
|
305
|
+
Similarity,
|
|
306
|
+
SL2>>();
|
|
307
|
+
case ScalarQuantizer::QT_8bit_direct_signed:
|
|
308
|
+
return scan.template operator()<DCTemplate<
|
|
309
|
+
Quantizer8bitDirectSigned<SL2>,
|
|
310
|
+
Similarity,
|
|
311
|
+
SL2>>();
|
|
312
|
+
default:
|
|
313
|
+
FAISS_THROW_MSG("unknown qtype");
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
if (mt == METRIC_L2) {
|
|
318
|
+
return select_by_simd_and_metric
|
|
319
|
+
.template operator()<SL, SimilarityL2<SL>>();
|
|
320
|
+
} else if (mt == METRIC_INNER_PRODUCT) {
|
|
321
|
+
return select_by_simd_and_metric
|
|
322
|
+
.template operator()<SL, SimilarityIP<SL>>();
|
|
323
|
+
}
|
|
324
|
+
FAISS_THROW_MSG("unsupported metric type");
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
} // namespace scalar_quantizer
|
|
328
|
+
|
|
329
|
+
} // namespace faiss
|