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: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Always keep the **compiler -> scheduler -> Verilog emission** chain coherent.
- `cw_reference.py`: software reference model for CW flows (one pass over `flow.stages` linear order, mirroring the coordinator state machine); consumed by the benchmark scoreboard and tests.
- `demo/de0-nano/basic-example/host/programs/run_cw_stress_benchmark.py`: live DE0-NANO scoreboard/observability harness for `CWs/example-program.cw`-class flows compiled into the board wrapper.
- `cw_lang.py`: the real `.cw` front-end (lexer → AST → recursive-descent parser → host-side tree-walking interpreter). Independent of `cw_compiler.py`'s regex/template RTL-lowering path. Owns **compile-time class magic methods** (operator overloading + type-conversion hooks `__to_int__`/`__to_float__`/`__convert__`); `Interpreter.convert()` is the toolchain hook for dynamic type-format conversion. Driven by the `cw-eval` CLI subcommand and the syntax side of `cw-lint`. Must not be wired into RTL lowering or the benchmark gate.
- `arch_search.py`: synthesis-time architecture-candidate enumeration and ranking (`arch-search` CLI) plus the simulator-driven fit finder (`fit-config` CLI via `run_fit_search`/`emit_fit_config`/`FitBudget`, schema `wau_fit_search_v1`). Reuses the real `compile_project`/`build_schedule` pipeline for performance metrics; owns 2D/3D grid-shape enumeration (fixed-core-count reshapes for `arch-search`; variable-core-count sweeps bounded by a device budget for `fit-config`), the versioned estimate models (`wau_resource_model_v1`, `dram_model_v1`, `arch_search_rank_v1`), and reads device capacity metadata (`logic_cells`/`bram_kbits`/`dsp_blocks`) from `device_library.py`. Must not change scheduling/emission behavior — it only builds and evaluates candidate config payloads in memory. `run_arch_search` must stay byte-identical (guarded by `tests/python/test_arch_search.py`); `fit-config` is additive.
- `arch_search.py`: synthesis-time architecture-candidate enumeration and ranking (`arch-search` CLI) plus the simulator-driven fit finder (`fit-config` CLI via `run_fit_search`/`emit_fit_config`/`FitBudget`, schema `wau_fit_search_v1`). Reuses the real `compile_project`/`build_schedule` pipeline for performance metrics; owns 2D/3D grid-shape enumeration (fixed-core-count reshapes for `arch-search`; variable-core-count sweeps bounded by a device budget for `fit-config`), the versioned estimate models (`wau_resource_model_v1`, `dram_model_v1`, `arch_search_rank_v1`), and reads device capacity metadata (`logic_cells`/`bram_kbits`/`dsp_blocks`) from `device_library.py`. `fit-config` additionally co-sweeps `coordinator.max_in_flight` (`CandidateKnobs.max_in_flight`, `--max-in-flight`, workload-bounded via `_fit_max_in_flight_values`) so single-flow workloads reclaim the LUTs unused in-flight slots would cost; `arch-search` never sets this dimension. Must not change scheduling/emission behavior — it only builds and evaluates candidate config payloads in memory. `run_arch_search` must stay byte-identical (guarded by `tests/python/test_arch_search.py`); `fit-config` is additive.
- `scripts/find_best_wau_config.py`: thin convenience wrapper over `waugen fit-config` (a `.cw` kernel or `.json` workload -> best/efficient config recommendation). Keeps all logic in `arch_search.py`.
- `scripts/fetch_dataset.py` (+ `.ps1`): on-demand, git-ignored dataset download (MNIST via the CVDF mirror) for data-exchange testing; also exposes `load_mnist_images`/`load_mnist_labels` readers. `datasets/` is git-ignored and never committed.
- `src/python/configs/wau_cw_fit_base.json`: minimal, demo-independent DE0-NANO base used to compile a raw `.cw` for `fit-config` and as the base for `scripts/run_cw_stress_benchmark.sh`. Carries the full `add/sub/mul/div/max` op set so the fixed ALU testbench elaborates; the board keeps its own lean `add/mul/max` base (`wau_de0_nano_cw_stress_base.json`).
Expand Down Expand Up @@ -96,7 +96,7 @@ Always keep the **compiler -> scheduler -> Verilog emission** chain coherent.
- `run_cw_example_benchmark.sh` must produce a valid `benchmarks/example_pogram_benchmark.txt` log with passing RTL tests, CW execution metrics, and `scoreboard_pass_ratio == 1.0`.
- `run_cw_stress_benchmark.sh` is a thin wrapper over the same engine for `CWs/stress/mesh_stress.cw`; it must write only `benchmarks/mesh_stress_*` artifacts and must never overwrite the CI-gated `example_pogram_*` files. It must also keep `scoreboard_pass_ratio == 1.0`.
- All real `.cw` programs live under `CWs/` (canonical location). Historical board reports (`benchmarks/de0_nano_*`) and dated ROADMAP entries keep their original `docs/...` paths as run-time records and must not be rewritten.
- `waugen.arch_search.run_arch_search` must stay byte-identical (guarded by `tests/python/test_arch_search.py`); `fit-config`/`run_fit_search` is additive and must not alter `arch-search` behavior. `fit-config` must only build/evaluate candidate payloads in memory (no scheduling/emission changes).
- `waugen.arch_search.run_arch_search` must stay byte-identical (guarded by `tests/python/test_arch_search.py`); `fit-config`/`run_fit_search` is additive and must not alter `arch-search` behavior. `fit-config` must only build/evaluate candidate payloads in memory (no scheduling/emission changes). The `CandidateKnobs.max_in_flight` co-sweep dimension defaults to `None` (leaves `coordinator.max_in_flight` untouched and omits the `_mif` id suffix / knobs key) precisely so `arch-search` reports stay byte-identical; only `fit-config` sets it. Swept depths must stay within the coordinator's `[1,16]` schema range.
- Whenever new possible future implementations, optimizations, or architecture changes are identified, update `ROADMAP.md` in the same work cycle.
- Whenever workflow steps, ownership boundaries, invariants, or scope change, update both `AGENTS.md` and `README.md` in the same work cycle.

Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,15 @@ ceiling. `fit-config` is additive; `arch-search` (fixed-core-count reshapes) is
unchanged. Use `--quick` for a grid-only sweep, `--lut-budget` /
`--max-utilization` / `--tolerance` to tune the envelope.

