Files
kernbench2/docs/adr-ko/ADR-0032-algo-intercube-allreduce.md
T
mukesh ff7d727ddd CCL allreduce: rename to lrab_hierarchical_allreduce + descriptive plots
Rename the intercube all-reduce identity to lrab_hierarchical_allreduce
(module, config key, distributed test) so the name reflects both levels
it implements: LRAB intra-SIP (local reduce to center root + broadcast)
and the hierarchical inter-SIP topology exchange (ring/torus/mesh).
ADR-0032 slug kept as the stable decision id; pure rename, no logic change.

Also in this batch:
- ADR-0032 (EN+KO): document the shipped center-root bidirectional reduce
  (doc was stale corner-root); annotate ccl.yaml root_cube as a placeholder.
- Rename allreduce + pe2pe latency plots to descriptive, title-matching
  filenames and retitle the in-plot headings; drop overview/overview_log.
- Point the PPTX image refs at the new plot names.

Doc + derived-artifact + rename only; no simulation behavior changed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 20:50:48 -07:00

12 KiB
Raw Blame History

ADR-0032: 큐브 간 All-Reduce — pe0 큐브-메시 리듀스 + 다중-SIP 교환

Status

Accepted (supersedes ADR-0029).

Context

목표

토폴로지 계층을 활용하는 단일 all-reduce 알고리즘을 정의한다: 각 SIP 내부의 큐브 메시(큐브 간) + SIP 간 교환. 단일 커널, 단일 SFR 구성 경로이며 topology.yamlccl.yaml로 구동된다.

ADR-0029(계층적 3-레벨)를 대체하는 이유

ADR-0029는 시스템의 모든 PE가 참여하는 3-레벨(큐브 내 → 큐브 간 → SIP 간) 알고리즘을 제안했다. 실제로는 텐서가 큐브 내 PE 단위가 아니라 큐브 단위로 샤딩되는 일반적 워크로드 패턴과 맞지 않으면서, 큐브 내 PE-PE stage 복잡성(양방향 reduce + 체인 브로드캐스트)을 추가한다.

또한 계층적 설계는 다음을 요구했다:

  • PE별 이웃 그래프 설치 (_build_pe_installs 다중 레벨)
  • 다중 레벨 토폴로지 스키마 (hierarchical_3level)
  • all_pes 매퍼 + multi_pe_sip_local 검증자 인프라

아래의 큐브 간 알고리즘은 이 모든 것을 제거한다: 4×4 큐브 메시 위에서 pe0만의 same-lane 큐브 간 reduce, 그 다음 루트 큐브에서 SIP 간 교환, 그 다음 다시 브로드캐스트. 더 단순한 커널, 더 단순한 와이어링, 일반적인 큐브당 DP 워크로드에 대해 동일한 대역폭 특성을 갖는다.

현재 상태

  • src/kernbench/ccl/algorithms/lrab_hierarchical_allreduce.py — 커널
  • src/kernbench/ccl/sfr_config.pyconfigure_sfr_intercube_multisip
  • src/kernbench/runtime_api/distributed.pyAhbmCCLBackendinit_process_group 시점에 자동으로 와이어링한다.
  • 기존 ring_allreduce, mesh_allreduce, tree_allreduce, hierarchical_allreduce 모듈과 그 테스트는 제거됨.

Decision

D1. 알고리즘 구조 — 5단계 (center-root, 양방향)

루트 큐브는 큐브 메시의 기하학적 중심에 위치한다:

root_col  = cube_w // 2
root_row  = cube_h // 2
root_cube = root_row * cube_w + root_col   # 중심; 4×4 메시에서 10

각 reduce/broadcast 단계는 이 중심을 향해 양방향으로 수렴/발산하여, corner-root 워크 대비 SIP 내부 임계 경로를 절반으로 줄인다 (4×4 메시: reduce 4홉 + broadcast 4홉 vs SE-코너 루트의 6+6).

각 SIP에 대해 (mp.spawn으로 동시에 launch):

Phase 1 — col == root_col에서 수렴하는 Row reduce (큐브 메시, pe0만):
    좌측 절반(col < root_col)은 W→E로, 우측 절반(col > root_col)은
    E→W로 진행; root_col 큐브가 양쪽을 병합 → row sum 보유.

Phase 2 — col == root_col에서 row == root_row로 수렴하는 Col reduce:
    위쪽(row < root_row)은 N→S로, 아래쪽(row > root_row)은 S→N로 진행;
    루트 큐브가 양쪽을 병합 → 전체 SIP sum 보유.

Phase 3 — cube_id == root_cube에서 SIP 간 교환 (pe0만):
    Ring / torus-2d row+col ring / mesh-2d chain reduce+broadcast —
    sip_topo_kind(topology.yaml의 sips.topology)로 선택.

Phase 4 — col == root_col에서 root_row로부터 바깥쪽으로 Col 브로드캐스트.

Phase 5 — root_col로부터 바깥쪽으로 큐브 메시 전반에 Row 브로드캐스트.

모든 단계가 끝나면 모든 큐브의 pe0이 전역 sum을 보유한다.

