Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <manifest.toml>` 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.
Expand Down
39 changes: 32 additions & 7 deletions docs/src/reference/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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.
Expand Down
Loading