Skip to content

Commit 8ebfd03

Browse files
committed
Accelerate ScalarQuantizer::QT_bf16 with AVX512-BF16.
Vectorizes the BF16 encode/decode path with AVX-512 BF16 and integer instructions, targeting Intel Sapphire Rapids and newer processors. Distance computations now operate directly on BF16 data, avoiding the overhead of FP32 conversion: - Inner product: the query is encoded to BF16 once, and dot products are computed natively in BF16 via VDPBF16PS. - L2 distance: uses the norm expansion identity, with all terms evaluated using the native BF16 dot-product instruction. Scalar quantizer benchmarks on Sapphire Rapids (d=768, n=2000, iterations=20) show speedups of 1.42x for encoding, 1.32x for decoding, and 1.16x for distance computation. Signed-off-by: Mulugeta Mammo <mulugeta.mammo@intel.com>
1 parent 2dff119 commit 8ebfd03

9 files changed

Lines changed: 945 additions & 434 deletions

File tree

faiss/CMakeLists.txt

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ set(FAISS_SIMD_AVX512_SRC
2828
utils/distances_fused/avx512.cpp
2929
utils/simd_impl/rabitq_avx512.cpp
3030
)
31+
set(FAISS_SIMD_AVX512_SPR_SRC
32+
impl/scalar_quantizer/sq-avx512-spr.cpp
33+
utils/simd_impl/distances_avx512_spr.cpp
34+
)
3135
set(FAISS_SIMD_NEON_SRC
3236
impl/fast_scan/impl-neon.cpp
3337
impl/scalar_quantizer/sq-neon.cpp
@@ -43,7 +47,7 @@ set(FAISS_SIMD_SVE_SRC
4347
)
4448
# Select SIMD sources based on target architecture
4549
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64|amd64|AMD64)")
46-
set(FAISS_SIMD_SRC ${FAISS_SIMD_AVX2_SRC} ${FAISS_SIMD_AVX512_SRC})
50+
set(FAISS_SIMD_SRC ${FAISS_SIMD_AVX2_SRC} ${FAISS_SIMD_AVX512_SRC} ${FAISS_SIMD_AVX512_SPR_SRC})
4751
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64|arm64|ARM64)")
4852
set(FAISS_SIMD_SRC ${FAISS_SIMD_NEON_SRC} ${FAISS_SIMD_SVE_SRC})
4953
else()
@@ -389,7 +393,7 @@ endif()
389393
if(NOT WIN32)
390394
# All modern CPUs support F, CD, VL, DQ, BW extensions.
391395
# Ref: https://en.wikipedia.org/wiki/AVX512
392-
target_compile_options(faiss_avx512 PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-mavx2 -mfma -mf16c -mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw -mpopcnt>)
396+
target_compile_options(faiss_avx512 PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-mavx -mavx2 -mfma -mf16c -mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw -mpopcnt>)
393397
else()
394398
target_compile_options(faiss_avx512 PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/arch:AVX512>)
395399
# we need bigobj for the swig wrapper
@@ -405,14 +409,14 @@ endif()
405409
if(NOT WIN32)
406410
# Architecture mode to support AVX512 extensions available since Intel(R) Sapphire Rapids.
407411
# Ref: https://networkbuilders.intel.com/solutionslibrary/intel-avx-512-fp16-instruction-set-for-intel-xeon-processor-based-products-technology-guide
408-
target_compile_options(faiss_avx512_spr PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-mavx2 -mfma -mf16c -mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw -mavx512vpopcntdq -mpopcnt -mavx512fp16 -mavx512bf16>)
412+
target_compile_options(faiss_avx512_spr PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-mavx -mavx2 -mfma -mf16c -mbmi2 -mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi2 -mavx512vpopcntdq -mpopcnt -mavx512fp16 -mavx512bf16>)
409413
else()
410414
target_compile_options(faiss_avx512_spr PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/arch:AVX512>)
411415
# we need bigobj for the swig wrapper
412416
add_compile_options(/bigobj)
413417
endif()
414-
target_sources(faiss_avx512_spr PRIVATE ${FAISS_SIMD_AVX2_SRC} ${FAISS_SIMD_AVX512_SRC})
415-
target_compile_definitions(faiss_avx512_spr PRIVATE COMPILE_SIMD_AVX2 COMPILE_SIMD_AVX512 COMPILE_SIMD_AVX512_SPR )
418+
target_sources(faiss_avx512_spr PRIVATE ${FAISS_SIMD_AVX2_SRC} ${FAISS_SIMD_AVX512_SRC} ${FAISS_SIMD_AVX512_SPR_SRC})
419+
target_compile_definitions(faiss_avx512_spr PRIVATE COMPILE_SIMD_AVX2 COMPILE_SIMD_AVX512 COMPILE_SIMD_AVX512_SPR)
416420

