Skip to main content

flashraw_core/
simd.rs

1//! Runtime CPU feature detection shared by SIMD kernels.
2
3/// SIMD capability level detected at runtime.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
5pub enum SimdLevel {
6    Scalar,
7    Sse41,
8    Avx2,
9    Avx512,
10    Neon,
11    WasmSimd128,
12}
13
14impl SimdLevel {
15    pub fn name(self) -> &'static str {
16        match self {
17            SimdLevel::Scalar => "scalar",
18            SimdLevel::Sse41 => "SSE4.1",
19            SimdLevel::Avx2 => "AVX2",
20            SimdLevel::Avx512 => "AVX-512",
21            SimdLevel::Neon => "NEON",
22            SimdLevel::WasmSimd128 => "WASM SIMD128",
23        }
24    }
25}
26
27/// Best SIMD level available on this CPU.
28pub fn detect() -> SimdLevel {
29    #[cfg(target_arch = "x86_64")]
30    {
31        use std::sync::OnceLock;
32        static LEVEL: OnceLock<SimdLevel> = OnceLock::new();
33        *LEVEL.get_or_init(|| {
34            if std::arch::is_x86_feature_detected!("avx512bw") && std::arch::is_x86_feature_detected!("avx512vbmi") {
35                SimdLevel::Avx512
36            } else if std::arch::is_x86_feature_detected!("avx2") {
37                SimdLevel::Avx2
38            } else if std::arch::is_x86_feature_detected!("sse4.1") {
39                SimdLevel::Sse41
40            } else {
41                SimdLevel::Scalar
42            }
43        })
44    }
45    #[cfg(target_arch = "aarch64")]
46    {
47        SimdLevel::Neon
48    }
49    #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))]
50    {
51        SimdLevel::WasmSimd128
52    }
53    #[cfg(not(any(
54        target_arch = "x86_64",
55        target_arch = "aarch64",
56        all(target_arch = "wasm32", target_feature = "simd128")
57    )))]
58    {
59        SimdLevel::Scalar
60    }
61}
62
63/// The instruction set FlashRaw's SIMD kernels actually use on this CPU (kernels
64/// target SSE4.1 on x86-64, NEON on aarch64, SIMD128 on WASM), for honest reporting.
65pub fn kernel_level() -> SimdLevel {
66    match detect() {
67        SimdLevel::Avx2 | SimdLevel::Avx512 | SimdLevel::Sse41 => SimdLevel::Sse41,
68        other => other,
69    }
70}