archmage/
lib.rs

1//! # archmage
2//!
3//! > Safely invoke your intrinsic power, using the tokens granted to you by the CPU.
4//! > Cast primitive magics faster than any mage alive.
5//!
6//! archmage provides capability tokens that prove CPU feature availability at runtime,
7//! making raw SIMD intrinsics safe to call via the `#[arcane]` macro.
8//!
9//! ## Quick Example
10//!
11//! ```rust,ignore
12//! use archmage::{Desktop64, HasAvx2, SimdToken, arcane};
13//! use archmage::mem::avx;  // Safe load/store (enabled by default)
14//! use std::arch::x86_64::*;
15//!
16//! #[arcane]
17//! fn multiply_add(token: impl HasAvx2, a: &[f32; 8], b: &[f32; 8]) -> [f32; 8] {
18//!     // Safe memory operations - references, not raw pointers!
19//!     let va = avx::_mm256_loadu_ps(token, a);
20//!     let vb = avx::_mm256_loadu_ps(token, b);
21//!
22//!     // Value-based intrinsics are SAFE inside #[arcane]!
23//!     let result = _mm256_add_ps(va, vb);
24//!     let result = _mm256_mul_ps(result, result);
25//!
26//!     let mut out = [0.0f32; 8];
27//!     avx::_mm256_storeu_ps(token, &mut out, result);
28//!     out
29//! }
30//!
31//! fn main() {
32//!     // Desktop64: AVX2 + FMA + BMI2 (Haswell 2013+, Zen 1+)
33//!     // CPUID check elided if compiled with -C target-cpu=native
34//!     if let Some(token) = Desktop64::summon() {
35//!         let result = multiply_add(token, &[1.0; 8], &[2.0; 8]);
36//!     }
37//! }
38//! ```
39//!
40//! ## How It Works
41//!
42//! **Capability Tokens** are zero-sized proof types created via `summon()`, which
43//! checks CPUID at runtime (elided if compiled with target features enabled).
44//!
45//! **The `#[arcane]` macro** generates an inner function with `#[target_feature]`,
46//! making intrinsics safe inside. The token parameter proves CPU support was verified.
47//!
48//! **Generic bounds** like `impl HasAvx2` let functions accept any token that
49//! provides AVX2 (e.g., `Avx2Token`, `Desktop64`, `Server64`).
50//!
51//! ## Feature Flags
52//!
53//! - `std` (default): Enable std library support
54//! - `macros` (default): Enable `#[arcane]` attribute macro (alias: `#[simd_fn]`)
55//! - `safe_unaligned_simd` (default): Safe load/store via references (exposed as `mem` module)
56//! - `__composite`: Higher-level ops (transpose, dot product) - unstable API
57//! - `__wide`: Integration with the `wide` crate - unstable API
58
59#![cfg_attr(not(feature = "std"), no_std)]
60#![cfg_attr(docsrs, feature(doc_cfg))]
61#![deny(unsafe_op_in_unsafe_fn)]
62#![warn(missing_docs)]
63
64#[cfg(feature = "std")]
65extern crate std;
66
67extern crate alloc;
68
69// Re-export arcane macro (and simd_fn alias) from archmage-macros
70#[cfg(feature = "macros")]
71#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
72pub use archmage_macros::{arcane, simd_fn};
73
74// Optimized feature detection
75#[cfg(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64"))]
76pub mod detect;
77
78// Core token types and traits
79pub mod tokens;
80
81// Integration layers
82#[cfg(any(feature = "__wide", feature = "safe_unaligned_simd"))]
83pub mod integrate;
84
85// Composite operations (requires "__composite" feature, unstable API)
86#[cfg(feature = "__composite")]
87#[cfg_attr(docsrs, doc(cfg(feature = "__composite")))]
88pub mod composite;
89
90// Safe unaligned memory operations (requires "safe_unaligned_simd" feature)
91// Wraps safe_unaligned_simd with token-based safety
92#[cfg(feature = "safe_unaligned_simd")]
93#[cfg_attr(docsrs, doc(cfg(feature = "safe_unaligned_simd")))]
94pub mod mem;
95
96// ============================================================================
97// Re-exports at crate root for convenience
98// ============================================================================
99
100// Core trait
101pub use tokens::SimdToken;
102
103// Composite token trait
104pub use tokens::CompositeToken;
105
106// Capability marker traits
107pub use tokens::{Has128BitSimd, Has256BitSimd, Has512BitSimd, HasFma, HasScalableVectors};
108
109// x86 feature marker traits (available on all architectures for cross-platform code)
110pub use tokens::{
111    HasAvx, HasAvx2, HasAvx512bw, HasAvx512f, HasAvx512vbmi2, HasAvx512vl, HasSse, HasSse2,
112    HasSse41, HasSse42,
113};
114
115// aarch64 feature marker traits (available on all architectures)
116pub use tokens::{HasNeon, HasSve, HasSve2};
117
118// All tokens available on all architectures (summon() returns None on wrong arch)
119pub use tokens::{
120    // x86 tokens
121    Avx2FmaToken, Avx2Token, Avx512Vbmi2Token, Avx512Vbmi2VlToken, Avx512bwToken, Avx512bwVlToken,
122    Avx512fToken, Avx512fVlToken, AvxToken, Desktop64, FmaToken, Server64, Sse2Token, Sse41Token,
123    Sse42Token, SseToken, X64V2Token, X64V3Token, X64V4Token,
124    // ARM tokens
125    Arm64, NeonToken, Sve2Token, SveToken,
126    // WASM tokens
127    Simd128Token,
128};