mirror of
https://github.com/facebookresearch/faiss.git
synced 2026-10-12 02:13:36 +00:00
Fix AVX512_SPR build failure for 512-bit SIMD types (#5030)
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5030 The `faiss_avx512_spr` CMake target fails to compile because 512-bit SIMD type aliases (`simd32uint16`, `simd64uint8`, etc.) resolve to empty primary templates when `SINGLE_SIMD_LEVEL = AVX512_SPR`. Only `AVX512` and `NONE` have explicit template specializations. This adds `simd512_level_selector` (analogous to existing `simd256_level_selector`) that maps `AVX512_SPR -> AVX512` for 512-bit types. This is correct because AVX512_SPR uses the same 512-bit integer SIMD instructions as AVX512 — SPR-specific gains come from separate instruction sets (BF16, FP16, VNNI) used in different code paths. Changes: - `simd_levels.h`: Add `simd512_level_selector` and `SINGLE_SIMD_LEVEL_512` - `simdlib_dispatch.h`: Route 512-bit aliases through `SINGLE_SIMD_LEVEL_512`; also check `COMPILE_SIMD_AVX512_SPR` in include guard - `LookupTableScaler.h`: Use `simd512_level_selector` for 512-bit types in `DummyScaler` and `NormTableScaler` Reviewed By: mnorris11 Differential Revision: D99306837 fbshipit-source-id: 49e71415c155b9328dc76ff0cd492f718060ff1e
This commit is contained in:
committed by
meta-codesync[bot]
parent
aef066ac0e
commit
0ce4dfb206
@@ -24,10 +24,11 @@ template <SIMDLevel SL = SINGLE_SIMD_LEVEL>
|
||||
struct DummyScaler {
|
||||
static constexpr int nscale = 0;
|
||||
static constexpr SIMDLevel SL256 = simd256_level_selector<SL>::value;
|
||||
static constexpr SIMDLevel SL512 = simd512_level_selector<SL>::value;
|
||||
using simd32uint8 = simd32uint8_tpl<SL256>;
|
||||
using simd16uint16 = simd16uint16_tpl<SL256>;
|
||||
using simd64uint8 = simd64uint8_tpl<SL>;
|
||||
using simd32uint16 = simd32uint16_tpl<SL>;
|
||||
using simd64uint8 = simd64uint8_tpl<SL512>;
|
||||
using simd32uint16 = simd32uint16_tpl<SL512>;
|
||||
|
||||
inline simd32uint8 lookup(const simd32uint8&, const simd32uint8&) const {
|
||||
FAISS_THROW_MSG("DummyScaler::lookup should not be called.");
|
||||
@@ -72,10 +73,11 @@ template <SIMDLevel SL = SINGLE_SIMD_LEVEL>
|
||||
struct NormTableScaler {
|
||||
static constexpr int nscale = 2;
|
||||
static constexpr SIMDLevel SL256 = simd256_level_selector<SL>::value;
|
||||
static constexpr SIMDLevel SL512 = simd512_level_selector<SL>::value;
|
||||
using simd32uint8 = simd32uint8_tpl<SL256>;
|
||||
using simd16uint16 = simd16uint16_tpl<SL256>;
|
||||
using simd64uint8 = simd64uint8_tpl<SL>;
|
||||
using simd32uint16 = simd32uint16_tpl<SL>;
|
||||
using simd64uint8 = simd64uint8_tpl<SL512>;
|
||||
using simd32uint16 = simd32uint16_tpl<SL512>;
|
||||
|
||||
int scale_int;
|
||||
simd16uint16 scale_simd;
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
// Only per-SIMD TUs (compiled with -mavx2 etc.) see the platform
|
||||
// specializations. In static mode: only the compiled-in level is available.
|
||||
|
||||
#if defined(COMPILE_SIMD_AVX512) && defined(__AVX512F__)
|
||||
#if (defined(COMPILE_SIMD_AVX512) || defined(COMPILE_SIMD_AVX512_SPR)) && \
|
||||
defined(__AVX512F__)
|
||||
|
||||
// AVX512 includes AVX2 (simdlib_avx512.h includes simdlib_avx2.h)
|
||||
#include <faiss/impl/simdlib/simdlib_avx512.h>
|
||||
@@ -50,10 +51,10 @@ using simd32uint8 = simd32uint8_tpl<SINGLE_SIMD_LEVEL_256>;
|
||||
using simd8uint32 = simd8uint32_tpl<SINGLE_SIMD_LEVEL_256>;
|
||||
using simd8float32 = simd8float32_tpl<SINGLE_SIMD_LEVEL_256>;
|
||||
|
||||
// 512-bit
|
||||
using simd512bit = simd512bit_tpl<SINGLE_SIMD_LEVEL>;
|
||||
using simd32uint16 = simd32uint16_tpl<SINGLE_SIMD_LEVEL>;
|
||||
using simd64uint8 = simd64uint8_tpl<SINGLE_SIMD_LEVEL>;
|
||||
using simd16float32 = simd16float32_tpl<SINGLE_SIMD_LEVEL>;
|
||||
// 512-bit (AVX512_SPR maps to AVX512 — same 512-bit integer ops)
|
||||
using simd512bit = simd512bit_tpl<SINGLE_SIMD_LEVEL_512>;
|
||||
using simd32uint16 = simd32uint16_tpl<SINGLE_SIMD_LEVEL_512>;
|
||||
using simd64uint8 = simd64uint8_tpl<SINGLE_SIMD_LEVEL_512>;
|
||||
using simd16float32 = simd16float32_tpl<SINGLE_SIMD_LEVEL_512>;
|
||||
|
||||
} // namespace faiss
|
||||
|
||||
@@ -86,6 +86,26 @@ struct simd256_level_selector {
|
||||
inline constexpr SIMDLevel SINGLE_SIMD_LEVEL_256 =
|
||||
simd256_level_selector<SINGLE_SIMD_LEVEL>::value;
|
||||
|
||||
/***************************************************************
|
||||
* Helper to select the appropriate 512-bit SIMD level.
|
||||
*
|
||||
* For 512-bit SIMD types (simd32uint16, simd64uint8, etc.), maps:
|
||||
* AVX512_SPR → AVX512 (512-bit ops share the same instructions)
|
||||
* AVX512 → AVX512
|
||||
* NONE → NONE
|
||||
***************************************************************/
|
||||
template <SIMDLevel SL>
|
||||
struct simd512_level_selector {
|
||||
static constexpr SIMDLevel value =
|
||||
(SL == SIMDLevel::AVX512_SPR) ? SIMDLevel::AVX512 : SL;
|
||||
};
|
||||
|
||||
/// SINGLE_SIMD_LEVEL mapped to 512-bit: use this for 512-bit simd types
|
||||
/// (simd32uint16, simd64uint8, etc.) which don't have AVX512_SPR
|
||||
/// specializations (AVX512_SPR uses the same 512-bit integer ops as AVX512).
|
||||
inline constexpr SIMDLevel SINGLE_SIMD_LEVEL_512 =
|
||||
simd512_level_selector<SINGLE_SIMD_LEVEL>::value;
|
||||
|
||||
/// Number of float32 lanes for a given SIMD level.
|
||||
/// ARM_SVE is variable-width (128–2048 bits); no single constant is correct.
|
||||
template <SIMDLevel SL>
|
||||
|
||||
Reference in New Issue
Block a user