faiss 0.6.2 → 0.6.3
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/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +3 -1
- data/vendor/faiss/faiss/Clustering.cpp +9 -1
- data/vendor/faiss/faiss/IVFlib.cpp +14 -3
- data/vendor/faiss/faiss/Index.h +2 -2
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +9 -10
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +2 -3
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +1 -2
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +4 -5
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +5 -9
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +2 -4
- data/vendor/faiss/faiss/IndexEDEN.cpp +273 -0
- data/vendor/faiss/faiss/IndexEDEN.h +57 -0
- data/vendor/faiss/faiss/IndexFastScan.cpp +15 -4
- data/vendor/faiss/faiss/IndexFlat.cpp +13 -50
- data/vendor/faiss/faiss/IndexHNSW.cpp +10 -11
- data/vendor/faiss/faiss/IndexIDMap.cpp +16 -3
- data/vendor/faiss/faiss/IndexIDMap.h +2 -0
- data/vendor/faiss/faiss/IndexIVF.cpp +17 -6
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +3 -4
- data/vendor/faiss/faiss/IndexIVFEDEN.cpp +302 -0
- data/vendor/faiss/faiss/IndexIVFEDEN.h +70 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +5 -6
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +3 -4
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +40 -22
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +0 -1
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +19 -49
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +180 -76
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +5 -4
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +8 -6
- data/vendor/faiss/faiss/IndexLSH.cpp +2 -3
- data/vendor/faiss/faiss/IndexLattice.cpp +5 -0
- data/vendor/faiss/faiss/IndexNNDescent.cpp +9 -2
- data/vendor/faiss/faiss/IndexNSG.cpp +7 -2
- data/vendor/faiss/faiss/IndexPQ.cpp +6 -8
- data/vendor/faiss/faiss/IndexPreTransform.cpp +15 -0
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +2 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +1 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +5 -1
- data/vendor/faiss/faiss/IndexRefine.cpp +30 -1
- data/vendor/faiss/faiss/IndexReplicas.cpp +1 -2
- data/vendor/faiss/faiss/IndexShards.cpp +2 -2
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +2 -2
- data/vendor/faiss/faiss/MetaIndexes.cpp +2 -4
- data/vendor/faiss/faiss/SuperKMeans.cpp +256 -240
- data/vendor/faiss/faiss/SuperKMeans.h +30 -0
- data/vendor/faiss/faiss/VectorTransform.cpp +33 -2
- data/vendor/faiss/faiss/clone_index.cpp +5 -0
- data/vendor/faiss/faiss/factory_tools.cpp +47 -4
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +11 -11
- data/vendor/faiss/faiss/gpu/GpuIndex.h +34 -11
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +47 -0
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +17 -0
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +16 -0
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +1 -1
- data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +2 -2
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +180 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +1 -5
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFPQ.h +88 -0
- data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFPQ.h +134 -0
- data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +2 -2
- data/vendor/faiss/faiss/impl/DistanceComputer.h +34 -0
- data/vendor/faiss/faiss/impl/EDENQuantizer.h +119 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +109 -152
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +2 -2
- data/vendor/faiss/faiss/impl/NSG.cpp +3 -1
- data/vendor/faiss/faiss/impl/Panorama.h +9 -7
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +152 -84
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +34 -22
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +44 -36
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +35 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +168 -67
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +19 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +2 -11
- data/vendor/faiss/faiss/impl/ResultHandler.h +25 -31
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +258 -57
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +20 -0
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +2 -2
- data/vendor/faiss/faiss/impl/VisitedTable.cpp +22 -2
- data/vendor/faiss/faiss/impl/VisitedTable.h +20 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +1 -1
- data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +4 -4
- data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +35 -2
- data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +1 -1
- data/vendor/faiss/faiss/impl/index_read.cpp +376 -36
- data/vendor/faiss/faiss/impl/index_write.cpp +55 -4
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +8 -9
- data/vendor/faiss/faiss/impl/platform_macros.h +3 -1
- data/vendor/faiss/faiss/impl/polysemous_training/avx512.cpp +284 -0
- data/vendor/faiss/faiss/impl/polysemous_training/dispatch.h +115 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +0 -1
- data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +26 -15
- data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +4 -4
- data/vendor/faiss/faiss/impl/result_handler/ResultHandler.cpp +195 -0
- data/vendor/faiss/faiss/impl/result_handler/avx2.cpp +133 -0
- data/vendor/faiss/faiss/impl/result_handler/avx512.cpp +281 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx2.cpp +72 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx512.cpp +228 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer.cpp +882 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +9 -8
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +85 -23
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +30 -30
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +4 -5
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +101 -34
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +136 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +16 -16
- data/vendor/faiss/faiss/impl/simd_dispatch.h +30 -9
- data/vendor/faiss/faiss/index_factory.cpp +32 -6
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -1
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +2 -2
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +19 -4
- data/vendor/faiss/faiss/python/python_callbacks.cpp +3 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +60 -0
- data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +26 -1
- data/vendor/faiss/faiss/svs/IndexSVSFlat.h +13 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +31 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +15 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +1 -2
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +1 -1
- data/vendor/faiss/faiss/utils/distances.cpp +14 -2
- data/vendor/faiss/faiss/utils/distances_simd.cpp +4 -3
- data/vendor/faiss/faiss/utils/extra_distances.cpp +4 -14
- data/vendor/faiss/faiss/utils/extra_distances.h +1 -2
- data/vendor/faiss/faiss/utils/hamming.cpp +1 -1
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +29 -8
- data/vendor/faiss/faiss/utils/rabitq_simd.h +202 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +0 -1
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +263 -15
- data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +160 -18
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +245 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +273 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512_spr.cpp +92 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +11 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +143 -6
- data/vendor/faiss/faiss/utils/simd_levels.cpp +44 -0
- data/vendor/faiss/faiss/utils/simd_levels.h +14 -0
- data/vendor/faiss/faiss/utils/utils.cpp +9 -27
- metadata +16 -1
|
@@ -147,14 +147,13 @@ struct QuantizerTemplate<
|
|
|
147
147
|
};
|
|
148
148
|
|
|
149
149
|
/*******************************************************************
|
|
150
|
-
*
|
|
150
|
+
* Lloyd-Max scalar quantizer
|
|
151
151
|
*******************************************************************/
|
|
152
152
|
template <int NBits, SIMDLevel SL>
|
|
153
|
-
struct
|
|
153
|
+
struct QuantizerLloydMax;
|
|
154
154
|
|
|
155
155
|
template <int NBits>
|
|
156
|
-
struct
|
|
157
|
-
: ScalarQuantizer::SQuantizer {
|
|
156
|
+
struct QuantizerLloydMax<NBits, SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
|
|
158
157
|
static_assert(NBits >= 1 && NBits <= 8);
|
|
159
158
|
|
|
160
159
|
static constexpr size_t kCentroidsCount = size_t(1) << NBits;
|
|
@@ -165,7 +164,7 @@ struct QuantizerTurboQuantMSE<NBits, SIMDLevel::NONE>
|
|
|
165
164
|
const float* centroids;
|
|
166
165
|
const float* boundaries;
|
|
167
166
|
|
|
168
|
-
|
|
167
|
+
QuantizerLloydMax(size_t d_in, const std::vector<float>& trained)
|
|
169
168
|
: d(d_in), centroids(nullptr), boundaries(nullptr) {
|
|
170
169
|
FAISS_THROW_IF_NOT(trained.size() == 2 * kCentroidsCount - 1);
|
|
171
170
|
centroids = trained.data();
|
|
@@ -221,11 +220,13 @@ struct QuantizerTurboQuantMSE<NBits, SIMDLevel::NONE>
|
|
|
221
220
|
};
|
|
222
221
|
|
|
223
222
|
template <int NBits, SIMDLevel SL>
|
|
224
|
-
struct
|
|
225
|
-
using
|
|
226
|
-
QuantizerTurboQuantMSE;
|
|
223
|
+
struct QuantizerLloydMax : QuantizerLloydMax<NBits, SIMDLevel::NONE> {
|
|
224
|
+
using QuantizerLloydMax<NBits, SIMDLevel::NONE>::QuantizerLloydMax;
|
|
227
225
|
};
|
|
228
226
|
|
|
227
|
+
template <int NBits, SIMDLevel SL>
|
|
228
|
+
using QuantizerTurboQuantMSE = QuantizerLloydMax<NBits, SL>;
|
|
229
|
+
|
|
229
230
|
/*******************************************************************
|
|
230
231
|
* FP16 quantizer
|
|
231
232
|
*******************************************************************/
|
|
@@ -232,7 +232,7 @@ struct QuantizerTemplate<
|
|
|
232
232
|
};
|
|
233
233
|
|
|
234
234
|
/**********************************************************
|
|
235
|
-
*
|
|
235
|
+
* Lloyd-Max scalar quantizer
|
|
236
236
|
**********************************************************/
|
|
237
237
|
|
|
238
238
|
// 1-bit MSE: boundary is always at centroids midpoint.
|
|
@@ -240,11 +240,11 @@ struct QuantizerTemplate<
|
|
|
240
240
|
// Decode: gather 8 centroids via index unpack.
|
|
241
241
|
// NOLINTNEXTLINE(facebook-hte-MisplacedTemplateSpecialization,facebook-hte-ShadowingClass)
|
|
242
242
|
template <>
|
|
243
|
-
struct
|
|
244
|
-
:
|
|
245
|
-
using Base =
|
|
243
|
+
struct QuantizerLloydMax<1, SIMDLevel::AVX2>
|
|
244
|
+
: QuantizerLloydMax<1, SIMDLevel::NONE> {
|
|
245
|
+
using Base = QuantizerLloydMax<1, SIMDLevel::NONE>;
|
|
246
246
|
|
|
247
|
-
|
|
247
|
+
QuantizerLloydMax(size_t d, const std::vector<float>& trained)
|
|
248
248
|
: Base(d, trained) {
|
|
249
249
|
assert(d % 8 == 0);
|
|
250
250
|
}
|
|
@@ -279,11 +279,11 @@ struct QuantizerTurboQuantMSE<1, SIMDLevel::AVX2>
|
|
|
279
279
|
// Decode: gather via index unpack.
|
|
280
280
|
// NOLINTNEXTLINE(facebook-hte-MisplacedTemplateSpecialization,facebook-hte-ShadowingClass)
|
|
281
281
|
template <>
|
|
282
|
-
struct
|
|
283
|
-
:
|
|
284
|
-
using Base =
|
|
282
|
+
struct QuantizerLloydMax<2, SIMDLevel::AVX2>
|
|
283
|
+
: QuantizerLloydMax<2, SIMDLevel::NONE> {
|
|
284
|
+
using Base = QuantizerLloydMax<2, SIMDLevel::NONE>;
|
|
285
285
|
|
|
286
|
-
|
|
286
|
+
QuantizerLloydMax(size_t d, const std::vector<float>& trained)
|
|
287
287
|
: Base(d, trained) {
|
|
288
288
|
assert(d % 8 == 0);
|
|
289
289
|
}
|
|
@@ -334,15 +334,15 @@ struct QuantizerTurboQuantMSE<2, SIMDLevel::AVX2>
|
|
|
334
334
|
}
|
|
335
335
|
};
|
|
336
336
|
|
|
337
|
-
// 3-bit and 4-bit
|
|
337
|
+
// 3-bit and 4-bit Lloyd-Max: use branchless comparison chain for encode.
|
|
338
338
|
// k boundaries → idx = sum of k-1 comparisons.
|
|
339
|
-
#define
|
|
339
|
+
#define DEFINE_LLOYD_MAX_AVX2_MULTIBIT(NBITS, UNPACK_EXPR) \
|
|
340
340
|
template <> \
|
|
341
|
-
struct
|
|
342
|
-
:
|
|
343
|
-
using Base =
|
|
341
|
+
struct QuantizerLloydMax<NBITS, SIMDLevel::AVX2> \
|
|
342
|
+
: QuantizerLloydMax<NBITS, SIMDLevel::NONE> { \
|
|
343
|
+
using Base = QuantizerLloydMax<NBITS, SIMDLevel::NONE>; \
|
|
344
344
|
\
|
|
345
|
-
|
|
345
|
+
QuantizerLloydMax(size_t d, const std::vector<float>& trained) \
|
|
346
346
|
: Base(d, trained) { \
|
|
347
347
|
assert(d % 8 == 0); \
|
|
348
348
|
} \
|
|
@@ -362,18 +362,18 @@ struct QuantizerTurboQuantMSE<2, SIMDLevel::AVX2>
|
|
|
362
362
|
} \
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
-
|
|
366
|
-
|
|
365
|
+
DEFINE_LLOYD_MAX_AVX2_MULTIBIT(3, unpack_8x3bit_to_u32(code, i));
|
|
366
|
+
DEFINE_LLOYD_MAX_AVX2_MULTIBIT(4, unpack_8x4bit_to_u32(code, i));
|
|
367
367
|
|
|
368
|
-
#undef
|
|
368
|
+
#undef DEFINE_LLOYD_MAX_AVX2_MULTIBIT
|
|
369
369
|
|
|
370
|
-
// 8-bit
|
|
370
|
+
// 8-bit Lloyd-Max: indices are raw bytes, no bit packing.
|
|
371
371
|
template <>
|
|
372
|
-
struct
|
|
373
|
-
:
|
|
374
|
-
using Base =
|
|
372
|
+
struct QuantizerLloydMax<8, SIMDLevel::AVX2>
|
|
373
|
+
: QuantizerLloydMax<8, SIMDLevel::NONE> {
|
|
374
|
+
using Base = QuantizerLloydMax<8, SIMDLevel::NONE>;
|
|
375
375
|
|
|
376
|
-
|
|
376
|
+
QuantizerLloydMax(size_t d, const std::vector<float>& trained)
|
|
377
377
|
: Base(d, trained) {
|
|
378
378
|
assert(d % 8 == 0);
|
|
379
379
|
}
|
|
@@ -787,6 +787,68 @@ struct DistanceComputerByte<Similarity, SIMDLevel::AVX2> : SQDistanceComputer {
|
|
|
787
787
|
}
|
|
788
788
|
};
|
|
789
789
|
|
|
790
|
+
template <class Similarity>
|
|
791
|
+
struct DistanceComputerByteSigned<Similarity, SIMDLevel::AVX2>
|
|
792
|
+
: SQDistanceComputer {
|
|
793
|
+
using Sim = Similarity;
|
|
794
|
+
|
|
795
|
+
int d;
|
|
796
|
+
std::vector<uint8_t> tmp;
|
|
797
|
+
|
|
798
|
+
DistanceComputerByteSigned(int d, const std::vector<float>&)
|
|
799
|
+
: d(d), tmp(d) {}
|
|
800
|
+
|
|
801
|
+
int compute_code_distance(const uint8_t* code1, const uint8_t* code2)
|
|
802
|
+
const {
|
|
803
|
+
// codes store value + 128. madd_epi16 is signed, so IP unbiases the
|
|
804
|
+
// bytes before multiplying; for L2 the +128 cancels in the difference.
|
|
805
|
+
// Only dispatched for d % 16 == 0, so the loop needs no tail.
|
|
806
|
+
__m256i accu = _mm256_setzero_si256();
|
|
807
|
+
for (int i = 0; i < d; i += 16) {
|
|
808
|
+
__m256i c1 = _mm256_cvtepu8_epi16(
|
|
809
|
+
_mm_loadu_si128((const __m128i*)(code1 + i)));
|
|
810
|
+
__m256i c2 = _mm256_cvtepu8_epi16(
|
|
811
|
+
_mm_loadu_si128((const __m128i*)(code2 + i)));
|
|
812
|
+
__m256i prod32;
|
|
813
|
+
if (Sim::metric_type == METRIC_INNER_PRODUCT) {
|
|
814
|
+
const __m256i bias = _mm256_set1_epi16(128);
|
|
815
|
+
c1 = _mm256_sub_epi16(c1, bias);
|
|
816
|
+
c2 = _mm256_sub_epi16(c2, bias);
|
|
817
|
+
prod32 = _mm256_madd_epi16(c1, c2);
|
|
818
|
+
} else {
|
|
819
|
+
__m256i diff = _mm256_sub_epi16(c1, c2);
|
|
820
|
+
prod32 = _mm256_madd_epi16(diff, diff);
|
|
821
|
+
}
|
|
822
|
+
accu = _mm256_add_epi32(accu, prod32);
|
|
823
|
+
}
|
|
824
|
+
__m128i sum = _mm256_extractf128_si256(accu, 0);
|
|
825
|
+
sum = _mm_add_epi32(sum, _mm256_extractf128_si256(accu, 1));
|
|
826
|
+
sum = _mm_hadd_epi32(sum, sum);
|
|
827
|
+
sum = _mm_hadd_epi32(sum, sum);
|
|
828
|
+
return _mm_cvtsi128_si32(sum);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
void set_query(const float* x) final {
|
|
832
|
+
for (int i = 0; i < d; i++) {
|
|
833
|
+
tmp[i] = uint8_t(int(x[i]) + 128);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
int compute_distance(const float* x, const uint8_t* code) {
|
|
838
|
+
set_query(x);
|
|
839
|
+
return compute_code_distance(tmp.data(), code);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
float symmetric_dis(idx_t i, idx_t j) override {
|
|
843
|
+
return compute_code_distance(
|
|
844
|
+
codes + i * code_size, codes + j * code_size);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
float query_to_code(const uint8_t* code) const final {
|
|
848
|
+
return compute_code_distance(tmp.data(), code);
|
|
849
|
+
}
|
|
850
|
+
};
|
|
851
|
+
|
|
790
852
|
/**********************************************************
|
|
791
853
|
* TurboQuant masked_sum AVX2 specialization
|
|
792
854
|
**********************************************************/
|
|
@@ -241,41 +241,41 @@ struct QuantizerTemplate<
|
|
|
241
241
|
};
|
|
242
242
|
|
|
243
243
|
/**********************************************************
|
|
244
|
-
*
|
|
244
|
+
* Lloyd-Max scalar quantizer
|
|
245
245
|
**********************************************************/
|
|
246
246
|
|
|
247
|
-
#define
|
|
248
|
-
template <>
|
|
249
|
-
struct
|
|
250
|
-
:
|
|
251
|
-
using Base =
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
: Base(d, trained) {
|
|
255
|
-
assert(d % 16 == 0);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
FAISS_ALWAYS_INLINE simd16float32
|
|
259
|
-
reconstruct_16_components(const uint8_t* code, int i) const {
|
|
260
|
-
const __m512i indices = (INDEX_EXPR);
|
|
261
|
-
return simd16float32(_mm512_i32gather_ps(
|
|
262
|
-
indices, this->centroids, sizeof(float)));
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
#undef
|
|
247
|
+
#define DEFINE_LLOYD_MAX_AVX512_SPECIALIZATION(NBITS, INDEX_EXPR) \
|
|
248
|
+
template <> \
|
|
249
|
+
struct QuantizerLloydMax<NBITS, SIMDLevel::AVX512> \
|
|
250
|
+
: QuantizerLloydMax<NBITS, SIMDLevel::NONE> { \
|
|
251
|
+
using Base = QuantizerLloydMax<NBITS, SIMDLevel::NONE>; \
|
|
252
|
+
\
|
|
253
|
+
QuantizerLloydMax(size_t d, const std::vector<float>& trained) \
|
|
254
|
+
: Base(d, trained) { \
|
|
255
|
+
assert(d % 16 == 0); \
|
|
256
|
+
} \
|
|
257
|
+
\
|
|
258
|
+
FAISS_ALWAYS_INLINE simd16float32 \
|
|
259
|
+
reconstruct_16_components(const uint8_t* code, int i) const { \
|
|
260
|
+
const __m512i indices = (INDEX_EXPR); \
|
|
261
|
+
return simd16float32(_mm512_i32gather_ps( \
|
|
262
|
+
indices, this->centroids, sizeof(float))); \
|
|
263
|
+
} \
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
DEFINE_LLOYD_MAX_AVX512_SPECIALIZATION(1, unpack_16x1bit_to_u32(code, i));
|
|
267
|
+
DEFINE_LLOYD_MAX_AVX512_SPECIALIZATION(2, unpack_16x2bit_to_u32(code, i));
|
|
268
|
+
DEFINE_LLOYD_MAX_AVX512_SPECIALIZATION(3, unpack_16x3bit_to_u32(code, i));
|
|
269
|
+
DEFINE_LLOYD_MAX_AVX512_SPECIALIZATION(4, unpack_16x4bit_to_u32(code, i));
|
|
270
|
+
|
|
271
|
+
#undef DEFINE_LLOYD_MAX_AVX512_SPECIALIZATION
|
|
272
272
|
|
|
273
273
|
template <>
|
|
274
|
-
struct
|
|
275
|
-
:
|
|
276
|
-
using Base =
|
|
274
|
+
struct QuantizerLloydMax<8, SIMDLevel::AVX512>
|
|
275
|
+
: QuantizerLloydMax<8, SIMDLevel::NONE> {
|
|
276
|
+
using Base = QuantizerLloydMax<8, SIMDLevel::NONE>;
|
|
277
277
|
|
|
278
|
-
|
|
278
|
+
QuantizerLloydMax(size_t d, const std::vector<float>& trained)
|
|
279
279
|
: Base(d, trained) {
|
|
280
280
|
assert(d % 16 == 0);
|
|
281
281
|
}
|
|
@@ -100,14 +100,13 @@ struct Quantizer8bitDirectSigned<SIMDLevel::AVX512_SPR>
|
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
/**********************************************************
|
|
103
|
-
*
|
|
103
|
+
* Lloyd-Max scalar quantizer - inherit AVX512 implementations
|
|
104
104
|
**********************************************************/
|
|
105
105
|
|
|
106
106
|
template <int NBits>
|
|
107
|
-
struct
|
|
108
|
-
:
|
|
109
|
-
using
|
|
110
|
-
QuantizerTurboQuantMSE;
|
|
107
|
+
struct QuantizerLloydMax<NBits, SIMDLevel::AVX512_SPR>
|
|
108
|
+
: QuantizerLloydMax<NBits, SIMDLevel::AVX512> {
|
|
109
|
+
using QuantizerLloydMax<NBits, SIMDLevel::AVX512>::QuantizerLloydMax;
|
|
111
110
|
};
|
|
112
111
|
|
|
113
112
|
/**********************************************************
|
|
@@ -250,16 +250,16 @@ struct QuantizerTemplate<
|
|
|
250
250
|
};
|
|
251
251
|
|
|
252
252
|
/**********************************************************
|
|
253
|
-
*
|
|
253
|
+
* Lloyd-Max scalar quantizer
|
|
254
254
|
**********************************************************/
|
|
255
255
|
|
|
256
|
-
// 1-bit
|
|
256
|
+
// 1-bit Lloyd-Max AVX512: 16 comparisons → 2 bytes via mask compare.
|
|
257
257
|
template <>
|
|
258
|
-
struct
|
|
259
|
-
:
|
|
260
|
-
using Base =
|
|
258
|
+
struct QuantizerLloydMax<1, SIMDLevel::AVX512>
|
|
259
|
+
: QuantizerLloydMax<1, SIMDLevel::NONE> {
|
|
260
|
+
using Base = QuantizerLloydMax<1, SIMDLevel::NONE>;
|
|
261
261
|
|
|
262
|
-
|
|
262
|
+
QuantizerLloydMax(size_t d, const std::vector<float>& trained)
|
|
263
263
|
: Base(d, trained) {
|
|
264
264
|
assert(d % 16 == 0);
|
|
265
265
|
}
|
|
@@ -291,14 +291,14 @@ struct QuantizerTurboQuantMSE<1, SIMDLevel::AVX512>
|
|
|
291
291
|
}
|
|
292
292
|
};
|
|
293
293
|
|
|
294
|
-
// 2-4 bit
|
|
295
|
-
#define
|
|
294
|
+
// 2-4 bit Lloyd-Max AVX512: decode via gather, encode stays scalar.
|
|
295
|
+
#define DEFINE_LLOYD_MAX_AVX512_MULTIBIT(NBITS, UNPACK_EXPR) \
|
|
296
296
|
template <> \
|
|
297
|
-
struct
|
|
298
|
-
:
|
|
299
|
-
using Base =
|
|
297
|
+
struct QuantizerLloydMax<NBITS, SIMDLevel::AVX512> \
|
|
298
|
+
: QuantizerLloydMax<NBITS, SIMDLevel::NONE> { \
|
|
299
|
+
using Base = QuantizerLloydMax<NBITS, SIMDLevel::NONE>; \
|
|
300
300
|
\
|
|
301
|
-
|
|
301
|
+
QuantizerLloydMax(size_t d, const std::vector<float>& trained) \
|
|
302
302
|
: Base(d, trained) { \
|
|
303
303
|
assert(d % 16 == 0); \
|
|
304
304
|
} \
|
|
@@ -318,19 +318,19 @@ struct QuantizerTurboQuantMSE<1, SIMDLevel::AVX512>
|
|
|
318
318
|
} \
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
321
|
+
DEFINE_LLOYD_MAX_AVX512_MULTIBIT(2, unpack_16x2bit_to_u32(code, i));
|
|
322
|
+
DEFINE_LLOYD_MAX_AVX512_MULTIBIT(3, unpack_16x3bit_to_u32(code, i));
|
|
323
|
+
DEFINE_LLOYD_MAX_AVX512_MULTIBIT(4, unpack_16x4bit_to_u32(code, i));
|
|
324
324
|
|
|
325
|
-
#undef
|
|
325
|
+
#undef DEFINE_LLOYD_MAX_AVX512_MULTIBIT
|
|
326
326
|
|
|
327
|
-
// 8-bit
|
|
327
|
+
// 8-bit Lloyd-Max AVX512
|
|
328
328
|
template <>
|
|
329
|
-
struct
|
|
330
|
-
:
|
|
331
|
-
using Base =
|
|
329
|
+
struct QuantizerLloydMax<8, SIMDLevel::AVX512>
|
|
330
|
+
: QuantizerLloydMax<8, SIMDLevel::NONE> {
|
|
331
|
+
using Base = QuantizerLloydMax<8, SIMDLevel::NONE>;
|
|
332
332
|
|
|
333
|
-
|
|
333
|
+
QuantizerLloydMax(size_t d, const std::vector<float>& trained)
|
|
334
334
|
: Base(d, trained) {
|
|
335
335
|
assert(d % 16 == 0);
|
|
336
336
|
}
|
|
@@ -677,24 +677,36 @@ struct DistanceComputerByte<Similarity, SIMDLevel::AVX512>
|
|
|
677
677
|
|
|
678
678
|
int compute_code_distance(const uint8_t* code1, const uint8_t* code2)
|
|
679
679
|
const {
|
|
680
|
-
// compute
|
|
680
|
+
// compute 32 lanes of 16-bit products (32-bytes) at once for
|
|
681
681
|
// the supported metrics
|
|
682
682
|
__m512i accu = _mm512_setzero_si512();
|
|
683
|
-
constexpr int kLanes =
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
__m512i
|
|
689
|
-
|
|
690
|
-
__m512i v;
|
|
683
|
+
constexpr int kLanes = 32;
|
|
684
|
+
int i = 0;
|
|
685
|
+
for (; i + kLanes <= d; i += kLanes) {
|
|
686
|
+
__m256i c1 = _mm256_loadu_epi8(code1 + i);
|
|
687
|
+
__m256i c2 = _mm256_loadu_epi8(code2 + i);
|
|
688
|
+
__m512i c1i16 = _mm512_cvtepu8_epi16(c1);
|
|
689
|
+
__m512i c2i16 = _mm512_cvtepu8_epi16(c2);
|
|
691
690
|
if (Sim::metric_type == METRIC_INNER_PRODUCT) {
|
|
692
|
-
|
|
691
|
+
accu = _mm512_add_epi32(accu, _mm512_madd_epi16(c1i16, c2i16));
|
|
693
692
|
} else {
|
|
694
|
-
__m512i diff =
|
|
695
|
-
|
|
693
|
+
__m512i diff = _mm512_sub_epi16(c1i16, c2i16);
|
|
694
|
+
accu = _mm512_add_epi32(accu, _mm512_madd_epi16(diff, diff));
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
// tail handling for dimensions not divisible by 32
|
|
698
|
+
if (i < d) {
|
|
699
|
+
__mmask32 mask = (__mmask32)((1ULL << (d - i)) - 1ULL);
|
|
700
|
+
__m256i c1 = _mm256_maskz_loadu_epi8(mask, code1 + i);
|
|
701
|
+
__m256i c2 = _mm256_maskz_loadu_epi8(mask, code2 + i);
|
|
702
|
+
__m512i c1i16 = _mm512_cvtepu8_epi16(c1);
|
|
703
|
+
__m512i c2i16 = _mm512_cvtepu8_epi16(c2);
|
|
704
|
+
if (Sim::metric_type == METRIC_INNER_PRODUCT) {
|
|
705
|
+
accu = _mm512_add_epi32(accu, _mm512_madd_epi16(c1i16, c2i16));
|
|
706
|
+
} else {
|
|
707
|
+
__m512i diff = _mm512_sub_epi16(c1i16, c2i16);
|
|
708
|
+
accu = _mm512_add_epi32(accu, _mm512_madd_epi16(diff, diff));
|
|
696
709
|
}
|
|
697
|
-
accu = _mm512_add_epi32(accu, v);
|
|
698
710
|
}
|
|
699
711
|
return _mm512_reduce_add_epi32(accu);
|
|
700
712
|
}
|
|
@@ -720,6 +732,61 @@ struct DistanceComputerByte<Similarity, SIMDLevel::AVX512>
|
|
|
720
732
|
}
|
|
721
733
|
};
|
|
722
734
|
|
|
735
|
+
template <class Similarity>
|
|
736
|
+
struct DistanceComputerByteSigned<Similarity, SIMDLevel::AVX512>
|
|
737
|
+
: SQDistanceComputer {
|
|
738
|
+
using Sim = Similarity;
|
|
739
|
+
|
|
740
|
+
int d;
|
|
741
|
+
std::vector<uint8_t> tmp;
|
|
742
|
+
|
|
743
|
+
DistanceComputerByteSigned(int d, const std::vector<float>&)
|
|
744
|
+
: d(d), tmp(d) {}
|
|
745
|
+
|
|
746
|
+
int compute_code_distance(const uint8_t* code1, const uint8_t* code2)
|
|
747
|
+
const {
|
|
748
|
+
// codes store value + 128. madd_epi16 is signed, so IP unbiases the
|
|
749
|
+
// bytes before multiplying; for L2 the +128 cancels in the difference.
|
|
750
|
+
// Only dispatched for d % 32 == 0, so the loop needs no tail.
|
|
751
|
+
__m512i accu = _mm512_setzero_si512();
|
|
752
|
+
constexpr int kLanes = 32;
|
|
753
|
+
for (int i = 0; i + kLanes <= d; i += kLanes) {
|
|
754
|
+
__m512i c1 = _mm512_cvtepu8_epi16(_mm256_loadu_epi8(code1 + i));
|
|
755
|
+
__m512i c2 = _mm512_cvtepu8_epi16(_mm256_loadu_epi8(code2 + i));
|
|
756
|
+
if (Sim::metric_type == METRIC_INNER_PRODUCT) {
|
|
757
|
+
const __m512i bias = _mm512_set1_epi16(128);
|
|
758
|
+
c1 = _mm512_sub_epi16(c1, bias);
|
|
759
|
+
c2 = _mm512_sub_epi16(c2, bias);
|
|
760
|
+
accu = _mm512_add_epi32(accu, _mm512_madd_epi16(c1, c2));
|
|
761
|
+
} else {
|
|
762
|
+
__m512i diff = _mm512_sub_epi16(c1, c2);
|
|
763
|
+
accu = _mm512_add_epi32(accu, _mm512_madd_epi16(diff, diff));
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
return _mm512_reduce_add_epi32(accu);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
void set_query(const float* x) final {
|
|
770
|
+
for (int i = 0; i < d; i++) {
|
|
771
|
+
tmp[i] = uint8_t(int(x[i]) + 128);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
int compute_distance(const float* x, const uint8_t* code) {
|
|
776
|
+
set_query(x);
|
|
777
|
+
return compute_code_distance(tmp.data(), code);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
float symmetric_dis(idx_t i, idx_t j) override {
|
|
781
|
+
return compute_code_distance(
|
|
782
|
+
codes + i * code_size, codes + j * code_size);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
float query_to_code(const uint8_t* code) const final {
|
|
786
|
+
return compute_code_distance(tmp.data(), code);
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
|
|
723
790
|
/**********************************************************
|
|
724
791
|
* TurboQuant masked_sum AVX512 specialization
|
|
725
792
|
**********************************************************/
|
|
@@ -416,6 +416,34 @@ ScalarQuantizer::SQuantizer* sq_select_quantizer<THE_LEVEL_TO_DISPATCH>(
|
|
|
416
416
|
return new QuantizerTurboQuantMSE<4, SL>(d, trained);
|
|
417
417
|
case ScalarQuantizer::QT_8bit_tqmse:
|
|
418
418
|
return new QuantizerTurboQuantMSE<8, SL>(d, trained);
|
|
419
|
+
case ScalarQuantizer::QT_1bit_eden:
|
|
420
|
+
return new QuantizerLloydMax<1, SL>(d, trained);
|
|
421
|
+
case ScalarQuantizer::QT_2bit_eden:
|
|
422
|
+
return new QuantizerLloydMax<2, SL>(d, trained);
|
|
423
|
+
case ScalarQuantizer::QT_3bit_eden:
|
|
424
|
+
return new QuantizerLloydMax<3, SL>(d, trained);
|
|
425
|
+
case ScalarQuantizer::QT_4bit_eden:
|
|
426
|
+
return new QuantizerLloydMax<4, SL>(d, trained);
|
|
427
|
+
case ScalarQuantizer::QT_5bit_eden:
|
|
428
|
+
if constexpr (SL != SIMDLevel::NONE) {
|
|
429
|
+
return nullptr;
|
|
430
|
+
} else {
|
|
431
|
+
return new QuantizerLloydMax<5, SL>(d, trained);
|
|
432
|
+
}
|
|
433
|
+
case ScalarQuantizer::QT_6bit_eden:
|
|
434
|
+
if constexpr (SL != SIMDLevel::NONE) {
|
|
435
|
+
return nullptr;
|
|
436
|
+
} else {
|
|
437
|
+
return new QuantizerLloydMax<6, SL>(d, trained);
|
|
438
|
+
}
|
|
439
|
+
case ScalarQuantizer::QT_7bit_eden:
|
|
440
|
+
if constexpr (SL != SIMDLevel::NONE) {
|
|
441
|
+
return nullptr;
|
|
442
|
+
} else {
|
|
443
|
+
return new QuantizerLloydMax<7, SL>(d, trained);
|
|
444
|
+
}
|
|
445
|
+
case ScalarQuantizer::QT_8bit_eden:
|
|
446
|
+
return new QuantizerLloydMax<8, SL>(d, trained);
|
|
419
447
|
case ScalarQuantizer::QT_2bit_tq:
|
|
420
448
|
return new QuantizerTurboQuantFull<2, SL>(d, trained);
|
|
421
449
|
case ScalarQuantizer::QT_3bit_tq:
|
|
@@ -518,6 +546,16 @@ SQDistanceComputer* select_distance_computer_body(
|
|
|
518
546
|
return new DistanceComputerByteSigned<Sim, SL2>(
|
|
519
547
|
static_cast<int>(d), trained);
|
|
520
548
|
}
|
|
549
|
+
} else if constexpr (SL2 == SIMDLevel::AVX512) {
|
|
550
|
+
if (d % 32 == 0) {
|
|
551
|
+
return new DistanceComputerByteSigned<Sim, SL2>(
|
|
552
|
+
static_cast<int>(d), trained);
|
|
553
|
+
}
|
|
554
|
+
} else if constexpr (SL2 == SIMDLevel::AVX2) {
|
|
555
|
+
if (d % 16 == 0) {
|
|
556
|
+
return new DistanceComputerByteSigned<Sim, SL2>(
|
|
557
|
+
static_cast<int>(d), trained);
|
|
558
|
+
}
|
|
521
559
|
}
|
|
522
560
|
return new DCTemplate<Quantizer8bitDirectSigned<SL2>, Sim, SL2>(
|
|
523
561
|
d, trained);
|
|
@@ -539,6 +577,42 @@ SQDistanceComputer* select_distance_computer_body(
|
|
|
539
577
|
case ScalarQuantizer::QT_8bit_tqmse:
|
|
540
578
|
return new DCTemplate<QuantizerTurboQuantMSE<8, SL2>, Sim, SL2>(
|
|
541
579
|
d, trained);
|
|
580
|
+
case ScalarQuantizer::QT_1bit_eden:
|
|
581
|
+
return new DCTemplate<QuantizerLloydMax<1, SL2>, Sim, SL2>(
|
|
582
|
+
d, trained);
|
|
583
|
+
case ScalarQuantizer::QT_2bit_eden:
|
|
584
|
+
return new DCTemplate<QuantizerLloydMax<2, SL2>, Sim, SL2>(
|
|
585
|
+
d, trained);
|
|
586
|
+
case ScalarQuantizer::QT_3bit_eden:
|
|
587
|
+
return new DCTemplate<QuantizerLloydMax<3, SL2>, Sim, SL2>(
|
|
588
|
+
d, trained);
|
|
589
|
+
case ScalarQuantizer::QT_4bit_eden:
|
|
590
|
+
return new DCTemplate<QuantizerLloydMax<4, SL2>, Sim, SL2>(
|
|
591
|
+
d, trained);
|
|
592
|
+
case ScalarQuantizer::QT_5bit_eden:
|
|
593
|
+
if constexpr (SL2 != SIMDLevel::NONE) {
|
|
594
|
+
return nullptr;
|
|
595
|
+
} else {
|
|
596
|
+
return new DCTemplate<QuantizerLloydMax<5, SL2>, Sim, SL2>(
|
|
597
|
+
d, trained);
|
|
598
|
+
}
|
|
599
|
+
case ScalarQuantizer::QT_6bit_eden:
|
|
600
|
+
if constexpr (SL2 != SIMDLevel::NONE) {
|
|
601
|
+
return nullptr;
|
|
602
|
+
} else {
|
|
603
|
+
return new DCTemplate<QuantizerLloydMax<6, SL2>, Sim, SL2>(
|
|
604
|
+
d, trained);
|
|
605
|
+
}
|
|
606
|
+
case ScalarQuantizer::QT_7bit_eden:
|
|
607
|
+
if constexpr (SL2 != SIMDLevel::NONE) {
|
|
608
|
+
return nullptr;
|
|
609
|
+
} else {
|
|
610
|
+
return new DCTemplate<QuantizerLloydMax<7, SL2>, Sim, SL2>(
|
|
611
|
+
d, trained);
|
|
612
|
+
}
|
|
613
|
+
case ScalarQuantizer::QT_8bit_eden:
|
|
614
|
+
return new DCTemplate<QuantizerLloydMax<8, SL2>, Sim, SL2>(
|
|
615
|
+
d, trained);
|
|
542
616
|
case ScalarQuantizer::QT_2bit_tq:
|
|
543
617
|
// FRICTION: bypasses DCTemplate entirely — custom DC
|
|
544
618
|
// that doesn't fit the Quantizer+Similarity decomposition
|
|
@@ -686,6 +760,16 @@ InvertedListScanner* sq_select_InvertedListScanner<THE_LEVEL_TO_DISPATCH>(
|
|
|
686
760
|
return scan.template operator()<
|
|
687
761
|
DistanceComputerByteSigned<Similarity, SL2>>();
|
|
688
762
|
}
|
|
763
|
+
} else if constexpr (SL2 == SIMDLevel::AVX512) {
|
|
764
|
+
if (d % 32 == 0) {
|
|
765
|
+
return scan.template operator()<
|
|
766
|
+
DistanceComputerByteSigned<Similarity, SL2>>();
|
|
767
|
+
}
|
|
768
|
+
} else if constexpr (SL2 == SIMDLevel::AVX2) {
|
|
769
|
+
if (d % 16 == 0) {
|
|
770
|
+
return scan.template operator()<
|
|
771
|
+
DistanceComputerByteSigned<Similarity, SL2>>();
|
|
772
|
+
}
|
|
689
773
|
}
|
|
690
774
|
return scan.template operator()<DCTemplate<
|
|
691
775
|
Quantizer8bitDirectSigned<SL2>,
|
|
@@ -719,6 +803,58 @@ InvertedListScanner* sq_select_InvertedListScanner<THE_LEVEL_TO_DISPATCH>(
|
|
|
719
803
|
QuantizerTurboQuantMSE<8, SL2>,
|
|
720
804
|
Similarity,
|
|
721
805
|
SL2>>();
|
|
806
|
+
case ScalarQuantizer::QT_1bit_eden:
|
|
807
|
+
return scan.template operator()<DCTemplate<
|
|
808
|
+
QuantizerLloydMax<1, SL2>,
|
|
809
|
+
Similarity,
|
|
810
|
+
SL2>>();
|
|
811
|
+
case ScalarQuantizer::QT_2bit_eden:
|
|
812
|
+
return scan.template operator()<DCTemplate<
|
|
813
|
+
QuantizerLloydMax<2, SL2>,
|
|
814
|
+
Similarity,
|
|
815
|
+
SL2>>();
|
|
816
|
+
case ScalarQuantizer::QT_3bit_eden:
|
|
817
|
+
return scan.template operator()<DCTemplate<
|
|
818
|
+
QuantizerLloydMax<3, SL2>,
|
|
819
|
+
Similarity,
|
|
820
|
+
SL2>>();
|
|
821
|
+
case ScalarQuantizer::QT_4bit_eden:
|
|
822
|
+
return scan.template operator()<DCTemplate<
|
|
823
|
+
QuantizerLloydMax<4, SL2>,
|
|
824
|
+
Similarity,
|
|
825
|
+
SL2>>();
|
|
826
|
+
case ScalarQuantizer::QT_5bit_eden:
|
|
827
|
+
if constexpr (SL2 != SIMDLevel::NONE) {
|
|
828
|
+
return nullptr;
|
|
829
|
+
} else {
|
|
830
|
+
return scan.template operator()<DCTemplate<
|
|
831
|
+
QuantizerLloydMax<5, SL2>,
|
|
832
|
+
Similarity,
|
|
833
|
+
SL2>>();
|
|
834
|
+
}
|
|
835
|
+
case ScalarQuantizer::QT_6bit_eden:
|
|
836
|
+
if constexpr (SL2 != SIMDLevel::NONE) {
|
|
837
|
+
return nullptr;
|
|
838
|
+
} else {
|
|
839
|
+
return scan.template operator()<DCTemplate<
|
|
840
|
+
QuantizerLloydMax<6, SL2>,
|
|
841
|
+
Similarity,
|
|
842
|
+
SL2>>();
|
|
843
|
+
}
|
|
844
|
+
case ScalarQuantizer::QT_7bit_eden:
|
|
845
|
+
if constexpr (SL2 != SIMDLevel::NONE) {
|
|
846
|
+
return nullptr;
|
|
847
|
+
} else {
|
|
848
|
+
return scan.template operator()<DCTemplate<
|
|
849
|
+
QuantizerLloydMax<7, SL2>,
|
|
850
|
+
Similarity,
|
|
851
|
+
SL2>>();
|
|
852
|
+
}
|
|
853
|
+
case ScalarQuantizer::QT_8bit_eden:
|
|
854
|
+
return scan.template operator()<DCTemplate<
|
|
855
|
+
QuantizerLloydMax<8, SL2>,
|
|
856
|
+
Similarity,
|
|
857
|
+
SL2>>();
|
|
722
858
|
case ScalarQuantizer::QT_2bit_tq:
|
|
723
859
|
return scan.template
|
|
724
860
|
operator()<DCTurboQuantFull<2, Similarity, SL2>>();
|