policy(adr): ADR-0026 Revision 6 — document DPPolicy.cube_start
Amends ADR-0026 to reflect the cube_start field added in e2fe331.
The production code shipped without an ADR update; this fills that
gap. Documentation-only change (no production code, no test code).
Changes (mirrored in both EN and KO):
- Status: Revision 5 → Revision 6
- D1: add ``cube_start: int = 0`` to the canonical DPPolicy dataclass
- D3: ``cube = policy.cube_start + cube_id`` in resolve_dp_policy
- D8: new section explaining purpose (disjoint cube sub-meshes for
GQA Llama-70B 8-KV-group headline), semantics, default-0 backward
compatibility, intra-device constraint, design rationale
(scalar vs 2D origin vs cube_ids list), and the kernel-side
cube_start subtraction needed to compensate for ADR-0022's
physical-cube-id ``program_id(axis=1)`` semantics.
tools/verify_adr_lang_pairs.py passes (EN/KO Status keyword and
title in sync).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (Revision 5 — Phase 2 landed 2026-04-14, 523 passed + 1 strict xfail)
|
||||
Accepted (Revision 6 — cube_start added 2026-06-04; Revision 5 landed 2026-04-14)
|
||||
|
||||
## Context
|
||||
|
||||
@@ -31,9 +31,11 @@ class DPPolicy:
|
||||
pe: Literal["replicate", "column_wise", "row_wise"] = "replicate"
|
||||
num_pes: int | None = None
|
||||
num_cubes: int | None = None
|
||||
cube_start: int = 0 # Revision 6 — first cube in SIP; see D8
|
||||
```
|
||||
|
||||
Removed fields: `sip`, `num_sips`.
|
||||
Added fields (Revision 6): `cube_start` — see D8.
|
||||
|
||||
### D2. `ShardSpec` — structural (sip, cube, pe) coordinates, `pe_index` fully removed
|
||||
|
||||
@@ -119,9 +121,9 @@ def resolve_dp_policy(
|
||||
|
||||
for ls in local_shards:
|
||||
all_shards.append(ShardSpec(
|
||||
sip=target_sip, # from caller (current_device)
|
||||
cube=cube_id, # local within SIP
|
||||
pe=ls.local_pe, # local within cube (explicit name)
|
||||
sip=target_sip, # from caller (current_device)
|
||||
cube=policy.cube_start + cube_id, # Rev 6: shifted by D8 cube_start; default 0 = local within SIP
|
||||
pe=ls.local_pe, # local within cube (explicit name)
|
||||
offset_bytes=cube_offset + ls.offset_bytes,
|
||||
nbytes=ls.nbytes,
|
||||
))
|
||||
@@ -239,6 +241,53 @@ property: code that expected a global flat could otherwise silently
|
||||
receive a SIP-local result and index incorrectly — that possibility is
|
||||
eliminated.
|
||||
|
||||
### D8. Add `cube_start: int = 0` for disjoint cube sub-meshes within a SIP
|
||||
|
||||
**Revision 6 addition (2026-06-04)**.
|
||||
|
||||
**Purpose**: address a disjoint cube sub-mesh within one SIP (e.g.
|
||||
cubes 8..15 alongside cubes 0..7). Required by the GQA Llama-70B
|
||||
8-KV-group headline target — two 2×4 KV-groups per SIP × 4 SIPs = 64
|
||||
cubes — where the second KV-group on each SIP must land on cubes 8..15
|
||||
instead of the default 0..7.
|
||||
|
||||
**Semantics**: `resolve_dp_policy` returns `ShardSpec` with
|
||||
`cube = policy.cube_start + cube_id`, where `cube_id` iterates
|
||||
`0..num_cubes-1` within the launch. Selected cubes lie in
|
||||
`[cube_start, cube_start + num_cubes)` within the target SIP.
|
||||
|
||||
**Default**: `cube_start = 0` preserves every existing call site
|
||||
bit-for-bit (`ShardSpec.cube ∈ [0, num_cubes)` as before). The CCL
|
||||
milestone bench's full-SIP `DPPolicy(num_cubes=16)` continues to
|
||||
produce cubes 0..15.
|
||||
|
||||
**Constraint**: intra-device invariant preserved.
|
||||
`cube_start ∈ [0, cubes_per_sip)` and
|
||||
`cube_start + num_cubes ≤ cubes_per_sip`. SIP boundary crossing remains
|
||||
the job of `ahbm.set_device(rank)` (ADR-0024).
|
||||
|
||||
**Why scalar** (not 2D `cube_mesh_origin` or arbitrary `cube_ids` list):
|
||||
consumer kernels (e.g. `_attention_mesh_mlo_2d`) assume row-major
|
||||
contiguous cubes; scalar `cube_start` pairs naturally with `num_cubes`
|
||||
(range = `[start, start + count)`); zero migration churn at default 0.
|
||||
More general designs can be added on top later if a non-contiguous use
|
||||
case appears.
|
||||
|
||||
**Backward compatibility**: additive change with default value. No
|
||||
existing call site is forced to change. The "breaking change" stance
|
||||
in D7 applies only to the original sip/num_sips removal — `cube_start`
|
||||
does NOT break existing callers.
|
||||
|
||||
**Kernel-side note**: kernbench's `tl.program_id(axis=1)` returns the
|
||||
physical cube id (ADR-0022), not a launch-local rank. Kernels that
|
||||
derive ring positions from `program_id(axis=1)` must subtract
|
||||
`cube_start` to recover launch-local rank when `cube_start > 0` —
|
||||
otherwise they compute out-of-bounds sub-mesh positions and deadlock.
|
||||
See `_attention_mesh_mlo_2d.py` for the reference pattern. A future
|
||||
revision of ADR-0022 could move `program_id(axis=1)` to launch-local
|
||||
rank semantics; that change would let kernels drop the explicit
|
||||
subtraction.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **ADR-0024** (launcher): `set_device(rank)` and current-device scoping
|
||||
|
||||
Reference in New Issue
Block a user