From 01a0a29b084fdcdad442f1a2568bc2f7b2b8ffc7 Mon Sep 17 00:00:00 2001 From: Peter Lukka Date: Tue, 19 May 2026 09:35:49 +0000 Subject: [PATCH] docs(reference): types.md AVX-512BW + missing unsigned wider-int gap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 unsigned wider-integer types (u32x4, u64x2, u64x4). All were already accepted by 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 flagged by the v1.14.0 u16x32 PR #29 spec post-mortem. The 512-bit section gained a "Feature" column distinguishing AVX-512F (foundation) from AVX-512BW (byte/word) so readers can predict which CPUs accept which types. Also adds a brief subsection acknowledging f16x{4,8} and the sub-128-bit narrow widths (i8x{4,8}, u8x8, i16x4, u16x4, i32x2) exist with target-specific semantics, with pointers to where they're documented in context (ARM reference for f16, intrinsics reference for the narrow-width consumers like wmul_i32). Doc-only — no code or public-api change. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 4 ++++ docs/src/reference/types.md | 39 ++++++++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 7 deletions(-) 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.