ferrox_core/vexp.rs
1//! The `ggml_v_expf` polynomial, shared.
2//!
3//! `attention` (softmax) and `matmul` (GELU/SiLU) each had a private
4//! copy of these nine constants. They were byte-identical, and nine
5//! duplicated magic numbers in two hot kernels is a drift hazard: a
6//! correction applied to one copy and not the other is invisible until
7//! two paths disagree about a number.
8//!
9//! What is NOT shared is the clamp, and that is deliberate. A softmax
10//! argument is always `<= 0`, so `attention` clamps below only. A GELU
11//! or SiLU argument is unbounded and appears as a DENOMINATOR, so a
12//! saturated exponential there divides a numerator with no bound of its
13//! own: `matmul` must select zero above the clamp rather than merely
14//! clamp. Each file keeps its own clamp constant next to the code that
15//! relies on it.
16//!
17//! Source: `ggml/src/ggml-cpu/vec.h`, ARM optimized-routines `expf`.
18
19/// `0x1.8p23`: adding this to `x*log2(e)` rounds it to an integer and
20/// parks that integer in the mantissa's low bits.
21pub const EXP_SHIFT: f32 = 12582912.0;
22/// `log2(e)`, `0x1.715476p+0`.
23pub const EXP_LOG2E: f32 = std::f32::consts::LOG2_E;
24/// High half of `ln 2`, `0x1.62e4p-1`, chosen with trailing zero bits
25/// so `n * ln2_hi` is exact in `f32`.
26pub const EXP_LN2_HI: f32 = 0.693_145_75;
27/// Low half of `ln 2`, `0x1.7f7d1cp-20`.
28pub const EXP_LN2_LO: f32 = 1.428_606_8e-6;
29/// Minimax coefficients for `e^b - 1` on `[-ln2/2, ln2/2]`:
30/// `0x1.ffffecp-1`, `0x1.fffdb6p-2`, `0x1.555e66p-3`, `0x1.573e2ep-5`,
31/// `0x1.0e4020p-7`.
32pub const EXP_C0: f32 = 0.999_999_4;
33pub const EXP_C1: f32 = 0.499_991_27;
34pub const EXP_C2: f32 = 0.166_683_96;
35pub const EXP_C3: f32 = 0.041_899_767;
36pub const EXP_C4: f32 = 0.008_247_39;