11//! SIMD abstraction layer and fast math functions.
22//!
33//! All numerical computation in this module is written generically over the
4- //! [`SimdFloat`] trait. The default [`ScalarFloat`] backend (WIDTH=1) works
5- //! everywhere; platform backends are activated via feature flags:
4+ //! [`crate::simd::generic::SimdFloat`] trait. The default
5+ //! [`crate::simd::generic::ScalarFloat`] backend (WIDTH=1) works everywhere;
6+ //! platform backends are activated by [`crate::sim`]'s compile-time-selected
7+ //! opt-in features, or unconditionally by [`crate::simd`]'s own
8+ //! runtime-detected `simd` feature (see
9+ //! [`crate::simd::generic::dispatch::detect_backend`]):
610//!
7- //! | Feature | Type | WIDTH | Platform |
8- //! |---------------|-----------|-------|-----------|
9- //! | (none) | `ScalarFloat` | 1 | all |
10- //! | `sim-avx2` | `F32x8` | 8 | x86_64 |
11- //! | `sim-avx512` | `F32x16` | 16 | x86_64 |
12- //! | `sim-neon` | `F32x4` | 4 | aarch64 |
11+ //! | Feature | Type | WIDTH | Platform |
12+ //! |---------------|------------|-------|-----------|
13+ //! | (none) | `ScalarFloat` | 1 | all |
14+ //! | `simd` | `F32x4Sse` | 4 | x86_64 (baseline floor)|
15+ //! | `sim-avx2` | `F32x8` | 8 | x86_64 |
16+ //! | `sim-avx512` | `F32x16` | 16 | x86_64 |
17+ //! | `sim-neon` | `F32x4` | 4 | aarch64 |
1318//!
1419//! # Fast Math
1520//!
1621//! The following functions are provided with < 1e-5 relative error:
1722//!
18- //! - [`simd_exp`] -- exponential via range reduction + degree-5 polynomial
19- //! - [`simd_log`] -- natural log via atanh series expansion
20- //! - [`simd_log1pexp`] -- numerically stable softplus
21- //! - [`simd_sigmoid`] -- logistic sigmoid without overflow
22- //! - [`simd_recip`], [`simd_rsqrt`] -- Newton-refined reciprocal/inverse sqrt
23+ //! - [`crate::simd::generic:: simd_exp`] -- exponential via range reduction + degree-5 polynomial
24+ //! - [`crate::simd::generic:: simd_log`] -- natural log via atanh series expansion
25+ //! - [`crate::simd::generic:: simd_log1pexp`] -- numerically stable softplus
26+ //! - [`crate::simd::generic:: simd_sigmoid`] -- logistic sigmoid without overflow
27+ //! - [`crate::simd::generic:: simd_recip`], [`crate::simd::generic:: simd_rsqrt`] -- Newton-refined reciprocal/inverse sqrt
2328
2429// `exp`'s Cody-Waite range-reduction constants are intentionally given to
2530// more decimal digits than `f32` can represent exactly (for readability
@@ -36,7 +41,7 @@ pub mod reciprocal;
3641pub mod scalar;
3742/// SIMD logistic sigmoid (`simd_sigmoid`).
3843pub mod sigmoid;
39- /// The [`SimdFloat`] abstraction trait itself.
44+ /// The [`crate::simd::generic:: SimdFloat`] abstraction trait itself.
4045pub mod traits;
4146
4247/// AVX2 `F32x8` backend, `x86_64` only. Compiled whenever either
@@ -46,29 +51,35 @@ pub mod traits;
4651#[ cfg( all( target_arch = "x86_64" , any( feature = "simd" , feature = "sim-avx2" ) ) ) ]
4752pub mod avx2;
4853
49- /// AVX-512 `F32x16` backend (`sim-avx512` feature, `x86_64` only).
50- #[ cfg( all( target_arch = "x86_64" , feature = "sim-avx512" ) ) ]
54+ /// AVX-512 `F32x16` backend, `x86_64` only. Compiled whenever either
55+ /// [`crate::sim`]'s compile-time-selected `sim-avx512` backend or
56+ /// [`crate::simd`]'s runtime-dispatched `simd` feature needs it, mirroring
57+ /// [`crate::simd::generic::avx2`]'s dual use.
58+ #[ cfg( all( target_arch = "x86_64" , any( feature = "simd" , feature = "sim-avx512" ) ) ) ]
5159pub mod avx512;
5260
5361/// ARM NEON `F32x4` backend, `aarch64` only. Compiled whenever either
5462/// [`crate::sim`]'s compile-time-selected `sim-neon` backend or
5563/// [`crate::simd`]'s runtime-dispatched `simd` feature needs it, mirroring
56- /// [`avx2`]'s dual use.
64+ /// [`crate::simd::generic:: avx2`]'s dual use.
5765#[ cfg( all( target_arch = "aarch64" , any( feature = "simd" , feature = "sim-neon" ) ) ) ]
5866pub mod neon;
5967
60- /// Baseline SSE2 `F32x4Sse` backend, `x86_64` only - see [`sse2`]'s module
61- /// docs for why it needs no opt-in feature of its own.
68+ /// Baseline SSE2 `F32x4Sse` backend, `x86_64` only - see
69+ /// [`crate::simd::generic::sse2`]'s module docs for why it needs no opt-in
70+ /// feature of its own.
6271#[ cfg( target_arch = "x86_64" ) ]
6372pub mod sse2;
6473
6574/// Width-agnostic `dot`/`mul_elementwise`/`mix_scalar` shared by every
66- /// [`SimdFloat`] backend - see [`ops`]'s module docs.
75+ /// [`crate::simd::generic::SimdFloat`] backend - see
76+ /// [`crate::simd::generic::ops`]'s module docs.
6777pub mod ops;
6878
69- /// Runtime backend selection ([`dispatch::detect_backend`]).
79+ /// Runtime backend selection ([`crate::simd::generic:: dispatch::detect_backend`]).
7080pub mod dispatch;
7181
82+ pub use dispatch:: SimdBackend ;
7283pub use scalar:: ScalarFloat ;
7384pub use traits:: SimdFloat ;
7485
@@ -78,23 +89,36 @@ pub use reciprocal::{simd_recip, simd_rsqrt};
7889pub use sigmoid:: simd_sigmoid;
7990
8091/// Select the best available SIMD backend at compile time.
81- /// Returns a string identifying the active backend.
92+ ///
93+ /// This is [`crate::sim`]'s own compile-time choice (which `sim-*` feature
94+ /// was enabled), distinct from
95+ /// [`crate::simd::generic::dispatch::detect_backend`]'s runtime CPU check -
96+ /// see that function's docs for why the two differ. Returns a string
97+ /// identifying the active backend, from the same vocabulary as
98+ /// [`SimdBackend::as_str`].
8299pub fn active_backend ( ) -> & ' static str {
83100 #[ cfg( all( target_arch = "x86_64" , feature = "sim-avx512" ) ) ]
84101 {
85- return "avx512" ;
102+ return SimdBackend :: Avx512 . as_str ( ) ;
86103 }
87104
88- #[ cfg( all( target_arch = "x86_64" , feature = "sim-avx2" ) ) ]
105+ // `not(sim-avx512)` keeps this mutually exclusive with the branch above
106+ // so `--all-features` (which enables every `sim-*` feature at once)
107+ // doesn't produce two unconditional `return`s in a row.
108+ #[ cfg( all(
109+ target_arch = "x86_64" ,
110+ feature = "sim-avx2" ,
111+ not( feature = "sim-avx512" )
112+ ) ) ]
89113 {
90- return "avx2" ;
114+ return SimdBackend :: Avx2 . as_str ( ) ;
91115 }
92116
93117 #[ cfg( all( target_arch = "aarch64" , feature = "sim-neon" ) ) ]
94118 {
95- return "neon" ;
119+ return SimdBackend :: Neon . as_str ( ) ;
96120 }
97121
98122 #[ allow( unreachable_code) ]
99- "scalar"
123+ SimdBackend :: Scalar . as_str ( )
100124}
0 commit comments