gqa(adr): ADR-0064/0065 second-pass review — 1024B rationale, FIFO as ordering source, robust formula-based tests, D5/D6 auto-bind alignment
ADR-0064 Revision 2 second-pass review fixes: - D7 added 1024-byte cap rationale: explicitly framed as a *safe engineering limit* (intentionally above all known composites at ~322 bytes, finite descriptor capacity placeholder), not a measured HW number. Default is the discipline; topology override for real HW. - D7 segment ordering: strict FIFO is the *ordering source*; rw_handles is dependency metadata, not the ordering primitive. Explicit note for the future RW-aware reorder migration path. - Tests rewritten around the formula (D1) instead of specific numbers: - Test #1 → "formula preservation" (parametrized across composites, asserts dispatch == FIXED + bytes × R, not anchor 43 ns). - Test #2 → robust "opt3 > 2 × opt2" qualitative gate; ≈ 4.0× is informative only, not the gate, so calibration changes don't break. - Test #9 → qualitative (opt2 < opt3 at all R), not a numeric ratio. - Anchor description in D3 stays as *informative* (shows the model produces ≈ 43 ns at defaults), but is no longer a test gate. ADR-0065 second-pass review: - D5 step 5 aligned with D6.6 invariant: explicit conflict check before auto-binding (previously written as if auto-bind always happens). Mirrors D6.6 wording: error if both kernel explicit `a` and prologue primary_out are present. - Test #7 made robust: `opt3 > 2 × opt2` gate (was ≈ 4.0×). Default-calibration model expectation (≈ 4.0×) recorded as informative reference, not the gate. DDD-0065 follow-on robust thresholds: - §1.4 success criteria: ratio condition rewritten as `opt3 > 2 × opt2` with model-expected ≈ 4.0× as informative. - §9 P6 phase gate: `opt3 > 2 × opt2` (was 4.0× ± 15%). - §10 dispatch ratio test: assert `opt3 > 2 × opt2`; record observed ratio for performance tracking but do not gate on it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -234,14 +234,31 @@ issue cost 를 0 → non-zero 로 바꾸면 **모든** bench 의 latency 변화.
|
|||||||
- segmentation 알고리즘 결정적 (emit 순서로 op 인덱스 greedy); host
|
- segmentation 알고리즘 결정적 (emit 순서로 op 인덱스 greedy); host
|
||||||
emitter 의 일부, PE_SCHEDULER 가 아님.
|
emitter 의 일부, PE_SCHEDULER 가 아님.
|
||||||
|
|
||||||
이게 필요한 이유. 실제 하드웨어는 descriptor queue entry 크기, scheduler
|
**cap 이 필요한 이유.** 실제 하드웨어는 descriptor queue entry 크기,
|
||||||
parser buffer, command SRAM, firmware 입력의 하드 제한 보유. cap 없으면
|
scheduler parser buffer, command SRAM, firmware 입력의 하드 제한 보유.
|
||||||
`FIXED + bytes × R` 모델이 하드웨어가 받지 못할 정도로 큰 fused composite
|
cap 없으면 `FIXED + bytes × R` 모델이 하드웨어가 받지 못할 정도로 큰
|
||||||
를 보상 (예: primitive 100 개를 composite 1 개로 fuse, FIXED 1 회만 지불).
|
fused composite 를 보상 (예: primitive 100 개를 composite 1 개로 fuse,
|
||||||
~30 bytes 짜리 op 100 개의 composite = ~3000 bytes > 1024 cap → 3 개로
|
FIXED 1 회만 지불).
|
||||||
segment → 3 × FIXED, 정직한 회계 회복.
|
|
||||||
|
|
||||||
Decode opt2 의 `#2` composite (10 ops, ~310 bytes) 는 1024 cap 안에
|
**1024 bytes 라는 *특정* 숫자의 근거.** 이는 측정된 HW 숫자가 아니라
|
||||||
|
**safe engineering limit** — kernbench 코드베이스의 현재 모든 알려진
|
||||||
|
composite (가장 큰 것이 decode opt2 의 `#2` ~322 bytes) 보다 훨씬 위이면서
|
||||||
|
미래 recipe 도 지켜야 할 *유한* descriptor capacity 를 의도적으로 표현.
|
||||||
|
값은 topology 별 override (D4); 실제 HW reference 등장 시 재캘리브레이션.
|
||||||
|
이 default 의 역할은 cap 을 *원칙으로 존재시키는 것*, 특정 HW 에 맞추는
|
||||||
|
것이 아님.
|
||||||
|
|
||||||
|
**segment 간 순서 — strict FIFO 가 주체, `rw_handles` 아님.** segment 들은
|
||||||
|
emit 순서로 PE_CPU → PE_SCHEDULER 큐에 들어감. strict-FIFO dispatch
|
||||||
|
(ADR-0065 D6.3) 가 *순서의 주체* — segment 가 큐 진입 순서로 실행. 각
|
||||||
|
segment 의 `rw_handles` block 은 cross-composite 해저드 추적기의 **의존성
|
||||||
|
메타데이터** — 그 자체로 inter-segment 순서를 보장하지 **않음**. 미래
|
||||||
|
scheduler 가 FIFO 를 완화 (예: RW-aware reorder, ADR-0065 A4) 한다면
|
||||||
|
segmenter 는 (a) segment 를 단일 CompositeCmd 로 merge 또는
|
||||||
|
(b) 명시적 completion-handle 의존 체인 도입 필요. Phase 1 에선 무관 —
|
||||||
|
strict FIFO 가 유효.
|
||||||
|
|
||||||
|
Decode opt2 의 `#2` composite (10 ops, ~322 bytes) 는 1024 cap 안에
|
||||||
편안히 — GQA workload 에 segmentation 없음.
|
편안히 — GQA workload 에 segmentation 없음.
|
||||||
|
|
||||||
## Alternatives
|
## Alternatives
|
||||||
@@ -307,12 +324,24 @@ fold. calibration 이 분리 필요성을 보이면 PE_DMA fixed setup 으로
|
|||||||
|
|
||||||
## Test Requirements
|
## Test Requirements
|
||||||
|
|
||||||
1. **Anchor 보존.** DMA-staged GEMM 경로용 단일-OpSpec composite
|
테스트는 specific 숫자 anchor 가 아닌 **공식 (D1)** 에 대해 작성 —
|
||||||
(`logical_bytes ≈ 54`) 가 default 값에서 ≈43 ns 에 dispatch (±2 ns).
|
calibration 이 바뀌거나 OpSpec/CompositeCmd 필드가 추가되어도 유효.
|
||||||
2. **구조적 ratio.** opt3 vs opt2 dispatch (ADR-0065 §verification 의):
|
|
||||||
default calibration 에서 `opt3 / opt2 ≈ 4.0×`.
|
1. **공식 보존.** 임의 `CompositeCmd` `c` 에 대해 PE_CPU 의 기록된
|
||||||
|
dispatch overhead 가 `FIXED_PER_CMD + c.logical_bytes × R`
|
||||||
|
(floor/round-off 의 ±1 cycle 내). 여러 composite parametrize:
|
||||||
|
1-OpSpec GEMM composite, 5-op MATH chain, 10-op recipe composite.
|
||||||
|
Default-calibration 숫자 (1-OpSpec composite 의 anchor ≈43 ns) 는
|
||||||
|
*informative* 참고, 테스트 gate 가 아님 — gate 는 공식 등가.
|
||||||
|
2. **정성적 ratio (robust).** opt3 per-tile PE_CPU dispatch 가 opt2
|
||||||
|
per-tile dispatch 를 최소 2× 차이로 엄격히 초과 — `opt3 > 2 × opt2`.
|
||||||
|
Default-calibration 모델은 ≈4× 예측; gate 는 느슨한 2× 한계라
|
||||||
|
calibration 이동 (예: HW reference 가 default 대체) 시 깨지지 않음.
|
||||||
|
Informative 숫자 — ADR-0065 §verification 와 DDD-0065 §11 의 모델
|
||||||
|
기대치 참조.
|
||||||
3. **Override 경로.** topology yaml 의 `pe_cost_model:` block 이 per-PE
|
3. **Override 경로.** topology yaml 의 `pe_cost_model:` block 이 per-PE
|
||||||
dispatch cost 변경; block 누락 시 default 복귀.
|
dispatch cost 변경; block 누락 시 default 복귀. #1 의 공식 등가가
|
||||||
|
override 값에서도 성립.
|
||||||
4. **`PeCpuOverheadCmd` 우회.** 수동 `tl.cycles(n)` 는 정확히 `n` cycles,
|
4. **`PeCpuOverheadCmd` 우회.** 수동 `tl.cycles(n)` 는 정확히 `n` cycles,
|
||||||
`n + dispatch_cycles(...)` 아님.
|
`n + dispatch_cycles(...)` 아님.
|
||||||
5. **double-count 없음.** PE_DMA `drain_ns`, PE_GEMM/MATH `_compute_ns` 가
|
5. **double-count 없음.** PE_DMA `drain_ns`, PE_GEMM/MATH `_compute_ns` 가
|
||||||
@@ -322,12 +351,12 @@ fold. calibration 이 분리 필요성을 보이면 PE_DMA fixed setup 으로
|
|||||||
dispatch-cycle 회계.
|
dispatch-cycle 회계.
|
||||||
8. **Composite 크기 cap (D7).** `logical_bytes >
|
8. **Composite 크기 cap (D7).** `logical_bytes >
|
||||||
MAX_COMPOSITE_LOGICAL_BYTES` 가 될 recipe 가 N 개 연속 `CompositeCmd`
|
MAX_COMPOSITE_LOGICAL_BYTES` 가 될 recipe 가 N 개 연속 `CompositeCmd`
|
||||||
로 segment; 총 dispatch = segment dispatch 의 합; segment 간 RW 순서
|
로 segment; `sum(segment.logical_bytes) == original logical_bytes`;
|
||||||
strict FIFO 로 보존.
|
총 dispatch = segment dispatch 의 합 (FIXED 가 segment 당 지불);
|
||||||
9. **민감도 sweep.** `R ∈ {0.25, 0.0625, 0.03125}` cycles/byte
|
inter-segment 순서 strict FIFO 로 보존 (`rw_handles` 단독 아님).
|
||||||
(= 4 / 16 / 32 bytes/cycle) 에서 *opt2 per-tile dispatch
|
9. **민감도 (정성적).** `R ∈ {0.25, 0.0625, 0.03125}` cycles/byte 에서
|
||||||
< opt3 per-tile dispatch* 결론 유지 (ratio 가 R 감소 시 단조 증가
|
3 지점 모두 `opt3 > opt2`. 방향 (R 감소 시 ratio 단조 증가) 도 단언,
|
||||||
— FIXED 가 더 지배).
|
단 절대 ratio 값은 *불필요*.
|
||||||
|
|
||||||
## Migration
|
## Migration
|
||||||
|
|
||||||
|
|||||||
@@ -251,15 +251,34 @@ per D4). Oversized commands are deterministically **segmented** by the
|
|||||||
- The segmentation algorithm is deterministic (greedy by op index in
|
- The segmentation algorithm is deterministic (greedy by op index in
|
||||||
emit order); it is part of the host emitter, not PE_SCHEDULER.
|
emit order); it is part of the host emitter, not PE_SCHEDULER.
|
||||||
|
|
||||||
Why this is needed. Real hardware imposes hard limits — descriptor
|
**Why a cap is needed.** Real hardware imposes hard limits — descriptor
|
||||||
queue entry size, scheduler parser buffer, command SRAM, firmware
|
queue entry size, scheduler parser buffer, command SRAM, firmware
|
||||||
input. Without a cap, the `FIXED + bytes × R` model would reward
|
input. Without a cap, the `FIXED + bytes × R` model would reward
|
||||||
arbitrarily large fused composites beyond what hardware accepts (e.g.,
|
arbitrarily large fused composites beyond what hardware accepts (e.g.,
|
||||||
fusing 100 primitive ops into one composite, paying one `FIXED`).
|
fusing 100 primitive ops into one composite, paying one `FIXED`).
|
||||||
A composite of (say) 100 ops at ~30 bytes each = ~3000 bytes >
|
|
||||||
1024 cap → segmented into 3 ≈ 3 × FIXED, restoring honest accounting.
|
|
||||||
|
|
||||||
Decode opt2's `#2` composite (10 ops, ~310 bytes) sits comfortably
|
**Why 1024 bytes specifically.** This is a **safe engineering limit**,
|
||||||
|
not a measured HW number — intentionally chosen to be well above all
|
||||||
|
currently known composites (decode opt2's `#2` at ~322 bytes is the
|
||||||
|
largest in the kernbench codebase) while still representing a *finite*
|
||||||
|
descriptor capacity that future recipes must respect. The number is
|
||||||
|
overridable per topology (D4); when a real HW reference appears, the
|
||||||
|
value should be recalibrated. The role of this default is to make the
|
||||||
|
cap *exist as a discipline*, not to fit a specific HW.
|
||||||
|
|
||||||
|
**Ordering of segments — driven by strict FIFO, not `rw_handles`.**
|
||||||
|
Segments are emitted into the PE_CPU → PE_SCHEDULER queue in their
|
||||||
|
emit order. Strict-FIFO dispatch (ADR-0065 D6.3) is the *ordering
|
||||||
|
source*: segments execute in the order they enter the queue. The
|
||||||
|
`rw_handles` block on each segment is **dependency metadata** for the
|
||||||
|
cross-composite hazard tracker — it does **not** by itself guarantee
|
||||||
|
inter-segment ordering. If a future scheduler relaxed FIFO (e.g., to
|
||||||
|
RW-aware reorder, ADR-0065 A4), the segmenter would need to either
|
||||||
|
(a) merge segments into a single CompositeCmd, or (b) introduce an
|
||||||
|
explicit completion-handle dependency chain. For Phase 1 this does
|
||||||
|
not arise: strict FIFO is in effect.
|
||||||
|
|
||||||
|
Decode opt2's `#2` composite (10 ops, ~322 bytes) sits comfortably
|
||||||
inside the 1024 cap — no segmentation for the GQA workload.
|
inside the 1024 cap — no segmentation for the GQA workload.
|
||||||
|
|
||||||
## Alternatives
|
## Alternatives
|
||||||
@@ -331,13 +350,27 @@ calibration shows it matters.
|
|||||||
|
|
||||||
## Test Requirements
|
## Test Requirements
|
||||||
|
|
||||||
1. **Anchor preservation.** A single-OpSpec composite for a DMA-staged
|
Tests are written against the **formula** (D1), not against specific
|
||||||
GEMM path (`logical_bytes ≈ 54`) dispatches in ≈43 ns at default
|
numeric anchors, so they remain valid when calibration changes or when
|
||||||
values (within ±2 ns).
|
OpSpec/CompositeCmd fields are added.
|
||||||
2. **Structural ratio.** opt3 vs opt2 dispatch (per ADR-0065 §verification):
|
|
||||||
`opt3 / opt2 ≈ 4.0×` at default calibration.
|
1. **Formula preservation.** For any `CompositeCmd` `c`, PE_CPU's
|
||||||
|
recorded dispatch overhead equals `FIXED_PER_CMD + c.logical_bytes
|
||||||
|
× R` (within ±1 cycle for floor/round-off). Parametrized over
|
||||||
|
several composites: a 1-OpSpec GEMM composite, a 5-op MATH chain,
|
||||||
|
and a 10-op recipe composite. Default-calibration numbers (anchor
|
||||||
|
≈43 ns for the 1-OpSpec composite) are informative reference, not
|
||||||
|
the test gate — the test gate is the formula equality.
|
||||||
|
2. **Qualitative ratio (robust).** opt3 per-tile PE_CPU dispatch
|
||||||
|
strictly exceeds opt2 per-tile dispatch by at least a 2× margin —
|
||||||
|
`opt3 > 2 × opt2`. The default-calibration model predicts ≈4×;
|
||||||
|
the gate is the loose 2× bound so the test does not break when
|
||||||
|
calibration is moved (e.g., when a HW reference replaces the
|
||||||
|
default). Informative numbers — see ADR-0065 §verification and
|
||||||
|
DDD-0065 §11 for the model expectation.
|
||||||
3. **Override path.** Topology yaml `pe_cost_model:` block changes the
|
3. **Override path.** Topology yaml `pe_cost_model:` block changes the
|
||||||
per-PE dispatch cost; default is recovered when block is missing.
|
per-PE dispatch cost; default is recovered when block is missing.
|
||||||
|
The formula identity from #1 must hold with the override values.
|
||||||
4. **`PeCpuOverheadCmd` bypass.** Manual `tl.cycles(n)` issues exactly `n`
|
4. **`PeCpuOverheadCmd` bypass.** Manual `tl.cycles(n)` issues exactly `n`
|
||||||
cycles, not `n + dispatch_cycles(...)`.
|
cycles, not `n + dispatch_cycles(...)`.
|
||||||
5. **No double-count.** PE_DMA `drain_ns`, PE_GEMM/MATH `_compute_ns`
|
5. **No double-count.** PE_DMA `drain_ns`, PE_GEMM/MATH `_compute_ns`
|
||||||
@@ -348,12 +381,14 @@ calibration shows it matters.
|
|||||||
dispatch-cycle accounting for the same kernel.
|
dispatch-cycle accounting for the same kernel.
|
||||||
8. **Composite size cap (D7).** A recipe that would emit `logical_bytes
|
8. **Composite size cap (D7).** A recipe that would emit `logical_bytes
|
||||||
> MAX_COMPOSITE_LOGICAL_BYTES` is segmented into N consecutive
|
> MAX_COMPOSITE_LOGICAL_BYTES` is segmented into N consecutive
|
||||||
`CompositeCmd`s; total dispatch = sum of segment dispatches; RW
|
`CompositeCmd`s; `sum(segment.logical_bytes) == original
|
||||||
ordering across segments preserved by strict FIFO.
|
logical_bytes`; total dispatch = sum of segment dispatches (FIXED
|
||||||
9. **Sensitivity sweep.** At `R ∈ {0.25, 0.0625, 0.03125}` cycles/byte
|
paid per segment); inter-segment ordering preserved by strict FIFO
|
||||||
(= 4 / 16 / 32 bytes/cycle), the conclusion *opt2 per-tile dispatch
|
(not by `rw_handles` alone).
|
||||||
< opt3 per-tile dispatch* must hold (ratio monotonically increases
|
9. **Sensitivity (qualitative).** At `R ∈ {0.25, 0.0625, 0.03125}`
|
||||||
as R decreases — FIXED dominates more).
|
cycles/byte, `opt3 > opt2` at *all* three points. Direction (ratio
|
||||||
|
monotonically increases as R decreases) is also asserted, but
|
||||||
|
absolute ratio values are *not* required.
|
||||||
|
|
||||||
## Migration
|
## Migration
|
||||||
|
|
||||||
|
|||||||
@@ -179,7 +179,10 @@ op="gemm", ...)` 에서:
|
|||||||
3. primary output P 의 shape 을 `s.shape` 에서 derive (identity).
|
3. primary output P 의 shape 을 `s.shape` 에서 derive (identity).
|
||||||
4. `engine_seq` 를 8 개의 평평한 MATH OpSpec 으로 펼침 (모든 주소/크기 채움).
|
4. `engine_seq` 를 8 개의 평평한 MATH OpSpec 으로 펼침 (모든 주소/크기 채움).
|
||||||
각 OpSpec 의 `scope = KERNEL`.
|
각 OpSpec 의 `scope = KERNEL`.
|
||||||
5. head GEMM 의 `operands["a"] = P_handle` auto-bind.
|
5. **Auto-bind (충돌 검사, D6.6).** head GEMM 이 `operands["a"]` 를
|
||||||
|
*명시하지 않은* 경우에만 `operands["a"] = P_handle` auto-bind.
|
||||||
|
커널이 `a` 를 명시적으로 제공했다면 validation error — 모호한
|
||||||
|
primary-output 대체.
|
||||||
6. `CompositeCmd(ops=(8 MATH + 1 GEMM + epilogue), rw_handles=(m, l, O))` emit.
|
6. `CompositeCmd(ops=(8 MATH + 1 GEMM + epilogue), rw_handles=(m, l, O))` emit.
|
||||||
|
|
||||||
**RECIPE_DESCRIPTORS 는 HW 경로 어디에도 안 나타남**. PE_SCHEDULER 는
|
**RECIPE_DESCRIPTORS 는 HW 경로 어디에도 안 나타남**. PE_SCHEDULER 는
|
||||||
@@ -331,9 +334,12 @@ scratch 에서 읽는 형태 — 순환 tile-loop 의존성. **기각 (incorrect
|
|||||||
emit 안 함.
|
emit 안 함.
|
||||||
6. **opt2 가 opt3 와 수치 동등.** data mode 에서 opt2 의 최종
|
6. **opt2 가 opt3 와 수치 동등.** data mode 에서 opt2 의 최종
|
||||||
`(m, l, O)` 가 opt3 와 fp tolerance 안.
|
`(m, l, O)` 가 opt3 와 fp tolerance 안.
|
||||||
7. **opt2 dispatch ratio (ADR-0064 Rev2 이후).** opt3 vs opt2 per-tile
|
7. **opt2 dispatch ratio (ADR-0064 Rev2 이후) — robust.** opt3 vs opt2
|
||||||
PE_CPU dispatch cycles ratio 가 default calibration (FIXED=40 cycles,
|
per-tile PE_CPU dispatch cycles 가 `opt3 > 2 × opt2` 만족
|
||||||
R=0.0625 cycles/byte) 에서 ≈ 4.0×. Ratio 가 FIXED-dominated —
|
(정성적 gate, calibration-독립). Default-calibration 모델 기대치는
|
||||||
|
≈ 4.0× (FIXED=40 cycles, R=0.0625 cycles/byte) — DDD-0065 §11 의
|
||||||
|
모델-유도 숫자 참조; 테스트 gate 는 느슨한 `> 2×` 한계라
|
||||||
|
calibration 변경에도 살아남음. Ratio 가 FIXED-dominated —
|
||||||
command-count 감소가 1차 신호임을 반영.
|
command-count 감소가 1차 신호임을 반영.
|
||||||
8. **GEMM-count invariant.** GEMM OpSpec 두 개 가진 composite 가
|
8. **GEMM-count invariant.** GEMM OpSpec 두 개 가진 composite 가
|
||||||
TLContext emit 시 validation error.
|
TLContext emit 시 validation error.
|
||||||
|
|||||||
@@ -200,7 +200,11 @@ op="gemm", ...)`:
|
|||||||
3. Derives the primary output P's shape from `s.shape` (identity).
|
3. Derives the primary output P's shape from `s.shape` (identity).
|
||||||
4. Expands `engine_seq` into 8 flat MATH OpSpecs with all addresses /
|
4. Expands `engine_seq` into 8 flat MATH OpSpecs with all addresses /
|
||||||
sizes filled. Each OpSpec gets `scope=KERNEL`.
|
sizes filled. Each OpSpec gets `scope=KERNEL`.
|
||||||
5. Auto-binds head GEMM's `operands["a"] = P_handle`.
|
5. **Auto-binds (with conflict check, D6.6).** If the head GEMM does
|
||||||
|
*not* explicitly provide `operands["a"]`, auto-bind
|
||||||
|
`operands["a"] = P_handle`. If the kernel *did* provide `a`
|
||||||
|
explicitly, emit a validation error — ambiguous primary-output
|
||||||
|
replacement.
|
||||||
6. Emits `CompositeCmd(ops=(8 MATH + 1 GEMM + epilogue), rw_handles=
|
6. Emits `CompositeCmd(ops=(8 MATH + 1 GEMM + epilogue), rw_handles=
|
||||||
(m, l, O))`.
|
(m, l, O))`.
|
||||||
|
|
||||||
@@ -370,10 +374,14 @@ input from #1's epilogue scratch — circular tile-loop dependency.
|
|||||||
`space=hbm` emits DMA_WRITE; `space=tcm` does not.
|
`space=hbm` emits DMA_WRITE; `space=tcm` does not.
|
||||||
6. **opt2 numeric parity with opt3.** In data mode, opt2's final
|
6. **opt2 numeric parity with opt3.** In data mode, opt2's final
|
||||||
`(m, l, O)` matches opt3's within fp tolerance.
|
`(m, l, O)` matches opt3's within fp tolerance.
|
||||||
7. **opt2 dispatch ratio (after ADR-0064 Rev2).** opt3 vs opt2 per-tile
|
7. **opt2 dispatch ratio (after ADR-0064 Rev2) — robust.** opt3 vs
|
||||||
PE_CPU dispatch cycles ratio ≈ 4.0× at default calibration
|
opt2 per-tile PE_CPU dispatch cycles satisfies `opt3 > 2 × opt2`
|
||||||
(FIXED=40 cycles, R=0.0625 cycles/byte). Ratio is FIXED-dominated,
|
(qualitative gate; calibration-independent). The default-calibration
|
||||||
reflecting command-count reduction as the primary signal.
|
model expectation is ≈ 4.0× (FIXED=40 cycles, R=0.0625 cycles/byte)
|
||||||
|
— see DDD-0065 §11 for the model-derived numbers; only the loose
|
||||||
|
`> 2×` bound is the test gate so it survives calibration changes.
|
||||||
|
Ratio is FIXED-dominated, reflecting command-count reduction as the
|
||||||
|
primary signal.
|
||||||
8. **GEMM-count invariant.** A composite with two GEMM OpSpecs raises a
|
8. **GEMM-count invariant.** A composite with two GEMM OpSpecs raises a
|
||||||
validation error at TLContext emit.
|
validation error at TLContext emit.
|
||||||
9. **Within composite size cap (ADR-0064 D7).** Decode opt2's `#2`
|
9. **Within composite size cap (ADR-0064 D7).** Decode opt2's `#2`
|
||||||
|
|||||||
@@ -26,9 +26,11 @@ unchanged.
|
|||||||
3. **Boundary preservation.** PE_SCHEDULER imports nothing recipe-related;
|
3. **Boundary preservation.** PE_SCHEDULER imports nothing recipe-related;
|
||||||
PE_MATH/PE_GEMM/PE_DMA see only `Stage.params["op_kind"]` (no new
|
PE_MATH/PE_GEMM/PE_DMA see only `Stage.params["op_kind"]` (no new
|
||||||
engine code).
|
engine code).
|
||||||
4. **Dispatch ratio.** Per-tile PE_CPU dispatch cycles
|
4. **Dispatch ratio (robust).** Per-tile PE_CPU dispatch cycles satisfy
|
||||||
`ratio(opt3 / opt2) ≈ 4.0×` at default ADR-0064 Rev2 calibration
|
`opt3 > 2 × opt2` (qualitative invariant, calibration-independent).
|
||||||
(FIXED=40 cycles, R=0.0625 cycles/byte).
|
Default ADR-0064 Rev2 calibration (FIXED=40 cycles, R=0.0625
|
||||||
|
cycles/byte) gives model-expected ≈ 4.0× — informative only, not the
|
||||||
|
test gate.
|
||||||
5. **K-before-V invariant.** op_log of decode opt2 shows zero V-related
|
5. **K-before-V invariant.** op_log of decode opt2 shows zero V-related
|
||||||
DMA during #2's MATH prologue.
|
DMA during #2's MATH prologue.
|
||||||
|
|
||||||
@@ -437,7 +439,7 @@ Each phase is an independent Phase-1 → Phase-2 cycle per CLAUDE.md Part 1.
|
|||||||
| **P3** | PE_SCHEDULER `_generate_plan` flat-ops + `PipelinePlan.prologue_stages` + DMA auto-insertion + `_feed_loop` extension | all existing bench Stage sequences unchanged; new MATH chain visible in op_log for opt2 mock |
|
| **P3** | PE_SCHEDULER `_generate_plan` flat-ops + `PipelinePlan.prologue_stages` + DMA auto-insertion + `_feed_loop` extension | all existing bench Stage sequences unchanged; new MATH chain visible in op_log for opt2 mock |
|
||||||
| **P4** | Strict-FIFO RW hazard tracker + `_RwHazardTracker` integration | two-composite RW conflict test serializes correctly |
|
| **P4** | Strict-FIFO RW hazard tracker + `_RwHazardTracker` integration | two-composite RW conflict test serializes correctly |
|
||||||
| **P5** | `_gqa_decode_long.py` opt2 variant; data-mode numeric parity check; K-before-V invariant check | opt2 matches opt3 within fp tolerance; no V DMA during prologue |
|
| **P5** | `_gqa_decode_long.py` opt2 variant; data-mode numeric parity check; K-before-V invariant check | opt2 matches opt3 within fp tolerance; no V DMA during prologue |
|
||||||
| **P6** | Dispatch-ratio measurement: opt3 vs opt2 per-tile PE_CPU cycles + R sensitivity sweep | ratio ≈ 4.0× ± 15% at default calibration; opt2 < opt3 at all `R ∈ {0.25, 0.0625, 0.03125}` (ADR-0064 Test #9) |
|
| **P6** | Dispatch-ratio measurement: opt3 vs opt2 per-tile PE_CPU cycles + R sensitivity sweep | `opt3 > 2 × opt2` at default calibration (gate); model-expected ≈ 4.0× (informative); `opt2 < opt3` at all `R ∈ {0.25, 0.0625, 0.03125}` (ADR-0064 Test #9) |
|
||||||
|
|
||||||
P0 must land first (separate ADR). P1 is pure refactor (safest). P2–P4
|
P0 must land first (separate ADR). P1 is pure refactor (safest). P2–P4
|
||||||
build the new path without touching opt3. P5 enables opt2. P6 closes
|
build the new path without touching opt3. P5 enables opt2. P6 closes
|
||||||
@@ -488,7 +490,10 @@ Mirrors ADR-0065 §Test Requirements; grounded in SPEC R2/R5, ADR-0023/
|
|||||||
**Dispatch ratio (P6):**
|
**Dispatch ratio (P6):**
|
||||||
- For `S_kv=64, n_tiles=16`, measure total PE_CPU dispatch cycles for
|
- For `S_kv=64, n_tiles=16`, measure total PE_CPU dispatch cycles for
|
||||||
opt3 vs opt2 paths.
|
opt3 vs opt2 paths.
|
||||||
- Assert ratio in `[3.4, 4.6]` (centre 4.0× at ADR-0064 Rev2 defaults).
|
- Assert `opt3 > 2 × opt2` (robust gate — calibration-independent).
|
||||||
|
- Record observed ratio; the default-calibration model expects ≈ 4.0×
|
||||||
|
(DDD §11). The recorded number is informative for performance
|
||||||
|
tracking, not a test gate.
|
||||||
- **Sensitivity sweep.** Repeat with `R ∈ {0.25, 0.0625, 0.03125}`
|
- **Sensitivity sweep.** Repeat with `R ∈ {0.25, 0.0625, 0.03125}`
|
||||||
cycles/byte; assert opt2 < opt3 in all three. (ADR-0064 Test #9.)
|
cycles/byte; assert opt2 < opt3 in all three. (ADR-0064 Test #9.)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user