diff --git a/CLAUDE.md b/CLAUDE.md index 005543d..f99e4cb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,15 +14,17 @@ which of its decisions were superseded. Read PLAN.md before implementing anythin re-derive decisions it has already settled (compile-time direction, profile vocabulary, the three-leg test strategy, the pinned-eps cross-validation design). -Current state: **v0.1 (M6 complete), M7a measurement harness landed.** Design/schedule/tables -(M2), the streaming converter for float/Q15/Q31 with committed scipy reference vectors (M3/M4), -the golden cross-validation against SampleRateTap at pinned eps (M5, test-only submodule), the -bluetooth_bridge example + C ABI + executed demo notebook (M6), and the embedded CI matrix + -instruction-count ratchet (M7a: Cortex-M33/M55 + Hexagon under QEMU, eight fixed workloads gated -two-sided ±3% against `bench/baselines.json` — `scripts/icount.py`). Next: the M7 levers, one -measured PR each, superblock codegen first — see PLAN.md section 7. Any change that moves a -workload's count beyond ±3% must re-record baselines (`icount.py --update` per target) in the -same PR; an *improvement* beyond tolerance fails the gate too, by design. +Current state: **v0.2 — M7 codegen phase complete.** v0.1 (M0–M6): design/schedule/tables, the +streaming converter for float/Q15/Q31 with committed scipy reference vectors, the golden +cross-validation against SampleRateTap at pinned eps (test-only submodule), bluetooth_bridge + +C ABI + executed notebook. M7 (v0.2): the embedded CI matrix + instruction-count ratchet +(Cortex-M33/M55 + Hexagon under QEMU, eight workloads gated two-sided ±3% against +`bench/baselines.json` — `scripts/icount.py`), then three measured codegen levers — superblock +walk, committed trip counts, symmetry-halved tables — outputs bit-identical throughout; PLAN.md +section 7 records each lever's numbers. Remaining levers are deferred until a consumer pulls +them (they change the output contract). Any change that moves a workload's count beyond ±3% +must re-record baselines (`icount.py --update` per target) in the same PR; an *improvement* +beyond tolerance fails the gate too, by design. ## The charter constraints (load-bearing) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a88d61..428a62b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.24) -project(RatioTap VERSION 0.1.0 LANGUAGES CXX) +project(RatioTap VERSION 0.2.0 LANGUAGES CXX) # ============================================================================== # RatioTap — synchronous 44.1 <-> 48 kHz sample rate conversion, as fast as diff --git a/PLAN.md b/PLAN.md index aee7555..44fdfe3 100644 --- a/PLAN.md +++ b/PLAN.md @@ -273,11 +273,18 @@ executed (it measures the shipping C++, not a Python re-implementation). (Hexagon down_q31 +2.7%); Arm came out slightly ahead (M33 Q31 −2.5%). v0.1 ships at M6. Nothing in M7+ blocks it. **Status: M0–M6 complete — -v0.1 shipped (2026-07-23). M7a measurement harness + M7b superblock -codegen + M7c committed trip counts + M7d symmetry halving landed -(2026-07-23/24); next lever candidates: multistage decomposition, -minimum-phase economy variant, or the M33 float story if a consumer -needs it.** +v0.1 shipped (2026-07-23). M7 codegen phase complete — v0.2 (2026-07-24): +M7a measurement harness, M7b superblock codegen, M7c committed trip +counts, M7d symmetry halving, all measured, outputs bit-identical +throughout. Cumulative vs the M7a baselines: M55 Q15 −59%/−60% and float +−35%/−37%; M33 Q31 −26%/−27%, Q15 −15%/−16%; Hexagon Q15 −13%/−10%, +Q31 −15%/−7%; table storage halved. The remaining levers (multistage +decomposition, minimum-phase economy, IIR pre-filter, FFT offline path) +all change the output contract or serve currently-unpressured needs +(storage, latency) — deferred until a consumer pulls them: a latency +need pulls minimum-phase; a storage need pulls multistage; an MCU float +consumer pulls the accumulation-contract discussion (a DspTap decision, +since double accumulation is the float golden model's identity).** ## 8. Acceptance criteria (v0.1) diff --git a/README.md b/README.md index 81d9e1c..067a9db 100644 --- a/README.md +++ b/README.md @@ -13,18 +13,24 @@ on the Tap family's shared FIR substrate float/Q15/Q31 sample-format traits, measured dot-product kernels, row-sum quantization, measurement instruments). -> **Status: v0.1 (milestone M6).** The converter is in for all three sample -> formats: float (the golden model, pinned against committed scipy -> reference vectors sample-for-sample), Q31 (tracks float within −147 dB; -> measures 146 dB at 997 Hz — exceeding float, whose float32 I/O is its -> own bound), and Q15 (format-limited: pair it with `economy`, which is -> both cheaper *and* quieter than `transparent` at 16 bits). The golden -> cross-validation against SampleRateTap's async engine at pinned -> eps = L/M−1 agrees to −109 dB (down) / −99 dB (up) over every phase. -> The `bluetooth_bridge` example, the C ABI (`tools/capi/`), and the -> executed demo notebook (`notebooks/ratio_demo.ipynb`) complete v0.1. +> **Status: v0.2 (M7 codegen campaign).** v0.1 shipped the converter for +> all three sample formats: float (the golden model, pinned against +> committed scipy reference vectors sample-for-sample), Q31 (tracks float +> within −147 dB), and Q15 (format-limited: pair it with `economy`, which +> is both cheaper *and* quieter than `transparent` at 16 bits), plus the +> golden cross-validation against SampleRateTap's async engine (−109 dB +> down / −99 dB up over every phase), the `bluetooth_bridge` example, the +> C ABI, and the executed demo notebook. v0.2 is the measured optimization +> campaign on top — four levers, each gated by the instruction-count +> ratchet, outputs bit-identical throughout: the superblock walk, +> committed compile-time trip counts, and symmetry-halved tables. Since +> the campaign's baselines: **Q15 −59%/−60% and float −35%/−37% on +> Cortex-M55, Q31 −26%/−27% on Cortex-M33, Q15 −13%/−10% on Hexagon — +> with table storage halved** (economy Q15 up: 6.9 KiB). The remaining +> PLAN §7 levers (multistage, minimum-phase, IIR, FFT) change the output +> contract and stay deferred until a consumer needs them. > [PLAN.md](PLAN.md) is the authoritative roadmap (charter, architecture -> decisions, milestones, acceptance criteria); +> decisions, milestones, acceptance criteria, per-lever measurements); > [HANDOFF.md](HANDOFF.md) is the original design brief it grew from. ## Quick start diff --git a/include/tap/ratio/ratio.h b/include/tap/ratio/ratio.h index 4d0be5d..0d496eb 100644 --- a/include/tap/ratio/ratio.h +++ b/include/tap/ratio/ratio.h @@ -35,7 +35,7 @@ #include "tap/ratio/schedule.h" // IWYU pragma: export #define TAP_RATIO_VERSION_MAJOR 0 -#define TAP_RATIO_VERSION_MINOR 1 +#define TAP_RATIO_VERSION_MINOR 2 #define TAP_RATIO_VERSION_PATCH 0 namespace tap::ratio {