Move the GEMM + allreduce sweep/render logic out of scripts/ and tests/
into two self-contained eval benches so a user can regenerate every
result + figure with one command:
kernbench run --bench milestone-1h-gemm (MILESTONE_FAST=1 reuses JSON)
kernbench run --bench milestone-1h-ccl
- benches/milestone_1h_{gemm,ccl}.py: single home for each domain; the
run(torch) entry drives the sweeps and writes figures into
benches/1H_milestone_output/{gemm,ccl}/ (gitignored), then submits a
sentinel tensor to satisfy the run_bench contract.
- tests/gemm + tests/sccl helpers and scripts/gemm_sweep.py become thin
re-export/wrapper shims over the benches (single source preserved); the
pytest-only param builders + _run_distributed wrapper stay in the shim.
- eval-bench pattern: a bench may drive many configs + build its own
per-config engines (extends ADR-0045 D5; reverses ADR-0044 D1/D2).
ADR-0054 (EN+KO) records the design; ADR-0043/0044/0045 + CLAUDE.md CLI
Semantics amended; ADR INDEX regenerated. Verified: milestone benches run
clean (ok=True, all artifacts), full suite 67 passed, lang-pairs OK.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.4 KiB
ADR-0044: GEMM 평가 하니스 — scripts/gemm_sweep.py + tests/gemm/
Status
Accepted
GEMM 평가/특성화 하니스를 문서화한다; 구현과 대조 검증 완료 (상수, tile 크기, figure 집합, script↔test 분할을 교차 확인). D5/D6 caveat은 부정확이 아니라 기록된 한계다.
ADR-0054로 개정됨: sweep + renderer가 milestone-1h-gemm bench(단일
home)로 이동했다; scripts/gemm_sweep.py와 tests/gemm/는 이제 거기서
re-export한다. D1/D2의 "데이터 생성은 수동 script / 무거운 작업은 opt-in"은
평가-bench 패턴으로 대체된다(하나의 bench가 전부 재생성;
MILESTONE_FAST=1은 committed JSON 재사용).
Context
ADR-0014(PE pipeline)와 ADR-0042(tile-plan generator)는 GEMM 구현을 정의하고, ADR-0033은 latency 모델을 정의한다. 그러나 어느 것도 GEMM 성능을 어떻게 스윕하고 특성화하는가 — 타이밍 데이터를 만드는 shape/variant 스윕과 이를 해석하는 figure — 는 기술하지 않는다. 본 ADR이 그 하니스를 고정한다.
allreduce 하니스(ADR-0043)와 달리 GEMM 스윕은 무겁다(24 sim 실행:
8 shape × 3 operand-staging variant; 512 shape 하나가 2048 tile). 이
무게가 아래 분할을 결정한다.
Decision
D1. 두 계층 분할 — 무거운 데이터 생성(script) vs. 빠른 figure(test)
- 데이터 생성은 수동 script로 유지:
scripts/gemm_sweep.py가matmul-composite(ADR-0042 plan)를 CLI와 동일한run_bench경로로 shape × variant에 걸쳐 실행하고,result.engine.op_log를 수확하여docs/diagrams/gemm_sweep.json(stage별/engine별 wall-clock + occupancy- record count + pe/composite window)을 쓴다.
- figure 렌더링은 test 생성:
tests/gemm/이 committedgemm_sweep.json을 읽어 matplotlib PNG를docs/diagrams/gemm_plots/에 렌더링한다. 이 테스트는 빠르고 기본 실행된다.
근거: 슬라이드덱 규모의 sim 스윕은 매 pytest 실행에 속하지 않지만,
figure(저렴·결정적)는 자유롭게 재생성되고 CI로 가드되어야 한다. 이는
CLAUDE.md의 script-vs-test 분할(무거운/수동 생성은 script; 빠른 assertion은
test)을 반영한다.
D2. Slow regenerator 테스트가 script를 감싼다
tests/gemm/test_gemm_sweep.py는 @pytest.mark.slow로 표시된다(기본
addopts: -m "not slow"에서 제외). 이는 scripts/gemm_sweep.py를
subprocess로 호출하여 gemm_sweep.json을 on-demand로 재생성한다
(pytest -m slow tests/gemm/test_gemm_sweep.py). 스윕 로직은 단일
home(script)을 가지며 테스트는 이를 감싸기만 하므로 sim 구동 코드의
중복이 없다.
D3. Figure 집합 (3개 차트, load_ref variant)
| 테스트 | PNG | 내용 |
|---|---|---|
test_plot_gemm_stage_breakdown.py |
gemm_stage_breakdown.png |
stage별 engine wall-clock (DMA in / Fetch / GEMM / DMA out) |
test_plot_gemm_mac_utilization.py |
gemm_mac_utilization_measured.png |
GEMM util % + useful eff % |
test_plot_gemm_mac_utilization.py |
gemm_mac_utilization_theoretical_vs_measured.png |
theoretical vs 시뮬레이터-measured util/eff |
tests/gemm/_gemm_plot_helpers.py가 공유 renderer를 보유한다(시리즈 로직은
scripts/build_overview_slides.py의 GEMM _render_* 함수를 미러링하며,
그쪽은 여전히 PPTX에 네이티브로 그린다). 수집되지 않음(test_ 접두사
없음). 각 test_plot_*는 gemm_sweep.json이 없으면 skip한다.
D4. Tile 크기는 데이터 기반; under-tile shape는 표시
Tile 크기는 gemm_sweep.json(tile_sizes)에서 읽으며, 이는 스윕이
PeSchedulerComponent.TILE_M/K/N = 32/64/32 — 권위 소스 — 에서 기록한
값이다. M<TILE_M ∨ K<TILE_K ∨ N<TILE_N인 shape는 차트에
("under-tile") 표시된다. 512³ shape는 figure에서 제외된다
(EXCLUDED_SHAPES).
D5. Theoretical 모델 — 상속된 상수, 아직 ADR-미검증
"theoretical" 곡선은 scripts/build_overview_slides.py에서 그대로 복사한
상수로 해석적 ideal-pipeline 모델을 사용한다:
HBM_GBS = 256.0 # GB/s T_STAGE = 16.0 ns
D_STAGES = 3 BPE = 2
이 값들은 아직 ADR과 대조 소싱되지 않았다. 특히 ADR-0033의 256은
burst_bytes(256 B)로 이 256 GB/s와 다른 양이며, ADR-0033은
대역폭을 pc_bw_gbs = hbm_to_router_bw_gbs / num_pcs로 도출한다.
T_STAGE/stage 수도 여기서 ADR-0014로 추적되지 않았다. 따라서 모델은
기존 deck script와 일관할 뿐 ADR과 검증되지 않았고, 상수가 중복된다
(deck + helper). 이를 조정(topology/ADR-0033/0014에서 소싱, 중복 제거)하는
것은 보류 — Open questions 참조.
D6. 알려진 네이밍 caveat — _measured 차트
gemm_mac_utilization_measured.png는 현재 theoretical ideal-pipeline
수치를 그린다(footnote가 그렇게 명시). 파일명만 "measured"라고 한다. 이는
그 내용을 시뮬레이터-measured 시리즈로 재지정할지 또는 제목을 바꿀지
결정을 보류 중인 알려진 misnomer다.
Consequences
Positive
- GEMM figure가 allreduce처럼 test 생성·CI 가드된다.
- 무거운 스윕은 opt-in으로 유지되어 기본 테스트 실행이 빠르다.
- 스윕 로직의 단일 소스(script)를 slow 테스트가 재사용.
Negative / limitations
- theoretical 모델 상수(D5)는 미검증·중복이다.
_measuredfigure는 misnomer(D6).build_overview_slides.py는 여전히 이 PNG를 임베드하지 않고gemm_sweep.json에서 GEMM 막대를 네이티브로 그린다 — test 아티팩트를 소비하도록 deck를 재배선하는 작업은 미완.
Dependencies
- ADR-0013: verification strategy.
- ADR-0014 / ADR-0042: PE pipeline + tile-plan generator — 스윕이 측정하는 GEMM 구현; D4의 stage record count는 ADR-0042 D2/D3에서 온다.
- ADR-0033: latency 모델 — D5 상수가 (아직은 아니지만) 추적되어야 할 소스.
- ADR-0043: 형제 격인 allreduce 평가 하니스.
Open questions
- D5 상수를
topology.yaml/ ADR-0033 / ADR-0014와 대조 조정하고 중복 제거할 것인가(모델 파라미터의 단일 소스)? - D6
_measured네이밍 해결(내용 재지정 vs. 제목 변경)? build_overview_slides.py를 네이티브 막대 그리기 대신gemm_plots/PNG 임베드로 재배선할 것인가?