gqa(decode-4cases): Case 3 — Cube-Repl × PE-SP (intra-CUBE AR only; 8× memory) (5C.C)
Adds the third 4-cases panel: KV replicated per cube (8× memory waste), PEs SP on S_kv within each cube, intra-CUBE 8-way reduce on (m, ℓ, O), and no inter-CUBE comm (every cube ends with full answer; designated writer = cube 0). Reuses the row-chain + col-bridge intra-CUBE pattern that anchors Case 4 (21 ipcq_copy per cube × 8 cubes = 168 total). 12 tests pass (4 Case 4 + 4 Case 2 + 4 Case 3). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,9 @@ import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from kernbench.benches._gqa_attention_decode_cube_repl_pe_sp import (
|
||||
gqa_attention_decode_cube_repl_pe_sp_kernel,
|
||||
)
|
||||
from kernbench.benches._gqa_attention_decode_cube_repl_pe_tp import (
|
||||
gqa_attention_decode_cube_repl_pe_tp_kernel,
|
||||
)
|
||||
@@ -58,7 +61,8 @@ _SWEEP_JSON = _OUTPUT_DIR / "sweep.json"
|
||||
_PANELS = (
|
||||
"single_kv_group_decode_gqa_cube_sp_pe_sp", # Case 4 ★ optimal
|
||||
"single_kv_group_decode_gqa_cube_repl_pe_tp", # Case 2 (no comm; 8× memory)
|
||||
# Cases 1, 3 to be added by 5C.A/C
|
||||
"single_kv_group_decode_gqa_cube_repl_pe_sp", # Case 3 (intra-CUBE AR only; 8× memory)
|
||||
# Case 1 to be added by 5C.A
|
||||
)
|
||||
|
||||
# Each entry: (kind, panel-specific params).
|
||||
@@ -82,6 +86,14 @@ _PANEL_DISPATCH: dict[str, tuple[str, dict]] = {
|
||||
"T_q": 1, "S_kv": 131_072,
|
||||
"d_head": 128, "h_q": 8, "h_kv": 1,
|
||||
}),
|
||||
"single_kv_group_decode_gqa_cube_repl_pe_sp": ("decode_cube_repl_pe_sp", {
|
||||
# Case 3: K, V replicated per cube (8× memory); PEs SP on S_kv
|
||||
# within each cube. Intra-CUBE 8-way reduce; no inter-CUBE comm
|
||||
# (every cube ends with full answer; designated writer = cube 0).
|
||||
"C": 8, "P": 8,
|
||||
"T_q": 1, "S_kv": 131_072,
|
||||
"d_head": 128, "h_q": 8, "h_kv": 1,
|
||||
}),
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +131,39 @@ def _run_decode_panel_cube_repl_pe_tp(
|
||||
)
|
||||
|
||||
|
||||
def _run_decode_panel_cube_repl_pe_sp(
|
||||
ctx, *, panel: str, C: int, P: int,
|
||||
T_q: int, S_kv: int,
|
||||
d_head: int, h_q: int, h_kv: int,
|
||||
) -> None:
|
||||
"""Case 3 runner: K, V replicated per cube; PEs SP on S_kv within cube.
|
||||
|
||||
DPPolicy models the cluster-wide 8× memory waste — every cube
|
||||
holds full K, V in its HBM region, then splits the S_kv axis
|
||||
row_wise across its 8 PEs. The kernel does an intra-CUBE 8-way
|
||||
reduce on (m, ℓ, O); only cube 0's PE 0 writes the output.
|
||||
"""
|
||||
configure_sfr_intercube_multisip(ctx.engine, ctx.spec, _ccl_cfg())
|
||||
dp_full = DPPolicy(cube="replicate", pe="replicate",
|
||||
num_cubes=C, num_pes=P)
|
||||
dp_kv = DPPolicy(cube="replicate", pe="row_wise",
|
||||
num_cubes=C, num_pes=P)
|
||||
q = ctx.zeros((T_q, h_q * d_head),
|
||||
dtype="f16", dp=dp_full, name=f"{panel}_q")
|
||||
k = ctx.zeros((S_kv, h_kv * d_head),
|
||||
dtype="f16", dp=dp_kv, name=f"{panel}_k")
|
||||
v = ctx.zeros((S_kv, h_kv * d_head),
|
||||
dtype="f16", dp=dp_kv, name=f"{panel}_v")
|
||||
o = ctx.empty((T_q, h_q * d_head),
|
||||
dtype="f16", dp=dp_full, name=f"{panel}_o")
|
||||
ctx.launch(
|
||||
panel, gqa_attention_decode_cube_repl_pe_sp_kernel,
|
||||
q, k, v, o,
|
||||
T_q, S_kv, h_q, h_kv, d_head, C, P,
|
||||
_auto_dim_remap=False,
|
||||
)
|
||||
|
||||
|
||||
def _make_bench_fn(panel: str):
|
||||
kind, params = _PANEL_DISPATCH[panel]
|
||||
|
||||
@@ -127,6 +172,8 @@ def _make_bench_fn(panel: str):
|
||||
_run_decode_panel(ctx, panel=panel, **params)
|
||||
elif kind == "decode_cube_repl_pe_tp":
|
||||
_run_decode_panel_cube_repl_pe_tp(ctx, panel=panel, **params)
|
||||
elif kind == "decode_cube_repl_pe_sp":
|
||||
_run_decode_panel_cube_repl_pe_sp(ctx, panel=panel, **params)
|
||||
else:
|
||||
raise RuntimeError(
|
||||
f"milestone-gqa-decode-4cases panel {panel!r} has "
|
||||
|
||||
Reference in New Issue
Block a user