diff --git a/CHANGELOG.md b/CHANGELOG.md index 22a8c27..647b32e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ - `log_approx_f32(v: f32xN) -> f32xN` — natural log via Eigen/Cephes-family polynomial approximation. Bit-level decomposition (`x = m · 2^e` with `m ∈ [0.5, 1)`), √2/2 rebalance to center the polynomial range, degree-8 Horner in `(m - 1)`, Cody-Waite recombine with `e · ln(2)`. Max absolute error ~3e-6 across `(0, +∞)`. Avoids `@llvm.log.v*f32`, which LLVM scalarizes to per-lane libm `logf`. Companion to `exp_poly_f32` (v1.11.0) and `tanh_approx_f32` (v1.14.0); composes with `exp_poly_f32` to roundtrip-test pinned at ~1e-4 relative error. - `sin_approx_f32(v: f32xN) -> f32xN` and `cos_approx_f32(v: f32xN) -> f32xN` — polynomial sin/cos via shared mod-π/2 range reduction (2-piece Cody-Waite + FMA), Taylor-truncated polynomials over `d' ∈ [-π/4, π/4]`, and a quadrant blend. The `cos` variant reuses the same core via `q += 1` (precision-free integer shift expressing `cos(x) = sin(x + π/2)`). Max abs error ~3e-6 across `[-1e7, 1e7]`. Closes the original "Future API consistency" trio (`tanh_approx_f32` v1.14.0, `log_approx_f32` v1.14.0, sin/cos v1.14.0); the f32 transcendental approximation family is feature-complete. +### Docs + +- **`docs/src/reference/types.md` AVX-512BW gap.** The 512-bit AVX-512 section listed only `f32x16`, `f64x8`, `i32x16` — none of the AVX-512BW byte/word integer types (`i8x64`, `u8x64`, `i16x32`, `u16x32`) or the AVX-512F `u64x8`. The 128-bit and 256-bit sections were also missing the unsigned wider-integer types (`u32x4`, `u64x2`, `u64x4`). All were already in the lexer; the table just hadn't kept up across v1.12.0 (`u64x{2,4,8}`) and v1.14.0 (`u16x32`). Surfaced as a follow-up in the v1.14.0 `u16x32` PR #29 spec post-mortem. The 512-bit section gained a new "Feature" column distinguishing AVX-512F (foundation) from AVX-512BW (byte/word). + ## v1.13.0 — 2026-05-15 — ea bench + first aarch64 baselines + Specification umbrella Standing benchmark suite for the v1.11.0 audit kernels. Converts performance regression detection from vigilance-dependent to mechanical: `ea bench ` builds an `.ea` kernel + C harness, runs the harness pinned to one core (`taskset` on Linux), captures JSONL measurements, wraps them with environment metadata, and diffs against a committed baseline JSON. Day-one manifests cover `exp_poly_f32` (x86_64 only — kernel uses `f32x8`), `fp16_kv` (aarch64), and `gather_compose` (x86 + ARM variants), with baselines captured on the maintainer's x86_64 dev host and the Raspberry Pi 5 (Cortex-A76). Warn-only regression gate at 10% in v1.13.0 — regressions print `WARNING:` but the process still exits 0 so we collect runner-variance signal for one release before deciding the threshold. Companion docs: a new Specification umbrella at `docs/src/reference/index.md` gives the language reference a single canonical entry point, and `RELEASING.md` documents the maintainer pre-tag ritual. diff --git a/docs/src/reference/types.md b/docs/src/reference/types.md index b4c4a04..967d240 100644 --- a/docs/src/reference/types.md +++ b/docs/src/reference/types.md @@ -31,10 +31,12 @@ Vector types hold multiple lanes of the same scalar type. Element-wise operation | `f32x4` | 4 | `f32` | 16 bytes | | `f64x2` | 2 | `f64` | 16 bytes | | `i32x4` | 4 | `i32` | 16 bytes | +| `u32x4` | 4 | `u32` | 16 bytes | | `i16x8` | 8 | `i16` | 16 bytes | +| `u16x8` | 8 | `u16` | 16 bytes | | `i8x16` | 16 | `i8` | 16 bytes | | `u8x16` | 16 | `u8` | 16 bytes | -| `u16x8` | 8 | `u16` | 16 bytes | +| `u64x2` | 2 | `u64` | 16 bytes | ### 256-bit Vectors -- AVX2 (x86 only) @@ -44,22 +46,45 @@ Vector types hold multiple lanes of the same scalar type. Element-wise operation | `f64x4` | 4 | `f64` | 32 bytes | | `i32x8` | 8 | `i32` | 32 bytes | | `i16x16` | 16 | `i16` | 32 bytes | +| `u16x16` | 16 | `u16` | 32 bytes | | `i8x32` | 32 | `i8` | 32 bytes | | `u8x32` | 32 | `u8` | 32 bytes | -| `u16x16` | 16 | `u16` | 32 bytes | +| `u64x4` | 4 | `u64` | 32 bytes | These types produce a compile error on ARM targets. ### 512-bit Vectors -- AVX-512 (x86, `--avx512` flag required) -| Type | Lanes | Element | Size | -|------|-------|---------|------| -| `f32x16` | 16 | `f32` | 64 bytes | -| `f64x8` | 8 | `f64` | 64 bytes | -| `i32x16` | 16 | `i32` | 64 bytes | +`f32x16`, `f64x8`, `i32x16`, and `u64x8` lower to AVX-512F instructions. +`i8x64`, `u8x64`, `i16x32`, and `u16x32` additionally require AVX-512BW +(byte/word SIMD), which is present on Skylake-SP, Ice Lake, Zen 4, and +later. Eä emits both feature flags when `--avx512` is set. + +| Type | Lanes | Element | Size | Feature | +|------|-------|---------|------|---------| +| `f32x16` | 16 | `f32` | 64 bytes | AVX-512F | +| `f64x8` | 8 | `f64` | 64 bytes | AVX-512F | +| `i32x16` | 16 | `i32` | 64 bytes | AVX-512F | +| `u64x8` | 8 | `u64` | 64 bytes | AVX-512F | +| `i16x32` | 32 | `i16` | 64 bytes | AVX-512BW | +| `u16x32` | 32 | `u16` | 64 bytes | AVX-512BW | +| `i8x64` | 64 | `i8` | 64 bytes | AVX-512BW | +| `u8x64` | 64 | `u8` | 64 bytes | AVX-512BW | Using these types without `--avx512` produces a compile error. +### Half-precision and sub-128-bit narrow widths + +The lexer also accepts `f16x4` / `f16x8` (half-precision float vectors) and +sub-128-bit narrow widths used by ARM NEON widening intrinsics: `i8x4`, +`i8x8`, `u8x8`, `i16x4`, `u16x4`, `i32x2`. These have target-specific +constraints (`f16` requires `--fp16` on aarch64 and is unavailable on +plain x86; the narrow widths exist primarily as inputs to widening +multiplies like `wmul_i32(i16x4, i16x4) -> i32x4`) that are documented +alongside the intrinsics that consume them rather than as standalone +table rows. See [ARM / NEON reference](arm.md) for `f16` and +[All Intrinsics](intrinsics.md) for the narrow-width consumers. + ## Pointer Types Pointers represent caller-provided memory. Eä never allocates -- all memory comes from the host language.