mod exp_poly;
mod feasibility;
mod slab;
mod triple_solve;
pub use exp_poly::exp_f32x8;
pub use feasibility::{BLANK_OWNER, Feasibility, PlanesSoA64, any_violation, classify_feasibility};
pub use slab::{PlanesSoA32, SlabScan, slab_scan};
pub use triple_solve::{TRIPLE_LANES, TripleBatch, TripleSolution, solve_triple_batch};
use std::sync::OnceLock;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SimdLevel {
Scalar,
Avx2,
Avx512,
}
static LEVEL: OnceLock<SimdLevel> = OnceLock::new();
pub fn simd_level() -> SimdLevel {
*LEVEL.get_or_init(|| {
let detected = detect_level();
let cap = match std::env::var("INDICATRIX_SIMD").as_deref() {
Ok("scalar") => SimdLevel::Scalar,
Ok("avx2") => SimdLevel::Avx2,
_ => SimdLevel::Avx512,
};
if rank(cap) < rank(detected) {
cap
} else {
detected
}
})
}
const fn rank(level: SimdLevel) -> u8 {
match level {
SimdLevel::Scalar => 0,
SimdLevel::Avx2 => 1,
SimdLevel::Avx512 => 2,
}
}
#[cfg(target_arch = "x86_64")]
fn detect_level() -> SimdLevel {
if std::arch::is_x86_feature_detected!("avx512f") && std::arch::is_x86_feature_detected!("fma")
{
return SimdLevel::Avx512;
}
if std::arch::is_x86_feature_detected!("avx2") && std::arch::is_x86_feature_detected!("fma") {
return SimdLevel::Avx2;
}
SimdLevel::Scalar
}
#[cfg(not(target_arch = "x86_64"))]
const fn detect_level() -> SimdLevel {
SimdLevel::Scalar
}