1#[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
27pub 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
63pub fn kernel_level() -> SimdLevel {
66 match detect() {
67 SimdLevel::Avx2 | SimdLevel::Avx512 | SimdLevel::Sse41 => SimdLevel::Sse41,
68 other => other,
69 }
70}