단일 큐브 fast-path: cube_w == cube_h == 1(rank당 큐브 하나, 일반적인 TP 케이스)인 경우 SIP 내부 reduce/broadcast 단계를 건너뛰고 곧바로 Phase 3 SIP 간 교환으로 진행한다.

커널은 sip_topo_kind ∈ {0, 1, 2}(ring_1d, torus_2d, mesh_2d_no_wrap)로 파라미터화된 단일 함수이다. Phase 1-2와 4-5는 토폴로지 전반에서 동일하며, phase 3만 분기한다. 헬퍼 함수 _inter_sip_ring, _inter_sip_torus_2d, _inter_sip_mesh_2d가 세 가지 교환 패턴을 인코딩한다.

D2. 텐서 레이아웃 (rank = SIP, 워커별)

ADR-0024에 따라 프로세스 그룹 레벨에서 rank = SIP이다. 각 워커가 자신의 큐브-메시 전체 텐서를 할당한다:

dp = DPPolicy(cube="row_wise", pe="replicate", num_cubes=16, num_pes=1)
tensor = torch.zeros((n_cubes, n_elem), dtype="f16", dp=dp)

샤드 레이아웃: SIP당 16개 샤드, 큐브별 pe0에 하나씩. 커널은 각 큐브의 샤드를 pe_addr = t_ptr + cube_id * n_elem * 2로 주소 지정한다.

D3. SFR / IPCQ 와이어링 — configure_sfr_intercube_multisip

ADR-0024의 rank-to-2-PE 설치를 대체한다. 어느 큐브가 루트인지 또는 어느 SIP 토폴로지가 선택되었는지와 무관하게 모든 SIP의 모든 큐브의 pe0에 대해 PE_IPCQ 이웃 테이블을 와이어링한다. 이를 통해 커널이 런타임에 루트 큐브를 선출할 수 있고, 재와이어링 없이 토폴로지 전환을 지원한다.

Level Direction labels Scope
SIP 내부 큐브 간 N / S / E / W 모든 큐브의 pe0 → 메시 이웃의 pe0 (랩어라운드 없음)
SIP 간 (모든 큐브) global_E / global_W / global_N / global_S sip A의 큐브 c의 pe0 → sips.topology에 따른 피어 SIP의 큐브 c의 pe0

SIP 간 방향은 global_* 접두사를 사용하여 큐브 간 방향과 네임스페이스를 분리한다. ADR-0025의 _OPPOSITE_DIRglobal_E ↔ global_Wglobal_N ↔ global_S로 확장되어, 2-SIP 양방향 ring에 대한 역방향 리졸버가 올바르게 처리되도록 한다.

내부적으로 이 함수는 다음 인자로 install_ipcq를 호출한다:

  • world_size = n_sips × n_cubes
  • rank_to_pe = [(sip, cube, 0) for sip in range(n_sips) for cube in range(n_cubes)]
  • 위 매핑을 생성하는 클로저로 캡처된 neighbors() 함수.

world_size는 IPCQ 와이어링 내부적이며 프로세스-그룹 rank로 유출되지 않는다.

D4. SIP 토폴로지 — topology.yaml에서

system:
  sips:
    count: 2
    topology: ring_1d       # or torus_2d, mesh_2d_no_wrap
  • ring_1d: n_sips-1 라운드의 send global_E / recv global_W.
  • torus_2d: sqrt(n_sips)×sqrt(n_sips) 랩핑 메시. global_E/W에서 row ring, 이어서 global_S/N에서 col ring.
  • mesh_2d_no_wrap: 랩어라운드 없는 정사각형 메시. 차원별 chain reduce + 브로드캐스트.

2D 변형은 n_sips가 완전 제곱수여야 한다.

D5. 프로세스-그룹 통합 — AhbmCCLBackend

init_process_group 시점에 백엔드는:

  1. ccl.yaml + topology.yaml을 로드한다.
  2. 알고리즘 모듈의 TOPO_NAME_TO_KIND를 사용하여 system.sips.topology로부터 sip_topo_kind, sip_topo_w, sip_topo_h를 도출한다.
  3. configure_sfr_intercube_multisip(engine, spec, cfg)를 호출한다 — 일회성 SFR 와이어링, NCCL 커뮤니케이터 생성을 모방한다.

dist.all_reduce(tensor) 호출 시:

  1. cfg["module"]로부터 kernel_fn을 해석한다.
  2. kernel_args(world_size, n_elem)로부터 인자 (n_elem, cube_w, cube_h, n_sips)를 구성한다.
  3. (sip_rank, sip_topo_kind, sip_topo_w, sip_topo_h)를 추가하며, 여기서 sip_rank는 현재 greenlet에 바인딩된 rank이다.
  4. _defer_wait=True로 launch; 모든 워커가 제출한 후 메인 스케줄러가 pending 핸들을 드레인한다 (ADR-0027 D0.4).

D6. 구성 스키마

ccl.yaml:

defaults:
  algorithm: lrab_hierarchical_allreduce
  buffer_kind: tcm
  ...

