ADR: introduce docs/history/, merge 0011+0018, prune migration cruft
- CLAUDE.md: add ADR Lifecycle subsection (superseded → docs/history/, immutable numbering, no renumber) - ADR-0011: merge ADR-0018 content as "Address Model: LA" section alongside PA / VA; status notes VA model is currently implemented - ADR-0018 / 0029 / 0031: moved to docs/history/ with status updates (0018 merged into 0011, 0029 superseded by 0032, 0031 absorbed into 0001 rev 2) - ADR-0019: rewrite Context as PE-HBM connectivity decision (self-contained, no LA model framing) - ADR-0019/0020/0021/0023/0025/0027: Status Proposed → Accepted (code verified) and prune Implementation Notes / Affected files / Test strategy / "현재 상태" sub-sections describing pre-impl state - ADR-0024/0026: same migration-flavor cleanup; 0026 also drops D6 Migration and D8 docs-update sub-decisions - ADR-0030: status simplified (blocker ADR-0031 now superseded) - SPEC.md: R10 + §0.2 reflect PA / VA / LA model names - ADR-0008/0012/0013: refresh ADR-0011 subtitle in Links 21 files changed, 553 insertions(+), 1290 deletions(-). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,35 +2,23 @@
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
ADR-0018에서는 LA 기반 주소 추상화와 BAAW를 도입하여,
|
||||
logical memory access가 다음 두 형태의 request로 변환되도록 정의하였다.
|
||||
CUBE 내부 NOC은 각 PE를 HBM에 연결해야 한다. KernBench는 두 가지
|
||||
connectivity 모델을 비교 평가할 수 있어야 한다.
|
||||
|
||||
- 1:1 mode: 하나의 logical access → N개의 per-channel request
|
||||
- n:1 mode: 하나의 logical access → 하나의 aggregated request
|
||||
- **1:1 mode** — PE_DMA가 N개 per-channel router 각각에 별도 link로
|
||||
연결되고, 각 router는 hbm_ctrl에 자기 channel link를 가진다.
|
||||
Per-channel BW contention을 정확히 모델링.
|
||||
N = `hbm_pseudo_channels / pes_per_cube` (= `channels_per_pe`).
|
||||
- **n:1 mode** — PE_DMA가 단일 aggregated router를 거쳐 하나의 link로
|
||||
hbm_ctrl에 연결. Channel들이 interleaved 된 것으로 가정하고
|
||||
aggregate BW만 모델링.
|
||||
|
||||
여기서 N = `hbm_pseudo_channels / pes_per_cube` (= `channels_per_pe`)이며,
|
||||
topology 파라미터로 결정된다.
|
||||
|
||||
### 기존 구조의 문제
|
||||
|
||||
현재 구현(`topology/builder.py`)에서는:
|
||||
|
||||
- PE_DMA → NOC → xbar_top/xbar_bot → HBM_CTRL.slice{0-7} 경로를 사용
|
||||
- HBM은 8개 slice(= PE 수) 노드로 모델링됨
|
||||
- local/remote access가 서로 다른 경로를 사용:
|
||||
- local: NOC → xbar → HBM slice
|
||||
- cross-half: NOC → xbar_top → bridge → xbar_bot → HBM slice
|
||||
- remote cube: NOC → UCIe → remote NOC → remote xbar → remote HBM slice
|
||||
|
||||
이 구조의 한계:
|
||||
|
||||
- pseudo-channel 단위 모델링 불가 (slice = PE 단위, channel 단위 아님)
|
||||
- xbar/bridge가 local/remote 경로를 이원화
|
||||
- 1:1 / n:1 mode를 일관되게 표현할 수 없음
|
||||
두 모드에서 PE당 effective BW는 동일 (= N × per-channel BW);
|
||||
connectivity granularity만 다르다.
|
||||
|
||||
---
|
||||
|
||||
@@ -270,7 +258,6 @@ links:
|
||||
### Negative
|
||||
|
||||
- 명시적 라우터 노드로 인해 SimPy 노드 수가 증가한다 (6×6 = 최대 32개 라우터/cube)
|
||||
- 기존 xbar/bridge/단일 NOC 기반 테스트 전면 재작성 필요
|
||||
- TwoDMeshNocComponent의 내부 contention 모델을 라우터별 모델로 교체 필요
|
||||
|
||||
---
|
||||
@@ -296,119 +283,6 @@ links:
|
||||
|
||||
---
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### topology/builder.py 변경 상세
|
||||
|
||||
#### 제거할 코드 (현재 `_instantiate_cube()` 내)
|
||||
|
||||
- xbar_top, xbar_bot 노드 생성 (~line 495-508)
|
||||
- bridge.left, bridge.right 노드 생성
|
||||
- noc ↔ xbar edge 생성 (~line 540-555)
|
||||
- xbar ↔ hbm_ctrl.slice edge 생성 (~line 510-538)
|
||||
- xbar ↔ bridge edge 생성 (~line 557-572)
|
||||
|
||||
#### 추가할 코드
|
||||
|
||||
1:1 mode:
|
||||
|
||||
```python
|
||||
N = hbm_channels_per_pe # from topology config
|
||||
total_ch = hbm_pseudo_channels
|
||||
|
||||
# channel router 노드 생성
|
||||
for ch_id in range(total_ch):
|
||||
pe_id = ch_id // N
|
||||
nodes[f"{cp}.ch_r{ch_id}"] = Node(
|
||||
id=f"{cp}.ch_r{ch_id}", kind="noc_router", impl="noc_v1",
|
||||
attrs={}, pos_mm=(...), # horizontal row = ch_id % N
|
||||
)
|
||||
|
||||
# PE_DMA ↔ local channel router edges
|
||||
for pe_id in range(pes_per_cube):
|
||||
for local_ch in range(N):
|
||||
ch_id = pe_id * N + local_ch
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.pe{pe_id}.pe_dma", dst=f"{cp}.ch_r{ch_id}",
|
||||
bw_gbs=channel_bw, kind="pe_to_ch_router", ...))
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.ch_r{ch_id}", dst=f"{cp}.pe{pe_id}.pe_dma",
|
||||
bw_gbs=channel_bw, kind="ch_router_to_pe", ...))
|
||||
|
||||
# channel router ↔ hbm_ctrl edges
|
||||
for ch_id in range(total_ch):
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.ch_r{ch_id}", dst=f"{cp}.hbm_ctrl",
|
||||
bw_gbs=channel_bw, kind="ch_router_to_hbm", ...))
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.hbm_ctrl", dst=f"{cp}.ch_r{ch_id}",
|
||||
bw_gbs=channel_bw, kind="hbm_to_ch_router", ...))
|
||||
|
||||
# horizontal line edges (same logical index)
|
||||
for row in range(N):
|
||||
for p in range(pes_per_cube - 1):
|
||||
ch_a = p * N + row
|
||||
ch_b = (p + 1) * N + row
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.ch_r{ch_a}", dst=f"{cp}.ch_r{ch_b}",
|
||||
bw_gbs=ch_horizontal_bw, kind="ch_horizontal", ...))
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.ch_r{ch_b}", dst=f"{cp}.ch_r{ch_a}",
|
||||
bw_gbs=ch_horizontal_bw, kind="ch_horizontal", ...))
|
||||
```
|
||||
|
||||
n:1 mode:
|
||||
|
||||
```python
|
||||
# aggregated router 노드 생성
|
||||
for pe_id in range(pes_per_cube):
|
||||
nodes[f"{cp}.pe{pe_id}.agg_router"] = Node(
|
||||
id=f"{cp}.pe{pe_id}.agg_router", kind="noc_router", impl="noc_v1",
|
||||
attrs={}, pos_mm=(...),
|
||||
)
|
||||
|
||||
agg_bw = N * channel_bw # aggregated BW
|
||||
|
||||
# PE_DMA ↔ aggregated router
|
||||
for pe_id in range(pes_per_cube):
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.pe{pe_id}.pe_dma", dst=f"{cp}.pe{pe_id}.agg_router",
|
||||
bw_gbs=agg_bw, kind="pe_to_agg_router", ...))
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.pe{pe_id}.agg_router", dst=f"{cp}.pe{pe_id}.pe_dma",
|
||||
bw_gbs=agg_bw, kind="agg_router_to_pe", ...))
|
||||
|
||||
# aggregated router ↔ hbm_ctrl
|
||||
for pe_id in range(pes_per_cube):
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.pe{pe_id}.agg_router", dst=f"{cp}.hbm_ctrl",
|
||||
bw_gbs=agg_bw, kind="agg_to_hbm", ...))
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.hbm_ctrl", dst=f"{cp}.pe{pe_id}.agg_router",
|
||||
bw_gbs=agg_bw, kind="hbm_to_agg", ...))
|
||||
|
||||
# aggregated router 간 horizontal link
|
||||
for p in range(pes_per_cube - 1):
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.pe{p}.agg_router", dst=f"{cp}.pe{p+1}.agg_router",
|
||||
bw_gbs=agg_horizontal_bw, kind="agg_horizontal", ...))
|
||||
edges.append(Edge(
|
||||
src=f"{cp}.pe{p+1}.agg_router", dst=f"{cp}.pe{p}.agg_router",
|
||||
bw_gbs=agg_horizontal_bw, kind="agg_horizontal", ...))
|
||||
```
|
||||
|
||||
### 영향받는 기존 테스트
|
||||
|
||||
| 테스트 파일 | 영향 |
|
||||
| ---------- | ---- |
|
||||
| `tests/test_topology_compile.py` | xbar/bridge 노드 참조 제거, channel router 검증 추가 |
|
||||
| `tests/test_topology_load.py` | topology.yaml 설정 변경 반영 |
|
||||
| `tests/test_pe_components.py` | PE_DMA 라우팅 경로 변경 |
|
||||
| `tests/test_sip_parallel.py` | cross-PE 접근 경로 변경 |
|
||||
| xbar/bridge를 직접 테스트하는 케이스 | 제거 |
|
||||
|
||||
---
|
||||
|
||||
## Test Requirements
|
||||
|
||||
- 1:1 mode에서 channel별 link로 request가 전달되는지 확인
|
||||
@@ -425,7 +299,7 @@ for p in range(pes_per_cube - 1):
|
||||
|
||||
## Links
|
||||
|
||||
- ADR-0018 (LA + BAAW) → addressing 측 연동
|
||||
- ADR-0011 (LA model) → addressing 측 연동
|
||||
- ADR-0017 (Cube NOC 2D Mesh) → 본 ADR이 xbar/bridge 부분을 대체
|
||||
- ADR-0004 (Memory Semantics) → BW 모델 재정의
|
||||
- ADR-0014 (PE Internal Execution Model) → PE_DMA 경로 변경 영향
|
||||
|
||||
Reference in New Issue
Block a user