Alongside grid shape, op distribution, and memory split, `fit-config` also
co-sweeps `coordinator.max_in_flight`: every in-flight slot costs LUTs, but the
depth only buys makespan when independent flows overlap, so the finder tries the
workload-appropriate depths (a single-flow program collapses to `1`, reclaiming
those LUTs; multi-flow workloads try `1`, powers of two, and the flow-count
ceiling) and the ranker keeps the cheapest depth that doesn't cost makespan.
Override the depths with `--max-in-flight 1,2,4`; the swept set is reported as
`max_in_flight_swept` and encoded in each candidate id as a `_mif<N>` suffix.

### Datasets for data-exchange testing

Real operand streams (instead of random data) make the mesh/JTAG throughput
Expand Down
40 changes: 36 additions & 4 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,37 @@ Completed baseline:
- Generated RTL for coordinator/core/station/ALU/top.
- Initial verification with Python unit tests + `iverilog` testbenches.

## Progress Update (2026-07-11)
Implemented this cycle:
- **`fit-config` co-sweeps `coordinator.max_in_flight`** (2026-07-07 follow-up
"co-sweep `coordinator.max_in_flight` inside `fit-config`, currently fixed by
the compiled flow"). The fit finder now varies the coordinator in-flight depth
as a fourth candidate axis alongside grid shape / op distribution / memory
split. Every in-flight slot costs LUTs in `wau_resource_model_v1`, but the
depth only buys makespan when independent flows overlap, so the swept depths
are workload-bounded (`_fit_max_in_flight_values`): a **single-flow** workload
collapses to depth `1` (cycle-identical there, so higher depths would only
burn LUTs), while multi-flow workloads try `1`, powers of two, the base value,
and the flow-count ceiling (clamped to the `[1,16]` schema range). Because the
ranker's LUT tiebreaker follows makespan/hops, it keeps the cheapest depth
that doesn't cost makespan — e.g. on the 4-flow `wau_example_pogram_compiled`
workload the `mif1` variants outrank the equal-makespan `mif2`/`mif4` variants
by ~2% fewer estimated LUTs. `--max-in-flight 1,2,4` forces the set; the swept
depths are reported as `max_in_flight_swept` and encoded per candidate as a
`_mif<N>` id suffix (round-tripped by `emit_fit_config`).
- Kept **additive**: `CandidateKnobs.max_in_flight` defaults to `None`
(leaves `coordinator.max_in_flight` untouched, no `_mif` suffix, no knobs
key), so `arch-search` reports stay byte-identical — verified against the
pre-change output and guarded by
`tests/python/test_arch_search.py::ArchSearchReportTests.test_arch_search_never_sweeps_max_in_flight`.
On `mesh_stress.cw` the efficient recommendation is unchanged (`2x2`, the
empirically validated board ceiling) and the candidate count is identical
(single flow ⇒ one depth).
- New coverage: `FitMaxInFlightSweepTests` (depth bounds, reported swept set,
lower-depth-never-costs-more-LUTs monotonicity, explicit override, emit
round-trip) plus two CLI tests (`--max-in-flight` override + invalid-value
rejection). Full Python suite: 112 tests pass (was 104).

## Progress Update (2026-07-07)
Implemented this cycle (DE0-NANO real-board testing support):
- **Grid-scaling fit search** (`waugen fit-config` + `waugen.arch_search.run_fit_search`):
Expand Down Expand Up @@ -68,10 +99,11 @@ Implemented this cycle (DE0-NANO real-board testing support):
`CWs/samples/{nn,types}/*.cw`, `CWs/stress/mesh_stress.cw`); tests, docs,
scripts, and the demo updated. Historical board reports and dated ROADMAP
entries keep their original paths as run-time records.
- Follow-ups: co-sweep `lane_parallelism`/`coordinator.max_in_flight` inside
`fit-config` (currently fixed by the compiled flow); calibrate the fit
resource model against real DE0-NANO synthesis so the LUT budget maps to
measured LEs; feed board-measured stress-kernel scores back into the ranking.
- Follow-ups: co-sweep `lane_parallelism` inside `fit-config` (still fixed by
the compiled flow — `coordinator.max_in_flight` co-sweep landed 2026-07-11,
see below); calibrate the fit resource model against real DE0-NANO synthesis
so the LUT budget maps to measured LEs; feed board-measured stress-kernel
scores back into the ranking.

## Progress Update (2026-07-06)
Implemented this cycle:
Expand Down
Loading
Loading