use super::config::SimdMathConfig;
use super::instruction_set::InstructionSet;
use crate::config_table;
use std::sync::LazyLock;
use std::sync::atomic::{AtomicU8, Ordering};
pub static SIMD_MATH: LazyLock<SimdMathConfig> = LazyLock::new(detect_best_simd);
#[doc(hidden)]
pub static TEST_ISA_OVERRIDE: AtomicU8 = AtomicU8::new(u8::MAX);
#[doc(hidden)]
#[inline]
pub fn encode_isa_override(isa: InstructionSet) -> u8 {
match isa {
InstructionSet::Avx2 => 0,
InstructionSet::Avx512 => 1,
InstructionSet::Avx512VnniBf16 => 2,
}
}
#[doc(hidden)]
#[inline]
pub fn decode_isa_override(raw: u8) -> Option<InstructionSet> {
match raw {
0 => Some(InstructionSet::Avx2),
1 => Some(InstructionSet::Avx512),
2 => Some(InstructionSet::Avx512VnniBf16),
_ => None,
}
}
#[doc(hidden)]
#[inline]
pub fn effective_instruction_set() -> InstructionSet {
let raw = TEST_ISA_OVERRIDE.load(Ordering::Relaxed);
if let Some(isa) = decode_isa_override(raw) {
isa
} else {
SIMD_MATH.instruction_set
}
}
fn detect_best_simd() -> SimdMathConfig {
if is_x86_feature_detected!("avx512bf16") && is_x86_feature_detected!("avx512vnni") {
return config_table!(InstructionSet::Avx512VnniBf16, "AVX-512 (VNNI+BF16)", true);
}
if is_x86_feature_detected!("avx512f") {
return config_table!(InstructionSet::Avx512, "AVX-512", true);
}
config_table!(InstructionSet::Avx2, "AVX2", false)
}