algorithms:
  lrab_hierarchical_allreduce:
    module: kernbench.ccl.algorithms.lrab_hierarchical_allreduce
    topology: none
    buffer_kind: tcm
    n_elem: 8
    root_cube: 15   # 현재 사용되지 않음 — 커널이 루트를 기하학적 중심으로
                    # 동적으로 선출한다 (D1 참조). 향후 명시적 루트 override /
                    # 런타임 선출 훅을 위한 placeholder로 유지한다.

topology.yaml:

system:
  sips:
    count: 2
    topology: ring_1d
sip:
  cube_mesh: { w: 4, h: 4 }

D7. 알고리즘 모듈 계약

cfg["module"]로 로드되는 모듈은 다음을 export해야 한다:

Name Purpose
kernel callable, 시그니처 (t_ptr, n_elem, cube_w, cube_h, n_sips, sip_rank, sip_topo_kind, sip_topo_w, sip_topo_h, tl)
kernel_args(world_size, n_elem) -> tuple 처음 4개의 scalar 인자(텐서별) 반환
TOPO_NAME_TO_KIND: dict[str, int] system.sips.topology 이름을 커널 분기 코드로 매핑
SIP_TOPO_RING, SIP_TOPO_TORUS, SIP_TOPO_MESH 정수 상수 (0, 1, 2)

Dependencies

  • ADR-0023: IPCQ 프로토콜 (이웃 테이블, 송수신, credit 반환).
  • ADR-0024: rank = SIP launcher, mp.spawn, greenlet-로컬 rank.
  • ADR-0025: 주소 기반 IPCQ 방향 매칭; global_* 쌍으로 확장된 _OPPOSITE_DIR.
  • ADR-0027: 메인 스케줄러에서의 worker-wait / 집합 통신 pending 드레인.

Non-goals

  • PE별 allreduce (큐브 내 PE-PE reduce). 범위 밖 — 본 알고리즘의 워크로드는 큐브당 DP이다.
  • 비대칭 SIP 토폴로지 (정사각형이 아닌 메시/토러스). torus_2dmesh_2d_no_wrapn_sips = k²를 요구한다.
  • 파이프라인 청크: 큐브당 단일 타일, 아직 파이프라이닝 없음.
  • 루트 큐브의 런타임 선출: 커널은 현재 SIP 내부 임계 경로를 최소화하기 위해 기하학적 중심인 root_cube = (mesh_h // 2) * mesh_w + (mesh_w // 2)을 사용한다. SFR 와이어링이 모든 큐브를 커버하므로, 필요해질 때 다른 루트를 런타임에 선출하는 것은 순수 커널 변경이다.

Consequences

Positive

  • 단일 커널, 단일 설치 경로로 all-reduce를 처리 — 제거된 네 개의 모듈(ring, mesh, tree, hierarchical)을 대체한다.
  • 토폴로지 무관 커널: ring / torus / mesh를 정수 파라미터 하나로 선택, 커널 중복 없음.
  • dist.all_reduce를 통한 자동화: 벤치 레벨이나 사용자 레벨의 알고리즘 선택 불필요; end-to-end 구성 기반.
  • 완전한 SFR 와이어링: 모든 SIP의 모든 큐브가 SIP 간 링크를 보유 — 향후 동적 루트 큐브 선출을 지원한다.

Negative

  • PE별 샤딩된 텐서에 부적합: 큐브 하나 내부에서 8개 PE에 걸쳐 샤딩되는 TP-레이어 스타일 텐서는 본 커널로 주소 지정할 수 없다. 이러한 워크로드에는 별도의 큐브 내 all-reduce 경로가 필요하다 (아직 구현되지 않음).
  • configure_sfr_intercube_multisip는 항상 모든 pe0을 와이어링: 주어진 실행이 부분집합(예: 1 SIP, ring만)만 필요하더라도. 설치 비용은 작지만 영(zero)은 아니다.

Affected files

File Change
src/kernbench/ccl/algorithms/lrab_hierarchical_allreduce.py (신규) 커널 + _inter_sip_* 헬퍼 + TOPO_NAME_TO_KIND
src/kernbench/ccl/sfr_config.py (신규) configure_sfr_intercube_multisip
src/kernbench/ccl/topologies.py torus_2d, mesh_2d_no_wrap 추가
src/kernbench/ccl/install.py _OPPOSITE_DIRglobal_* 쌍으로 확장
src/kernbench/runtime_api/distributed.py AhbmCCLBackendconfigure_sfr_intercube_multisip 사용 + sip_rank/topo 인자 추가
ccl.yaml 단일 lrab_hierarchical_allreduce 항목
topology.yaml system.sips.topology 추가
benches/ccl_allreduce.py Row-wise 큐브-메시 텐서 레이아웃
tests/test_allreduce_multidevice.py (신규) 구성 기반 ring/torus/mesh
tests/test_distributed_lrab_hierarchical_allreduce.py (신규) 전체 dist.all_reduce 경로
tests/test_intercube_sfr_config.py (신규) SFR 와이어링 검증
제거 ring_allreduce.py, mesh_allreduce.py, tree_allreduce.py, hierarchical_allreduce.py, hello_send.py, testing.py 및 그 테스트