#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum SimdLevel {
Scalar,
Sse2,
Avx,
Avx2,
Avx512,
Neon,
Sve,
}
#[must_use]
pub fn detect_simd_level() -> SimdLevel {
#[cfg(target_arch = "x86_64")]
{
if is_x86_feature_detected!("avx512f") {
return SimdLevel::Avx512;
}
if is_x86_feature_detected!("avx2") {
return SimdLevel::Avx2;
}
if is_x86_feature_detected!("avx") {
return SimdLevel::Avx;
}
if is_x86_feature_detected!("sse2") {
return SimdLevel::Sse2;
}
SimdLevel::Scalar
}
#[cfg(target_arch = "aarch64")]
{
#[cfg(feature = "sve")]
{
if has_sve_runtime() {
return SimdLevel::Sve;
}
}
SimdLevel::Neon
}
#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
SimdLevel::Scalar
}
#[allow(dead_code)]
#[must_use]
#[cfg(target_arch = "x86_64")]
pub fn has_avx() -> bool {
is_x86_feature_detected!("avx")
}
#[allow(dead_code)]
#[must_use]
#[cfg(target_arch = "x86_64")]
pub fn has_avx2() -> bool {
is_x86_feature_detected!("avx2")
}
#[allow(dead_code)]
#[must_use]
#[cfg(target_arch = "x86_64")]
pub fn has_avx512() -> bool {
is_x86_feature_detected!("avx512f")
}
#[allow(dead_code)]
#[must_use]
#[cfg(all(target_arch = "aarch64", target_os = "linux", feature = "sve"))]
pub fn has_sve_runtime() -> bool {
#[allow(unsafe_code)]
unsafe {
const AT_HWCAP: libc::c_ulong = 16;
const HWCAP_SVE: u64 = 1 << 22;
let hwcap = libc::getauxval(AT_HWCAP);
(hwcap & HWCAP_SVE) != 0
}
}
#[allow(dead_code)]
#[must_use]
#[cfg(not(all(target_arch = "aarch64", target_os = "linux", feature = "sve")))]
pub fn has_sve_runtime() -> bool {
false
}