ADR housekeeping: category prefixes, lifecycle folders, retroactive 0034-0037
Filename + lifecycle:
- ADR rename to ADR-NNNN-<cat>-title.md with 8 3-letter category prefixes
(dev / mem / lat / prog / algo / par / api / ver). Numbers stay immutable.
- ADR Lifecycle split into 3 folders, documented in CLAUDE.md Part 2:
docs/adr/ (Accepted), docs/adr-proposed/ (Proposed/Stub/Draft),
docs/adr-history/ (Superseded/Merged). Status field gains "Draft" for
retroactive docs pending verification.
Merges (one ADR per topic, no change-history annotations):
- ADR-0017 absorbs ADR-0019 (Cube NOC + per-PE HBM connectivity, 10 D-items)
- ADR-0014 absorbs ADR-0021 (PE pipeline execution model, 8 D-items incl.
TileToken self-routing and multi-op composite epilogue scope)
- ADR-0023 absorbs docs/ipcq-dma-codesign-hw.md as new "HW Realization
Notes (Informative)" section (D16-D23 + Open HW Questions). codesign-hw.md
deleted; ADR-0019/0021 moved to adr-history with one-line stub status
Retroactive documentation (G4 closures, code-verified):
- ADR-0037 forwarding component (TransitComponent: first-flit overhead,
serial worker, path-based routing, single impl/multiple names)
- ADR-0036 IO_CPU component (target_start_ns global barrier stamping,
per-cube fan-out, response aggregation)
- ADR-0035 M_CPU & M_CPU.DMA component (3 fan-out paths, DMA Resources,
target_start_ns passthrough)
- ADR-0034 HBM controller internal design (per-PC state, address-based
selection, flit-aware per-flit commit, async finalize, command-only
fallback path)
Content updates:
- ADR-0010 expanded to full CLI surface (run/probe/web), retitled
"Command Line Interface and Execution Semantics"
- ADR-0007 D2 rewritten to current state; ADR-0015 supersession notes pruned
- ADR-0005 wrapped in Decision header with D1-D5; ADR-0022 metadata
block replaced with standard Status header
- ADR-0024 trimmed to rank=SIP launcher essentials (D1-D4);
ADR-0027 cleaned of supersession history
- ADR-0033 D6 cleanup: address-based PC selection moved out of future-work
(now documented in ADR-0034 D3); related D1/D3 wording realigned
- Cross-references back-filled in 5 ADRs (G3 gaps closed)
Onboarding docs split:
- docs/onboarding/ created
- moved: hw-architecture-overview.md, latency-model.md, di-presentation.md,
ccl-author-guide{,.en}.md
- references updated in README, ADR-0023{,.en}, src/kernbench/ccl/__init__.py
Source / test / yaml: ADR-NNNN cross-references in docstrings and YAML
comments updated after the merges (ADR-0021->0014 D6, ADR-0019->0017 D8).
No behavior change.
Tooling:
- tools/verify_adr_lang_pairs.py + tests/test_verify_adr_lang_pairs.py
(ADR EN/KO pair invariant checker)
- .claude/commands/report.md tracked (/report slash command)
- .gitignore: allow .claude/commands/*.md while keeping settings files ignored
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
# ADR-0028: DTensor Support — 선언적 분산 텐서 (Stub / Future)
|
||||
|
||||
## Status
|
||||
|
||||
Stub (Future Work)
|
||||
|
||||
## Context
|
||||
|
||||
### 목표
|
||||
|
||||
**선언적 분산 텐서 추상화**(PyTorch 2.x `DTensor` 스타일)를 KernBench에
|
||||
도입하기 위한 **디자인 공간 preliminary exploration**. 본 ADR은 **구현 계획이
|
||||
아닌 future 작업의 파일 플레이스홀더 + 초기 질문 목록**이다.
|
||||
|
||||
### Megatron-style TP와의 차이 (Why DTensor)
|
||||
|
||||
| 관점 | Megatron (ADR-0027) | DTensor (이 ADR) |
|
||||
|---|---|---|
|
||||
| 표현 | 명시적 parallel layer | 텐서 + placement spec |
|
||||
| 호출 형태 | `ColumnParallelLinear(...)` | `distribute_tensor(x, mesh, [Shard(1)])` |
|
||||
| Collective 삽입 | 레이어 내부 명시 | 연산 dispatch가 자동 |
|
||||
| Learning curve | 낮음 (명시적) | 중~높음 (선언적 의미 이해) |
|
||||
| 유연성 | 레이어 단위로 고정 | 레이어 경계 무관, 어디서나 |
|
||||
| KernBench에 선행 필요한 것 | launcher (ADR-0024) + TP (0027) | 그 + operator dispatch overhaul |
|
||||
|
||||
DTensor는 operator-level에서 "텐서의 placement를 보고 자동으로 collective
|
||||
삽입". KernBench가 이를 지원하려면 **operator dispatch layer에 placement-aware
|
||||
rewriting**이 들어가야 한다. 이는 비-trivial.
|
||||
|
||||
### 현재 상태
|
||||
|
||||
- KernBench는 operator dispatch 레이어가 없음 (`torch.matmul`은 없음; kernel
|
||||
launch로 대체).
|
||||
- DPPolicy는 정적 placement metadata를 보유 (ADR-0026 후: intra-device only).
|
||||
- ADR-0024 launcher가 rank / device 개념 제공.
|
||||
- Megatron-style TP (ADR-0027)가 명시적 대안으로 기능할 것.
|
||||
|
||||
---
|
||||
|
||||
## Preliminary decision space
|
||||
|
||||
### DQ1. PyTorch DTensor API 수용 범위
|
||||
|
||||
- `DeviceMesh`: rank들의 논리적 grid.
|
||||
- `Placements`: `Shard(dim)`, `Replicate()`, `Partial(reduce_op)`.
|
||||
- `distribute_tensor(tensor, device_mesh, placements)`: local tensor → DTensor.
|
||||
- Redistribute: `dt.redistribute(new_placements)`로 collective 자동 삽입.
|
||||
- Operator forward: `dt @ dt`, `dt + dt` 등 → 적절한 collective 자동 dispatch.
|
||||
|
||||
KernBench가 어느 수준까지 지원할지 결정 필요. 최소: `distribute_tensor` +
|
||||
`redistribute`. 최대: 모든 operator overloading.
|
||||
|
||||
### DQ2. Operator dispatch 레이어
|
||||
|
||||
KernBench에서 `dt @ dt`를 정의하려면 Tensor의 `__matmul__`이 placement를
|
||||
보고 적절한 action 수행:
|
||||
|
||||
- 둘 다 replicated → local matmul
|
||||
- A column-sharded, B row-sharded → local matmul + all-reduce (RowParallel)
|
||||
- A replicated, B column-sharded → local matmul (ColumnParallel)
|
||||
- etc.
|
||||
|
||||
이는 Megatron-style의 **자동화된 버전**. Kernel은 기존 matmul kernel 사용.
|
||||
|
||||
### DQ3. DeviceMesh와 기존 topology
|
||||
|
||||
KernBench topology는 이미 SIP/cube/PE 계층. DTensor의 DeviceMesh는 추상
|
||||
`(tp_size, dp_size, ...)` grid. 매핑:
|
||||
|
||||
- 1D mesh of size = SIP count → rank = SIP
|
||||
- 2D mesh (tp × dp) → SIP을 그룹 분할 (pure TP 대신 mixed parallelism)
|
||||
|
||||
초기엔 1D mesh만, DP × TP 2D는 future.
|
||||
|
||||
### DQ4. Placement의 intra-device (DP) 통합
|
||||
|
||||
KernBench 특이점: 한 rank 내부에서 DPPolicy로 cube/PE에 분산. DTensor는
|
||||
device 내부를 보지 않음. 통합:
|
||||
|
||||
- DTensor placement = rank (SIP) 간 분산
|
||||
- 각 rank의 local tensor는 여전히 DPPolicy로 cube/PE 배치
|
||||
- → DTensor wrapper가 local tensor의 DPPolicy도 보관
|
||||
|
||||
### DQ5. Collective 자동 삽입 지점
|
||||
|
||||
`redistribute` 또는 operator forward 시. ADR-0024의 submit+yield+wait 패턴을
|
||||
자동으로 호출하는 형태. `_launch_submit` 내부화.
|
||||
|
||||
### DQ6. Autograd
|
||||
|
||||
DTensor는 autograd와 상호작용 (backward에서 reverse collective). KernBench가
|
||||
backward 지원하기 전까지는 **forward-only DTensor**.
|
||||
|
||||
---
|
||||
|
||||
## Open questions (to resolve before real design)
|
||||
|
||||
1. **우선순위**: Megatron-style(ADR-0027)이 먼저 안착한 후 DTensor를 위에
|
||||
얹는가, 아니면 공통 lower-layer를 먼저 설계하는가?
|
||||
2. **호환성 목표**: PyTorch DTensor API와 몇 %까지 일치시키는가? 독자 API vs
|
||||
거의 동일?
|
||||
3. **Operator dispatch**: KernBench `Tensor` 클래스에 `__matmul__` 등 연산자
|
||||
overloading을 도입하는가? (현재는 kernel launch만)
|
||||
4. **Redistribute 정책**: `Shard(0) → Replicate()` 변환 시 어떤 collective
|
||||
사용? `all_gather`가 없으면 구현 전까지 제약.
|
||||
5. **Mesh × DPPolicy interaction**: 하나의 DTensor가 2개 layer 분산을 갖는
|
||||
경우의 metadata 표현.
|
||||
6. **Partial placement의 reduce 시점**: 자동 vs 명시 `redistribute` 호출.
|
||||
7. **Bench authoring impact**: 기존 Megatron-style bench가 DTensor 기반으로
|
||||
얼마나 쉽게 포팅되는가?
|
||||
|
||||
---
|
||||
|
||||
## Non-goals (for future real ADR)
|
||||
|
||||
- 이번 stub에서 API 확정. Future ADR에서 구체화.
|
||||
- Implementation timeline. 이번 round에서는 **설계 공간 매핑만**.
|
||||
|
||||
---
|
||||
|
||||
## Dependencies (potential)
|
||||
|
||||
- **ADR-0024** (launcher): rank / device 기반
|
||||
- **ADR-0026** (DPPolicy cleanup): DTensor placement와의 분리 명확화
|
||||
- **ADR-0027** (Megatron TP): 실용 TP 패턴 경험을 DTensor 설계로 환류
|
||||
- **Future ADR** (operator dispatch layer): KernBench Tensor에 operator
|
||||
overloading 도입
|
||||
|
||||
---
|
||||
|
||||
## Expected consequences (hypothetical)
|
||||
|
||||
### Positive
|
||||
|
||||
- PyTorch training code 이식이 **매우 쉬워짐** (DTensor 코드 그대로).
|
||||
- TP + DP + 더 복잡한 parallelism을 **하나의 추상화**로 표현.
|
||||
- Collective 삽입이 자동 → bench 작성자 부담 감소.
|
||||
|
||||
### Negative
|
||||
|
||||
- Operator dispatch layer 신규 구축 → 상당한 엔지니어링.
|
||||
- Implicit behavior 증가 → 디버깅 / 성능 분석 복잡.
|
||||
- KernBench의 "명시적 kernel launch" 철학과 tension.
|
||||
|
||||
---
|
||||
|
||||
## Action
|
||||
|
||||
- **Phase 1 (현재)**: 본 stub 유지. Megatron-style (ADR-0027) 먼저 구현 +
|
||||
사용 경험 축적.
|
||||
- **Phase 2 (future)**: 사용 경험을 바탕으로 본 ADR을 real design으로 승격.
|
||||
위 Open questions에 대한 답을 제시.
|
||||
- **Phase 3 (future)**: Implementation.
|
||||
|
||||
현재 구현 작업은 **없음**. 디자인 공간 매핑만.
|
||||
|
||||
---
|
||||
|
||||
## Affected files
|
||||
|
||||
본 ADR은 **stub**이므로 production 변경 없음. Future real ADR에서 갱신될
|
||||
파일 후보:
|
||||
|
||||
| File | 예상 변경 (future) |
|
||||
|------|---|
|
||||
| `src/kernbench/dtensor/__init__.py` | 신규 패키지 |
|
||||
| `src/kernbench/dtensor/device_mesh.py` | DeviceMesh |
|
||||
| `src/kernbench/dtensor/placements.py` | Shard/Replicate/Partial |
|
||||
| `src/kernbench/dtensor/api.py` | distribute_tensor, redistribute |
|
||||
| `src/kernbench/dtensor/ops/*.py` | Operator dispatch (matmul 등) |
|
||||
| `src/kernbench/runtime_api/tensor.py` | Tensor에 `__matmul__` 등 추가 |
|
||||
@@ -0,0 +1,347 @@
|
||||
# ADR-0030: IPCQ Physical Addressing — PhysAddr integration
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
|
||||
## Context
|
||||
|
||||
### 목표
|
||||
|
||||
IPCQ ring buffer의 주소 체계를 ADR-0023의 **synthetic parallel namespace**
|
||||
(`_IPCQ_BASE = 1<<60`)에서 **ADR-0001의 PhysAddr**로 이관한다. Routing /
|
||||
allocator / MemoryStore의 정합성을 회복하고, buffer_kind (tcm/hbm/sram)별
|
||||
physical backing을 구조적 좌표로 표현한다.
|
||||
|
||||
### 현재 상태 (ADR-0023 D2.5)
|
||||
|
||||
`src/kernbench/ccl/install.py:52-56`:
|
||||
|
||||
```python
|
||||
_IPCQ_BASE = 1 << 60
|
||||
def _ipcq_base_for_pe(sip, cube, pe):
|
||||
return _IPCQ_BASE | (sip << 40) | (cube << 32) | (pe << 24)
|
||||
|
||||
def rx_base(s, c, p, d):
|
||||
return _ipcq_base_for_pe(s, c, p) + direction_idx[d] * bytes_per_direction
|
||||
```
|
||||
|
||||
- **bit 60** 사용 → ADR-0001의 51-bit PhysAddr 공간 밖 (`MAX_51 = (1 << 51) - 1`)
|
||||
- `PhysAddr.decode(addr)` → `PhysAddrError("addr must be a 51-bit value")`
|
||||
- `IpcqEndpoint.rx_base_pa: int` — 타입이 raw int, 구조 없음
|
||||
- `buffer_kind` (tcm/hbm/sram)와 synthetic 주소의 관계가 coupling 없음
|
||||
- Allocator (`PEMemAllocator`) 우회 — synthetic unique id per (sip, cube, pe,
|
||||
direction). 진짜 physical allocation이 아님
|
||||
|
||||
ADR-0023 D2.5 원문:
|
||||
|
||||
> This bypasses the topology's address resolver / PhysAddr encoding and
|
||||
> treats IPCQ buffers as a separate, parallel address namespace. Real PA
|
||||
> encoding can be plugged in later without changing the rest of the design.
|
||||
|
||||
"later"가 이 ADR.
|
||||
|
||||
### 왜 지금 다루는가
|
||||
|
||||
- ADR-0025 (direction addressing)은 주소-기반 매칭으로 전환. 주소가 correctness에
|
||||
직접 기여 → 주소 체계가 설계 관점에서 더 중요해짐
|
||||
- ADR-0001의 "Routing consumes decoded domains, not raw bit-fields" 계약 위반
|
||||
지속 → 기술 부채
|
||||
- Routing fabric (cube_noc / UCIe)은 PhysAddr.decode()로 destination을 정함.
|
||||
IPCQ의 synthetic 주소가 fabric routing에서 실제로 어떻게 처리되는지 **검증되지
|
||||
않음** (별도 경로로 배달되는 것으로 추정)
|
||||
- TCM / HBM / SRAM의 실제 memory layout과 IPCQ ring buffer 위치가 **disjoint**
|
||||
→ allocator가 IPCQ 영역을 모르므로 실수로 겹칠 가능성 (현재는 bit 60로 완전
|
||||
분리되어 문제 없지만 설계 원칙상 건강하지 않음)
|
||||
|
||||
### 풀어야 할 문제
|
||||
|
||||
1. **IPCQ ring buffer의 PhysAddr 표현**: buffer_kind별로 어떤 PhysAddr factory를
|
||||
쓸지.
|
||||
2. **PhysAddr 공간 부족 가능성**: 51-bit 공간에 IPCQ 버퍼를 담을 여유가 있는지.
|
||||
3. **Allocator 통합**: `PEMemAllocator`에 IPCQ buffer 영역 예약 기능 추가, 또는
|
||||
기존 pool에서 정상 allocation.
|
||||
4. **MemoryStore space naming 정리**: 현재는 `{"tcm", "hbm", "sram"}` 문자열로
|
||||
space 구분. IPCQ buffer도 이 space에 속하면 일반 data와 주소 겹침 방지 필요.
|
||||
5. **Routing fabric 통합**: PhysAddr 기반 routing이 IPCQ 토큰을 올바른 SIP의
|
||||
올바른 메모리로 배달.
|
||||
6. **ADR-0025와의 정합**: 주소-기반 매칭이 PhysAddr에서도 동일하게 작동.
|
||||
|
||||
---
|
||||
|
||||
## Decision
|
||||
|
||||
### D1. IPCQ ring buffer = PhysAddr factory 사용
|
||||
|
||||
각 `buffer_kind`가 해당하는 PhysAddr factory를 호출:
|
||||
|
||||
| buffer_kind | PhysAddr factory | 필요한 인자 |
|
||||
|---|---|---|
|
||||
| `tcm` | `PhysAddr.pe_tcm_addr(rack_id, sip_id, cube_id, pe_id, tcm_offset)` | PE-local TCM |
|
||||
| `hbm` | `PhysAddr.pe_hbm_addr(rack_id, sip_id, cube_id, pe_id, pe_local_hbm_offset, slice_size_bytes)` | PE-local HBM slice |
|
||||
| `sram` | `PhysAddr.cube_sram_addr(rack_id, sip_id, cube_id, sram_offset)` | Cube-shared SRAM |
|
||||
|
||||
Install plan builder (`build_install_plans` in ADR-0024)가 각 PE의 rx_base를
|
||||
계산할 때:
|
||||
|
||||
```python
|
||||
# ADR-0030 후 install_plan.py (pseudocode)
|
||||
def _compute_rx_base(sip, cube, pe, direction_idx, buffer_kind, n_slots, slot_size,
|
||||
allocator_pool, rack_id=0) -> PhysAddr:
|
||||
bytes_per_direction = n_slots * slot_size
|
||||
offset = direction_idx * bytes_per_direction
|
||||
|
||||
if buffer_kind == "tcm":
|
||||
# TCM base (per-PE) + direction offset
|
||||
tcm_base = allocator_pool.reserve_pe_tcm_for_ipcq(sip, cube, pe,
|
||||
total_bytes=N_DIR * bytes_per_direction)
|
||||
return PhysAddr.pe_tcm_addr(rack_id=rack_id, sip_id=sip, cube_id=cube,
|
||||
pe_id=pe, tcm_offset=tcm_base + offset)
|
||||
elif buffer_kind == "hbm":
|
||||
hbm_base = allocator_pool.reserve_pe_hbm_for_ipcq(sip, cube, pe,
|
||||
total_bytes=...)
|
||||
return PhysAddr.pe_hbm_addr(rack_id=rack_id, sip_id=sip, cube_id=cube,
|
||||
pe_id=pe, pe_local_hbm_offset=hbm_base + offset,
|
||||
slice_size_bytes=slice_size)
|
||||
elif buffer_kind == "sram":
|
||||
sram_base = allocator_pool.reserve_cube_sram_for_ipcq(sip, cube,
|
||||
total_bytes=...)
|
||||
return PhysAddr.cube_sram_addr(rack_id=rack_id, sip_id=sip, cube_id=cube,
|
||||
sram_offset=sram_base + offset)
|
||||
```
|
||||
|
||||
`IpcqEndpoint.rx_base_pa`의 타입을 `PhysAddr` (또는 encoded `int`)로 변경:
|
||||
|
||||
```python
|
||||
@dataclass(frozen=True)
|
||||
class IpcqEndpoint:
|
||||
sip: int
|
||||
cube: int
|
||||
pe: int
|
||||
buffer_kind: str
|
||||
rx_base_pa: int # PhysAddr.encode() 결과 (51-bit)
|
||||
rx_base_va: int
|
||||
n_slots: int
|
||||
slot_size: int
|
||||
```
|
||||
|
||||
타입은 int 유지 (encoded form), 단 **반드시 PhysAddr.decode()로 복원 가능**한
|
||||
값임을 invariant으로 둔다. 디코더 호출자는 `PhysAddr.decode(rx_base_pa)`로
|
||||
구조적 좌표 획득.
|
||||
|
||||
### D2. Allocator 확장 — IPCQ 예약 API
|
||||
|
||||
`PEMemAllocator`에 IPCQ 전용 예약 기능 추가:
|
||||
|
||||
```python
|
||||
class PEMemAllocator:
|
||||
def reserve_ipcq_tcm(self, total_bytes: int) -> int:
|
||||
"""Reserve TCM region for IPCQ ring buffers at this PE.
|
||||
Returns tcm_offset (to be used in PhysAddr.pe_tcm_addr)."""
|
||||
# TCM에서 `total_bytes` 연속 영역 예약.
|
||||
# Tensor allocation과 겹치지 않도록.
|
||||
|
||||
def reserve_ipcq_hbm(self, total_bytes: int) -> int: ...
|
||||
# cube-level allocator도 유사
|
||||
```
|
||||
|
||||
Install plan 빌더가 각 PE allocator에서 예약. 예약 결과(offset)를 PhysAddr
|
||||
factory에 전달.
|
||||
|
||||
**기존 `_ipcq_base_for_pe` / `_IPCQ_BASE` 제거**.
|
||||
|
||||
### D3. MemoryStore space 통합
|
||||
|
||||
현재 `MemoryStore`는 `{space_name: {addr: ndarray}}` 구조. IPCQ buffer는 일반
|
||||
tensor 데이터와 같은 space (tcm/hbm/sram)를 공유하게 됨. 주소 유일성은 ADR-0001의
|
||||
PhysAddr 계층 보장.
|
||||
|
||||
Backward compatibility: 기존 IPCQ address (synthetic)을 쓰는 code path는
|
||||
**제거**하고, 모두 PhysAddr.encode() 결과만 사용. 이 자체는 API 변경이 아니라
|
||||
값 변경.
|
||||
|
||||
### D4. Routing fabric 통합
|
||||
|
||||
IPCQ DMA write (`IpcqDmaToken`의 `src_addr → dst_addr`)이 PhysAddr encoding을
|
||||
사용하므로 **routing fabric이 `PhysAddr.decode(dst_addr)`로 destination
|
||||
SIP/cube/PE를 정확히 찾을 수 있음**. Fabric routing 로직 변경 없음 (기존에도
|
||||
PhysAddr.decode를 쓰는 것으로 추정).
|
||||
|
||||
**검증 필요**: 현재 fabric이 bit 60 synthetic 주소를 어떻게 라우팅하는지 확인.
|
||||
별도 경로가 있다면 제거, PhysAddr 경로로 통합.
|
||||
|
||||
### D5. ADR-0025와의 정합
|
||||
|
||||
ADR-0025의 주소-기반 매칭 (dst_addr로 direction 식별)은 PhysAddr.encode()
|
||||
결과를 비교하는 것으로 자연스럽게 호환. 변경 없음.
|
||||
|
||||
다만 debug / diagnostic 향상 가능:
|
||||
|
||||
```python
|
||||
# pointer_dump 등에서
|
||||
print(f"E: rx_base_pa={PhysAddr.decode(qp.peer.rx_base_pa)}")
|
||||
# 출력 예: PhysAddr(sip=1, cube=0, pe=0, kind="pe_resource", unit_type=PE, ...)
|
||||
```
|
||||
|
||||
이전 synthetic 주소는 decode 불가 → diagnostic 질 저하. PhysAddr 전환으로 개선.
|
||||
|
||||
### D6. ADR-0023 D2.5 amendment
|
||||
|
||||
ADR-0023의 "bypasses PhysAddr encoding" 문구를 **Accepted fallback → now
|
||||
replaced by ADR-0030**으로 수정. 본 ADR이 적용되면 ADR-0023 D2.5의 "Real PA
|
||||
encoding can be plugged in later" 약속이 이행된 것.
|
||||
|
||||
---
|
||||
|
||||
## Migration strategy
|
||||
|
||||
단계적 전환 (한 PR로 하지 않는다):
|
||||
|
||||
### Phase 1: PhysAddr 공간 재검토
|
||||
- 51-bit PhysAddr 공간에 IPCQ ring buffer가 실제로 들어갈 수 있는지 확인.
|
||||
- 각 buffer_kind (tcm/hbm/sram)별 factory가 제공하는 `local_offset` 범위가
|
||||
IPCQ 요구 (4 direction × n_slots × slot_size)를 수용 가능한지.
|
||||
- 부족하면 PhysAddr layout 자체 확장 (ADR-0001 amendment 별도 필요).
|
||||
|
||||
### Phase 2: Allocator API 확장
|
||||
- `PEMemAllocator.reserve_ipcq_*` 메소드 추가.
|
||||
- 기존 tensor allocation과 영역 충돌 방지.
|
||||
|
||||
### Phase 3: Install plan builder 전환
|
||||
- `_ipcq_base_for_pe` 제거, PhysAddr factory 호출로 대체.
|
||||
- `IpcqEndpoint.rx_base_pa`가 PhysAddr.encode() 결과 (51-bit).
|
||||
|
||||
### Phase 4: Routing fabric 검증
|
||||
- IPCQ DMA token이 fabric 정상 경로로 배달되는지 확인.
|
||||
- 별도 fast-path가 있다면 제거, 통합.
|
||||
|
||||
### Phase 5: MemoryStore space 검증
|
||||
- IPCQ buffer 주소가 기존 tensor 주소와 겹치지 않는지.
|
||||
- Allocator 레벨에서 이미 예약했으므로 정상적으로 분리되어야 함.
|
||||
|
||||
### Phase 6: ADR-0023 D2.5 업데이트 + 기존 sideband path 제거 (완료)
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **ADR-0031** (PhysAddr PE-resource extension) — **Blocker**: PhysAddr가 PE
|
||||
resource (특히 IPCQ ring buffer)를 충분히 표현할 수 있도록 schema 확장이
|
||||
선행되어야 함. 본 ADR은 ADR-0031 완료 후에만 실행 가능.
|
||||
- **ADR-0001** (PhysAddr layout): 본 ADR의 기반. 51-bit 공간 / factory API의
|
||||
ADR-0031 확장본을 사용.
|
||||
- **ADR-0023** (IPCQ protocol): 본 ADR은 ADR-0023 D2.5의 "later" 약속 이행.
|
||||
D9 piggyback / credit return 프로토콜 자체는 불변.
|
||||
- **ADR-0024** (launcher + install_plan.py): `build_install_plans`가 PhysAddr
|
||||
factory를 호출하게 됨.
|
||||
- **ADR-0025** (direction addressing): 주소-기반 매칭이 PhysAddr에서도 동일하게
|
||||
작동. 변경 없음.
|
||||
|
||||
---
|
||||
|
||||
## Non-goals
|
||||
|
||||
- **ADR-0001 PhysAddr layout 자체 변경**: 51-bit 공간과 segment 구조는 유지.
|
||||
부족 시 별도 ADR.
|
||||
- **IPCQ protocol semantic 변경**: ADR-0023 D9 piggyback 등 프로토콜 로직 유지.
|
||||
- **Allocator 전반 재설계**: IPCQ 예약 API 추가만.
|
||||
|
||||
---
|
||||
|
||||
## Open questions
|
||||
|
||||
### 🔴 Critical — Migration 전 반드시 검증
|
||||
|
||||
- **PhysAddr 51-bit 공간에 IPCQ 버퍼가 실제로 들어가는가**: 각 PE의 TCM
|
||||
영역에서 `4 direction × n_slots (default 4) × slot_size (default 4KB)` =
|
||||
64KB가 PE TCM 공간에 수용 가능. TCM size (e.g., 16MB) 대비 충분. HBM도 여유
|
||||
많음. SRAM은 cube 공유라 direction × PE 곱이 있음 — 별도 검증 필요.
|
||||
- **Routing fabric의 현재 IPCQ 주소 처리**: 현재 synthetic 주소가 fabric에서
|
||||
어떻게 routing되는지 trace 필요. `PhysAddr.decode()`로 판독 불가한 값이
|
||||
fabric에서 정상 배달된다면 어떤 경로를 쓰는지 조사.
|
||||
|
||||
### 🟡 Nice-to-have
|
||||
|
||||
- **IPCQ 전용 kind / sub_offset 인코딩**: `UnitType.PE`의 sub_offset 공간을
|
||||
IPCQ와 공유. 충돌 방지를 위해 IPCQ 전용 sub-space 정의할지 여부.
|
||||
- **Debug tool**: `pointer_dump`를 PhysAddr 포매팅으로 개선.
|
||||
|
||||
---
|
||||
|
||||
## Test strategy
|
||||
|
||||
### T1. PhysAddr round-trip
|
||||
|
||||
`tests/test_ipcq_physaddr.py` (new):
|
||||
- `PhysAddr.pe_tcm_addr(...)` → encode → decode → 동일 필드 복원
|
||||
- TCM / HBM / SRAM 각 factory에 대해
|
||||
|
||||
### T2. Allocator 예약
|
||||
|
||||
`tests/test_ipcq_alloc.py` (new):
|
||||
- `PEMemAllocator.reserve_ipcq_tcm` → 반환된 offset이 valid TCM 영역
|
||||
- 중복 예약 → 에러 또는 non-overlapping offset
|
||||
- Tensor allocation과 충돌 없음
|
||||
|
||||
### T3. Install plan PhysAddr integration
|
||||
|
||||
`tests/test_ccl_install_plan.py` (확장):
|
||||
- `build_install_plans` 결과의 `rx_base_pa`가 PhysAddr.decode() 가능
|
||||
- Decoded 좌표가 plan의 (sip, cube, pe)와 일치
|
||||
- I3.1 invariant (ADR-0025 D6) — rx_base range disjointness가 PhysAddr에서도 성립
|
||||
|
||||
### T4. Routing — IPCQ DMA fabric traversal
|
||||
|
||||
`tests/test_ipcq_routing.py` (new):
|
||||
- Cross-SIP IPCQ send → fabric이 `PhysAddr.decode(dst_addr)`로 destination SIP
|
||||
정확히 판단 → 올바른 MemoryStore에 write
|
||||
- UCIe 경로 / cube_noc 경로 모두 검증
|
||||
|
||||
### T5. 회귀
|
||||
|
||||
- 기존 IPCQ E2E 테스트 (ring, mesh, tree) 모두 통과
|
||||
- ADR-0024, ADR-0025 통합 테스트 통과
|
||||
|
||||
---
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
- **ADR-0001 정합성 회복**: routing과 addressing이 단일 체계.
|
||||
- **buffer_kind 명확**: TCM/HBM/SRAM이 구조적 좌표로 구분.
|
||||
- **Debug 향상**: PhysAddr.decode()로 사람이 읽을 수 있는 좌표.
|
||||
- **Allocator 통합**: IPCQ 영역이 정상 예약 → tensor와의 충돌 리스크 사전 차단.
|
||||
- **Fabric routing 일원화**: 별도 경로 없이 기존 PhysAddr-based routing 재활용.
|
||||
|
||||
### Negative
|
||||
|
||||
- **Migration 복잡도**: 6 Phase 단계적 전환 필요. 각 Phase마다 regression 리스크.
|
||||
- **PhysAddr 공간 검증 부담**: Phase 1에서 TCM/HBM/SRAM 공간이 IPCQ 요구를
|
||||
수용하는지 실측 필요.
|
||||
- **Routing fabric 검증**: 현재 fabric이 synthetic 주소를 어떻게 처리하는지
|
||||
조사 필요.
|
||||
|
||||
### Neutral
|
||||
|
||||
- IPCQ protocol semantic (ADR-0023 D9 등) 불변.
|
||||
- ADR-0025의 direction addressing 로직 불변.
|
||||
|
||||
---
|
||||
|
||||
## Affected files
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `src/kernbench/ccl/install.py` | `_IPCQ_BASE`, `_ipcq_base_for_pe` 제거 |
|
||||
| `src/kernbench/ccl/install_plan.py` (ADR-0024) | D1: PhysAddr factory 호출로 rx_base 계산 |
|
||||
| `src/kernbench/policy/address/allocator.py` (or similar) | D2: IPCQ 예약 API (`reserve_ipcq_tcm` 등) |
|
||||
| `src/kernbench/common/ipcq_types.py` | D1: `IpcqEndpoint.rx_base_pa` 문서화 — PhysAddr.encode 결과 |
|
||||
| `src/kernbench/sim_engine/memory_store.py` | D3: IPCQ buffer가 기존 space와 공유되는지 검증 |
|
||||
| `src/kernbench/sim_engine/engine.py` | D4: IPCQ token routing이 PhysAddr-based fabric 경로 사용 |
|
||||
| `src/kernbench/ccl/diagnostics.py` | D5: pointer_dump를 PhysAddr 포매팅으로 개선 |
|
||||
| `docs/adr/ADR-0023-dev-ipcq-pe-collective.md` | D6: D2.5 amendment note |
|
||||
| `tests/test_ipcq_physaddr.py` (new) | T1 |
|
||||
| `tests/test_ipcq_alloc.py` (new) | T2 |
|
||||
| `tests/test_ccl_install_plan.py` | T3 확장 |
|
||||
| `tests/test_ipcq_routing.py` (new) | T4 |
|
||||
Reference in New Issue
Block a user