Documents four cross-cutting surfaces that previously had no ADR backing, each surfaced as a G4 candidate by /report: - 0046 prog-tl-context-contract: the kernel-side tl.* API. Enumerates all primitives (ref/load/store/dot/composite/math/reduction/IPCQ/...), the two execution modes (command-list vs greenlet runner), scratch allocator semantics, dispatch-overhead model, and the kernel registry. - 0047 par-ahbm-ccl-backend: torch.distributed.init_process_group (backend="ahbm") install path. world_size priority (algorithm > defaults > topology), the 4-step init sequence (load ccl.yaml, import algorithm module, derive world_size, install SFR + IPCQ), greenlet- local rank registry, all_reduce dispatch via _defer_wait, barrier no-op rationale, and the explicit list of unsupported dist.* APIs. - 0048 mem-allocator-algorithms: VirtualAllocator + PEMemAllocator free-list semantics. Offset-keyed first-fit with coalescing, the no-validation trust model for free(), HBM/TCM channel separation, page-aligned VA allocation, the page_size dual-default (VirtualAllocator 2 MiB / _ensure_allocators 4 KiB fallback), and one-allocator-per-sub-unit rule. - 0049 ver-probe-subcommand: kernbench probe traffic-pattern catalog. H2D / D2H / PE DMA categories with their exact cube-index choices, the 32 KiB reference size, the 5-point utilization sweep, the formula vs actual column meanings, automatic invariant checks (monotonicity, D2H >= H2D, best < worst), per-case GraphEngine isolation, and the human-readable (not machine-parsable) output contract. Bilingual pair verifier passes for all four EN/KO pairs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
11 KiB
ADR-0049: kernbench probe Subcommand — Traffic-Pattern Verification Harness
Status
Accepted (2026-05-22).
probes/probe.py 의 run_probe(...) 가 노출하는 traffic-pattern catalog,
formula vs actual 비교, 그리고 monotonicity / D2H≥H2D 같은 invariant
체크의 의미를 명시한다. ADR-0010 (CLI surface) 가 kernbench probe
subcommand 를 enumerate 하나, probe 가 실제로 측정하는 것과 어떤
invariant 를 PASS/FAIL 로 판정하는가는 ADR-level 에 없었다.
First action (제일 처음에 하는 일)
run_probe(topology_path, case_filter=None) 의 첫 4가지 작업:
Path(topology_path).expanduser().resolve()로 절대 경로 산출.load_topology(path)→TopologyGraph인스턴스 (그래프 + spec)._build_edge_map(graph)→{(src, dst): Edge}빠른 lookup 테이블.AddressResolver(graph)+PathRouter(graph)인스턴스화.
그 다음 nbytes = 32768 (= 32 KiB, summary table 의 기준 데이터 크기) 와
show_all = (case_filter is None or case_filter == "all") 를 설정.
즉, probe 의 첫 일은 "토폴로지를 한 번 로드하여 edge map / resolver /
router 를 준비하고, 32 KiB 라는 표준 측정 크기를 픽스하는 것". 그 이후
H2D → D2H → PE DMA 세 카테고리의 case 들이 각각 별도의 GraphEngine
인스턴스에서 실행된다 (case 간 cross-talk 차단).
Context
kernbench probe 는 다음 의도로 도입된 verification 도구다:
- 수동 분석 ground truth: 실 시뮬레이션 (
kernbench run --bench ...) 결과의 latency 가 비정상으로 보일 때, 단순 traffic pattern 의 정답을 별도 로 얻어 비교. - formula vs actual 비교: 분석 모델 (wire latency + overhead + drain)
과 시뮬레이션 결과 (
total_ns) 가 일치하는지 확인. 일치하지 않으면 모델 단순화 가정 (ADR-0033) 어디가 빠진 것인지 단서. - monotonicity check: hop 수가 늘면 latency 가 단조 증가해야 한다는 invariant 의 자동 확인.
- utilization sweep: 데이터 크기 (4 KiB ~ 1 MiB) 별 BW 활용률 표.
이 도구의 동작 사양이 ADR-level 에 없으면:
- 다른 형식의 traffic pattern (예: MCpuDma, IPCQ) 을 추가하려는 사람이 기존 카테고리의 표 포맷 / 측정 단위를 일관되게 따르기 어렵다.
- monotonicity 가 무엇을 기준으로 검사되는지 (hop 수? cube 거리? wire 길이?) 모호.
- 32 KiB 라는 기준 크기와
[4 KiB, 16 KiB, 64 KiB, 256 KiB, 1 MiB]sweep 의 의미가 코드 grep 으로만 확인 가능.
Decision
D1. 세 가지 case category — H2D / D2H / PE DMA
각 category 는 토폴로지 상 별개의 데이터 경로를 가지며, 별도의 summary table + sweep table + route detail block 으로 출력된다.
- H2D (Host→Device Write):
MemoryWriteMsg(dst_sip=0, dst_cube, dst_pe=0, pattern="zero")가pcie_ep → io_cpu → m_cpu → hbm_ctrl경로 를 흐른다. cube 인덱스로 hop 수가 증가:- h2d-1hop: cube=0, hops=1
- h2d-2hop: cube=4, hops=2
- h2d-3hop: cube=8, hops=3
- h2d-4hop: cube=12, hops=4
- D2H (Device→Host Read):
MemoryReadMsg(src_sip=0, src_cube, src_pe=0). forward command path + reverse data path 의 합 latency. 같은 4 hops 카테고리. - PE DMA (PE-initiated):
PeDmaMsg(src_sip, src_cube, src_pe, dst_pa). 5 가지 케이스로 cube/PE 위치 변화:- pe-local-hbm: same cube, same PE
- pe-same-half-hbm: same cube, different PE (PE 1)
- pe-cross-half-hbm: same cube, far PE (PE 4)
- pe-cross-cube-hbm-best: adjacent cube (cube 1)
- pe-cross-cube-hbm-worst: diagonal far cube (cube 15)
cube 인덱스가 4/8/12 (H2D), 1/4/15 (PE DMA) 같이 의미 있는 이유는 4x4 cube mesh (sip.cube_mesh.w=4, h=4) 에서의 거리 정의 — 추후 cube_mesh 크기 변경 시 이 값들이 같이 갱신되어야 한다.
D2. 표준 측정 크기 — nbytes = 32768 (32 KiB)
모든 case 의 summary table 은 nbytes=32768 로 한 번 실행한 결과를
보여준다. 32 KiB 가 선택된 이유:
- DMA overhead 와 BW drain 이 한쪽으로 치우치지 않는 적당한 크기.
- 다수 sub-unit (TCM, register file) 의 1회 transfer 단위와 비교 가능.
크기별 utilization 변화는 별도 sweep table 이 보여준다 (D3).
D3. Utilization sweep — [4 KiB, 16 KiB, 64 KiB, 256 KiB, 1 MiB]
SWEEP_SIZES = [4096, 16384, 65536, 262144, 1048576], SWEEP_LABELS = ["4KB", "16KB", "64KB", "256KB", "1MB"]. 매 size 마다 다음 공식:
drain = nbytes / bottleneck_bw
total = overhead + wire + drain
eff_bw = nbytes / total
util% = eff_bw / bottleneck_bw × 100
bn_bw is None or <= 0 이면 그 컬럼은 0.0 % 로 출력. 의미: hop 수가 늘
수록 작은 transfer 는 overhead-bound, 큰 transfer 는 drain-bound 가 되는
패턴을 한 표에서 확인.
D4. 측정 항목 — actual / formula / breakdown
각 case 행에 표시되는 컬럼:
Actual(total_ns): SimPy 실행 결과의trace["total_ns"].Ovhd: 경로상 모든 node 의node.attrs["overhead_ns"]합 (formula breakdown).Drain:nbytes / min(edge.bw_gbs over path)(formula).Wire:Σ edge.distance_mm * (ns_per_mm from spec).Ovhd%/Drain%: Ovhd/Drain 이 Actual 에서 차지하는 비율 (formula 의 Wire 는 통상 매우 작아 표시하지 않음).Eff.BW:nbytes / total_ns(실 측정 BW).BN.BW: bottleneck bandwidth (formula). path 상 모든 edge 의 BW 중 최소. edge BW 가 없으면 "-".Util%:Eff.BW / BN.BW × 100. 100% 면 single-stream BW upper bound 에 도달.
formula 의 합 (wire + ovhd + drain) 과 actual 의 차이가 크면 모델
단순화가 잡지 못하는 요소가 있다는 신호 (ADR-0033 의 가정 점검).
D5. Invariant 자동 체크 — PASS/FAIL
다음 invariant 들이 자동으로 확인되어 [v] PASS / [x] FAIL 로 출력:
- H2D / D2H monotonic increase: hop 수가 늘면 actual latency 가
단조 증가해야 함.
all(lats[i] < lats[i+1] for ...). - D2H ≥ H2D: 같은 hop 인덱스에서 D2H ≥ H2D (D2H 는 forward command
- reverse data 두 leg 이므로).
all(d2h[i].total >= h2d[i].total).
- reverse data 두 leg 이므로).
- PE DMA best < worst: cross-cube best (adjacent) latency < cross-cube worst (diagonal) latency.
- PE DMA local vs remote: local BN BW vs remote BN BW 의 비교 출력 (PASS/FAIL 이 아닌 정보성).
체크가 FAIL 이면 사람이 즉시 모델/토폴로지 회귀를 인지할 수 있도록 한 줄로 분명하게 출력.
D6. Route detail — per-hop timestamp trace
summary 와 sweep 표 이후 각 case 의 path 와 per-hop 누적 시간 (
_hop_timestamps) 가 별도 섹션에서 출력된다:
- H2D: leg1 (
pcie_ep → io_cpu) + leg2 (io_cpu → m_cpu) + leg3 (m_cpu → hbm_ctrl) + per-hop trace. - D2H: forward (cmd, no data) + reverse (data) trace 분리 표시.
- PE DMA:
pe_dma → router → hbm_ctrlpath + per-hop trace.
각 hop 의 timestamp 는 cumulative wire_ns + overhead_ns 누적. terminal
hop 의 annotation 에 drain:Xns 가 붙는다. bottleneck edge 는
<BN:XXGB/s> 로 표시되어 시각적으로 식별 가능.
D7. case_filter 인자의 의미
None또는"all": 모든 case 실행 (default).- 다른 문자열: 그 이름과 정확히 일치하는 case 만 실행. 예:
kernbench probe --case h2d-2hop.
각 카테고리 안에서 name != case_filter 면 skip 되며, 그 카테고리의
monotonicity / D2H≥H2D 비교는 데이터가 1개일 때 자연히 skip 된다.
CLI parser 의 --case 기본값은 "all"이라 인자 생략 시 전체 실행.
D8. 매 case 별 fresh GraphEngine
H2D 4개, D2H 4개, PE DMA 5개의 case 가 각각 새로운 GraphEngine
인스턴스에서 실행된다 (engine = GraphEngine(graph)). 이유:
- case 간 누적 상태 (op_log, completion 추적, allocator 등) 가 cross-talk 하지 않도록 격리.
- 한 case 의 traffic 이 다른 case 의 BW 측정에 영향을 주지 않도록 보장.
이 격리는 probe 의 측정 결과를 각 case 단독 single-flow 의 latency 로
해석할 수 있게 한다. multi-flow contention 측정은 별도 도구 (예:
pe2pe_overview 플롯, ADR-0033 의 multi-flow merging 모델) 책임.
D9. 출력 포맷의 안정성
probe 의 stdout 출력은 사람이 읽기 위함이며, 정확한 컬럼 폭/구분자/공백 은 machine-readable contract 가 아니다. 자동화된 도구가 probe 결과를 파싱 하려면 별도 JSON 출력 모드를 추가해야 한다 (현재 미구현).
PASS/FAIL 줄의 [v] / [x] 접두사는 CI grep 용 anchor 로 안정 보장.
Alternatives Considered
A1. Probe 를 별도 bench 로 등록 (@bench(name="probe"))
기각. probe 는 bench 가 아니라 verification 도구로 의도된다 — sweep / 분석 용 multi-engine 실행과 invariant PASS/FAIL 출력이 본질이며, ADR-0045 의 "단일 디바이스 + 단일 RuntimeContext" bench 모델과 맞지 않는다.
A2. monotonicity 위반 시 exit code 1
기각 (현재). 인간 검사 도구 위주로 의도되어 있어 PASS/FAIL 줄을 출력하고
exit 0 로 종료. CI 가 violation 으로 fail 하길 원하면 별도 wrapper 가
grep "\[x\]" 결과로 판단하면 됨. 후속으로 strict-mode flag (--strict)
도입 가능.
A3. probe 의 case 정의를 외부 YAML 로
기각 (현재). 8개 case (4 H2D + 4 D2H + 5 PE DMA — 합 13개) 는 코드에 하드코딩되어 있고 의미가 토폴로지 mesh 구조에 단단히 묶여 있다. 외부 YAML 로 옮기면 cube 인덱스의 의미 (4, 8, 12 / 1, 4, 15) 를 별도로 문서화 해야 하므로 응집도 손실. 케이스 추가가 잦아지면 그때 별도 ADR 로 도입.
A4. multi-flow contention 측정 추가
기각 (probe 범위 밖). D8 에서 명시한 single-flow 격리 모델이 probe 의 핵심 의도. multi-flow contention 은 ADR-0033 latency model 의 다른 영역으로, 별도 도구 또는 별도 case category 로 처리.
Consequences
- probe 의 case catalog (D1) 와 측정 단위 (D2/D3) 가 ADR-level 에서 명시 되어, 새 traffic 카테고리 추가 시 어떤 표 포맷을 따라야 하는지 분명.
- formula vs actual 의 컬럼 의미 (D4) 가 굳어져, probe 결과를 보고 "왜 Drain% 가 5% 인가 / 70% 인가" 같은 질문을 빠르게 ADR-0033 가정 점검으로 연결 가능.
- invariant 자동 체크 (D5) 가 ADR 에 굳어져, 향후 latency 모델 변경 시 monotonicity / D2H≥H2D 회귀를 probe 가 즉시 잡아낸다는 안전망 정착.
- D8 의 case 간 격리가 명시되어, probe 결과를 single-flow 측정으로 안전 하게 해석 가능. multi-flow 측정이 필요해지면 별도 도구 트랙이 필요함이 분명.
- A2 의 strict-mode flag 가 후속 작업 후보로 기록되어, CI 통합 요구 시 최소 추가 작업으로 도입 가능.