hermes_simd_core/arch.rs
1//! Target architecture definition trait with architecture-level constants.
2//!
3//! `SimdArch` is a sealed-by-convention trait implemented by ZST markers.
4//! Constants here are architecture-wide and do not require a scalar type `T` binding,
5//! unlike `SimdKernel<T>` which is type-parameterized.
6
7/// ISA family classification for architecture markers.
8///
9/// Used for compile-time routing and documentation. Does not affect code generation.
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11pub enum IsaFamily {
12 /// x86 and x86_64 (SSE, AVX, AVX-512 families).
13 X86,
14 /// AArch64 (NEON, SVE, SME families).
15 AArch64,
16 /// RISC-V (V extension).
17 RiscV,
18 /// No vector ISA; pure scalar fallback.
19 Scalar,
20 /// Other or experimental architecture.
21 Other,
22}
23
24/// Trait representing a SIMD instruction set architecture.
25///
26/// Implemented by Zero-Sized Types (ZSTs). Constants are queryable without a scalar
27/// type parameter — contrast with `SimdKernel<T>` which requires `T` to be known.
28pub trait SimdArch: crate::private::Sealed + Send + Sync + 'static + Copy + Clone {
29 /// Human-readable ISA name (`"avx2"`, `"avx512"`, `"neon"`, `"scalar"`).
30 const NAME: &'static str;
31
32 /// Width of vector registers in bits.
33 ///
34 /// | Architecture | Width |
35 /// |---|---|
36 /// | `Scalar` | `0` |
37 /// | `Neon` | `128` |
38 /// | `Avx2` | `256` |
39 /// | `Avx512` | `512` |
40 const REGISTER_WIDTH_BITS: u32;
41
42 /// ISA family for this architecture.
43 const ISA_FAMILY: IsaFamily;
44
45 /// Suggested `TILE_M` value for `tiled_dot` to saturate FMA throughput.
46 ///
47 /// This is a hint, not a constraint. Optimal values:
48 /// - `Scalar`: 1 (no tiling benefit)
49 /// - `Neon`: 4 (4 NEON regs × 4-cycle FMA latency)
50 /// - `Avx2`: 4 (16 YMM / TILE_M=4 leaves headroom for loop overhead)
51 /// - `Avx512`: 8 (32 ZMM / TILE_M=8 saturates two FMA ports)
52 const FMA_THROUGHPUT_HINT: u32;
53
54 /// Returns true when the current host may execute this architecture's
55 /// native instructions from safe wrappers.
56 ///
57 /// Emulated backends return `true`; native ISA backends must include the
58 /// OS-enabled register-state checks covered by the platform feature probe.
59 fn is_runtime_supported() -> bool;
60}
61
62/// Panics unless `Arch` can execute on this host.
63///
64/// Kernel methods are `#[target_feature]`-gated, so invoking one on a host
65/// lacking those features is undefined behavior. Types parameterized by `Arch`
66/// call this where they are built, which turns "the host supports `Arch`" into
67/// an invariant of holding the value — the discharge every `unsafe` kernel call
68/// downstream relies on. Constructors that can report failure return `None`
69/// instead of calling this.
70///
71/// The probe caches its CPUID result, so repeated calls are a relaxed load.
72///
73/// # Panics
74/// If `Arch::is_runtime_supported()` is false.
75#[inline]
76pub(crate) fn assert_arch_executable<Arch: SimdArch>() {
77 assert!(
78 Arch::is_runtime_supported(),
79 "SIMD target {} is not supported or enabled on this host",
80 Arch::NAME
81 );
82}