417421
add_library(faiss_sve ${FAISS_SRC})
418422
if(NOT FAISS_OPT_LEVEL STREQUAL "sve")
@@ -460,14 +464,21 @@ if(FAISS_OPT_LEVEL STREQUAL "dd")
460464
target_compile_options(faiss PRIVATE
461465
$<$<COMPILE_LANGUAGE:CXX>:-mpopcnt -msse4 -mno-avx -mno-avx2>)
462466
# Per-file SIMD flags
467+
# Note: -mavx must be explicit because baseline sets -mno-avx which
468+
# overrides the implicit -mavx from higher ISA flags like -mavx512f.
463469
set_source_files_properties(${FAISS_SIMD_AVX2_SRC}
464470
TARGET_DIRECTORY faiss
465-
PROPERTIES COMPILE_OPTIONS "-mavx2;-mfma;-mf16c;-mpopcnt"
471+
PROPERTIES COMPILE_OPTIONS "-mavx;-mavx2;-mfma;-mf16c;-mpopcnt"
466472
)
467473
set_source_files_properties(${FAISS_SIMD_AVX512_SRC}
468474
TARGET_DIRECTORY faiss
469475
PROPERTIES COMPILE_OPTIONS
470-
"-mavx512f;-mavx512cd;-mavx512vl;-mavx512dq;-mavx512bw;-mfma;-mf16c;-mpopcnt"
476+
"-mavx;-mavx2;-mfma;-mavx512f;-mavx512cd;-mavx512vl;-mavx512dq;-mavx512bw;-mpopcnt"
477+
)
478+
set_source_files_properties(${FAISS_SIMD_AVX512_SPR_SRC}
479+
TARGET_DIRECTORY faiss
480+
PROPERTIES COMPILE_OPTIONS
481+
"-mavx;-mavx2;-mfma;-mbmi2;-mavx512f;-mavx512cd;-mavx512vl;-mavx512dq;-mavx512bw;-mavx512vbmi2;-mpopcnt;-mavx512bf16"
471482
)
472483
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64|arm64|ARM64)")
473484
# ARM NEON is always available on aarch64, no special compiler flags needed

faiss/impl/scalar_quantizer/quantizers.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,12 @@ struct QuantizerBF16<SIMDLevel::NONE> : ScalarQuantizer::SQuantizer {
165165
QuantizerBF16(size_t d_in, const std::vector<float>& /* unused */)
166166
: d(d_in) {}
167167

168-
void encode_vector(const float* x, uint8_t* code) const final {
169-
for (size_t i = 0; i < d; i++) {
170-
((uint16_t*)code)[i] = encode_bf16(x[i]);
171-
}
168+
void encode_vector(const float* x, uint8_t* code) const override {
169+
encode_bf16_simd(x, (uint16_t*)code, d);
172170
}
173171

174-
void decode_vector(const uint8_t* code, float* x) const final {
175-
for (size_t i = 0; i < d; i++) {
176-
x[i] = decode_bf16(((uint16_t*)code)[i]);
177-
}
172+
void decode_vector(const uint8_t* code, float* x) const override {
173+
decode_bf16_simd((const uint16_t*)code, x, d);
178174
}
179175

180176
FAISS_ALWAYS_INLINE float reconstruct_component(
@@ -189,6 +185,11 @@ struct QuantizerBF16 : QuantizerBF16<SIMDLevel::NONE> {
189185
using QuantizerBF16<SIMDLevel::NONE>::QuantizerBF16;
190186
};
191187

188+
template <>
189+
struct QuantizerBF16<SIMDLevel::AVX512>;
190+
template <>
191+
struct QuantizerBF16<SIMDLevel::AVX512_SPR>;
192+
192193
/*******************************************************************
193194
* 8bit_direct quantizer
194195
*******************************************************************/

0 commit comments

Comments
 (0)