sim: pin compute outputs and on-chip recv slots for composite operands
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
"""Regression: a recv handle used as a composite ``b`` operand must be read
|
||||
in place (on-chip), NOT DMA_READ from its non-HBM slot address.
|
||||
|
||||
Before the recv-pinning fix, recv handles were unpinned → the composite
|
||||
scheduler emitted DMA_READ(B) from the IPCQ slot address (non-HBM) →
|
||||
PhysAddr.decode raised PhysAddrError. On-chip (TCM/SRAM) recv slots are
|
||||
now pinned (ADR-0065 D4), so a composite operand reads them in place.
|
||||
|
||||
Isolates operand ``b``: ``a`` is a pinned ``tl.load``; only ``b`` is the
|
||||
recv handle. Mirrors the decode row-chain IPCQ directions (intra_E recv /
|
||||
intra_W send) so the recv actually lands without deadlock.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from kernbench.ccl.install import load_ccl_config, resolve_algorithm_config
|
||||
from kernbench.ccl.sfr_config import configure_sfr_intercube_multisip
|
||||
from kernbench.policy.placement.dp import DPPolicy
|
||||
from kernbench.runtime_api.bench_runner import run_bench
|
||||
from kernbench.runtime_api.types import resolve_device
|
||||
from kernbench.sim_engine.engine import GraphEngine
|
||||
from kernbench.topology.builder import resolve_topology
|
||||
|
||||
TOPOLOGY_DEFAULT = Path(__file__).resolve().parents[1] / "topology.yaml"
|
||||
P = 8
|
||||
|
||||
|
||||
def _ccl_cfg():
|
||||
return resolve_algorithm_config(
|
||||
load_ccl_config(), name="lrab_hierarchical_allreduce",
|
||||
)
|
||||
|
||||
|
||||
def _engine_factory(t, d):
|
||||
return GraphEngine(getattr(t, "topology_obj", t), enable_data=True)
|
||||
|
||||
|
||||
def _recv_operand_kernel(a_ptr, b_ptr, o_ptr, M, K, N, P, *, tl):
|
||||
pe_id = tl.program_id(axis=0)
|
||||
pe_in_group = pe_id % P
|
||||
group_cols = min(4, P)
|
||||
pe_col = pe_in_group % group_cols
|
||||
|
||||
A = tl.load(a_ptr, shape=(M, K), dtype="f16") # pinned (no DMA)
|
||||
if pe_col < group_cols - 1:
|
||||
B = tl.recv(dir="intra_E", shape=(K, N), dtype="f16") # recv handle
|
||||
out = tl.composite("gemm", a=A, b=B) # ← b = recv slot
|
||||
tl.store(o_ptr, out)
|
||||
if pe_col > 0:
|
||||
B_send = tl.load(b_ptr, shape=(K, N), dtype="f16")
|
||||
tl.send(dir="intra_W", src=B_send)
|
||||
|
||||
|
||||
def test_recv_handle_as_composite_operand_reads_in_place():
|
||||
M = K = N = 64
|
||||
topo = resolve_topology(str(TOPOLOGY_DEFAULT))
|
||||
|
||||
def _bench_fn(ctx):
|
||||
configure_sfr_intercube_multisip(ctx.engine, ctx.spec, _ccl_cfg())
|
||||
dp = DPPolicy(cube="replicate", pe="replicate", num_cubes=1, num_pes=P)
|
||||
a = ctx.zeros((M, K), dtype="f16", dp=dp, name="recv_operand_a")
|
||||
b = ctx.zeros((K, N), dtype="f16", dp=dp, name="recv_operand_b")
|
||||
o = ctx.empty((M, N), dtype="f16", dp=dp, name="recv_operand_o")
|
||||
ctx.launch(
|
||||
"recv_operand_composite", _recv_operand_kernel,
|
||||
a, b, o, M, K, N, P,
|
||||
_auto_dim_remap=False,
|
||||
)
|
||||
|
||||
r = run_bench(
|
||||
topology=topo, bench_fn=_bench_fn,
|
||||
device=resolve_device(None), engine_factory=_engine_factory,
|
||||
)
|
||||
assert r.completion.ok, f"recv-operand composite completion: {r.completion}"
|
||||
Reference in New Issue
Block a user