- Macrostep 00: Model contract and retained historical options. - Macrostep 01: Project foundation and configuration, including schema, presets, CLI, and CI setup. - Macrostep 02: Mathematical core implementation and deterministic oracles. - Macrostep 03: CPU-based planar simulation engine, FFT backend, and headless runner. Provides exhaustive objectives, phase breakdowns, validation policies, and deliverables for each macrostep.
149 lines
5.7 KiB
Markdown
149 lines
5.7 KiB
Markdown
# Macrostep 09 — Delayed-time backend
|
||
|
||
## Objective
|
||
|
||
Implement the distance-dependent delayed-time experiment as a deterministic, configurable 2-D backend with explicit history indexing, CPU oracle, accelerated GPU path, history diagnostics, and decoupled simulation/window resolution.
|
||
|
||
## Dependencies
|
||
|
||
Macrosteps 00–06 complete; follow the roadmap order after Macrostep 08.
|
||
|
||
## Phase 9.1 — Explicit history model
|
||
|
||
### Substep 9.1.1 — Storage and indexing
|
||
|
||
Represent history as `depth × height × width` with default depth 16 and a circular `head` denoting the next layer to overwrite. Define helpers:
|
||
|
||
```text
|
||
latest = wrap(head-1, depth)
|
||
sample(distance) = wrap(latest-floor(distance+0.5), depth)
|
||
```
|
||
|
||
Tests, UI, and shader must use the same integer helpers. Spatial x/y addressing is periodic. Window resize never changes simulation resolution by default.
|
||
|
||
### Substep 9.1.2 — Causal policy
|
||
|
||
Use one policy only: delay zero reads `latest`, and increasing rounded distance walks backward from it. Smooth dynamics also use `latest` as their base. The historical next-overwrite-head anomaly is discarded and is not configurable.
|
||
|
||
Use explicit integer layer selection; do not blur time through normalized 3-D texture interpolation.
|
||
|
||
## Phase 9.2 — Delayed neighborhood oracle
|
||
|
||
### Substep 9.2.1 — Stencil
|
||
|
||
Implement:
|
||
|
||
```text
|
||
ri = ra/3
|
||
inner width = outer width = 1
|
||
search radius = ceil(ra+0.5)
|
||
```
|
||
|
||
For each spatial offset, precompute:
|
||
|
||
- `(dx,dy)`;
|
||
- Euclidean distance;
|
||
- integer delay layer offset;
|
||
- disk and ring weights.
|
||
|
||
Normalize by numerically summing this exact discrete stencil, not analytic area.
|
||
|
||
### Substep 9.2.2 — CPU evaluation
|
||
|
||
For each output point, wrap x/y, choose the causal history layer, accumulate `M/N`, evaluate the shared rule, then:
|
||
|
||
```text
|
||
discrete: next = clamp(S)
|
||
smooth: next = clamp(history[latest] + 0.1*(2S-1))
|
||
```
|
||
|
||
Commit next into `history[head]`, then advance `head`. Separate `preview()` from `commit()` so pause semantics are explicit.
|
||
|
||
### Substep 9.2.3 — Pause and reset
|
||
|
||
Pause freezes output and head. Reset initializes every layer; recompute-without-commit and stale/undefined storage are not supported.
|
||
|
||
## Phase 9.3 — Initialization and interaction
|
||
|
||
Provide deterministic modes:
|
||
|
||
- all layers zero;
|
||
- one seeded frame replicated to all layers;
|
||
- independently seeded layers;
|
||
- populate one layer as an explicit analysis operation;
|
||
- source-inspired seeded boxes applied through a documented all-layer policy;
|
||
- import a restart state under an explicit layer-fill policy;
|
||
- import/export an exact checkpoint containing all history layers, `head`, generation, run descriptor, and RNG state.
|
||
|
||
The seeded box initializer uses width/height in `10..19` and one documented boundary policy, then initializes all layers explicitly. Keep reset and later overlay actions distinct; do not retain gradual history filling.
|
||
|
||
## Phase 9.4 — GPU history representation
|
||
|
||
### Substep 9.4.1 — Choose after capability spike
|
||
|
||
Preferred portable path is a tiled 2-D history atlas (default `4×4`) plus separate output/current targets. A texture array is an optional optimized path behind the same tested index abstraction.
|
||
|
||
Atlas requirements:
|
||
|
||
- integer tile/texel fetch;
|
||
- no interpolation bleed;
|
||
- dimensions preflighted against maximum texture size;
|
||
- clear ownership of padding;
|
||
- distinct read and write targets.
|
||
|
||
### Substep 9.4.2 — Rule pass and commit
|
||
|
||
Run the direct stencil pass using precomputed offsets/weights/delays (uniform buffer, lookup texture, or generated shader according to measured limits). Copy/blit output into the `head` tile only after all reads complete, then rotate the logical head. Never sample the atlas tile while writing it.
|
||
|
||
### Substep 9.4.3 — CPU/GPU parity
|
||
|
||
Read back `M`, `N`, output, and selected history tiles for small tests. Initial one-step max-error target: `≤1e-3`.
|
||
|
||
## Phase 9.5 — Workbench integration
|
||
|
||
Add:
|
||
|
||
- current committed state and computed preview;
|
||
- history timeline with selectable layer, age, and physical tile;
|
||
- radial delay map showing which distance uses which age;
|
||
- `M/N/S/increment` inspection;
|
||
- head/latest indicators;
|
||
- history initialization controls;
|
||
- direct/smooth mode selector;
|
||
- DT preset browser and model-resolution controls independent of window size.
|
||
|
||
Parameter edits state whether they preserve or reinitialize history. Rule-only edits may preserve state but must produce a reproducible run descriptor; radius or depth changes are cold rebuilds.
|
||
|
||
## Phase 9.6 — Verification
|
||
|
||
### History tests
|
||
|
||
1. Fill each layer with its index and verify every radial delay.
|
||
2. Test boundaries around `distance=n±0.5`.
|
||
3. Test head wrap `15→0`.
|
||
4. Verify smooth base is `head-1`.
|
||
5. Place one layer impulse and observe only the expected radial shell.
|
||
6. Verify x/y wrapping at all edges/corners.
|
||
7. Verify pause leaves head/state unchanged.
|
||
8. Verify every reset initializes all layers.
|
||
9. Verify atlas and CPU layouts select identical values.
|
||
|
||
### Performance target
|
||
|
||
At 512² and `ra≈12`, target p95 GPU step below 33 ms on the designated machine after offset/weight/delay precomputation. Keep CPU for correctness and reduced-resolution fallback. High-resolution cost limits must be visible before allocation.
|
||
|
||
## Deliverables
|
||
|
||
- CPU delayed-history oracle and GPU backend.
|
||
- One explicit causal indexing policy.
|
||
- Imported DT catalogue with named presets.
|
||
- History/radial-delay workbench views, restart-state export, and exact continuation checkpoints.
|
||
|
||
## Exit gate
|
||
|
||
- All layer, radial shell, wrap, pause, and reset tests pass.
|
||
- CPU/GPU one-step tolerance passes.
|
||
- Window resize does not reset history.
|
||
- No atlas bleed, uninitialized layer, or read/write alias exists.
|
||
- Every DT preset uses the causal latest-relative delay policy and is reproducible.
|