File size: 5,046 Bytes
58ba6df | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | """MANO head (M = 1 tile) ops: DRAM-sharded matmuls, width-sharded LN, vs the current minimal_matmul / 1-core LN."""
from common import *
dev = open_dev()
torch.manual_seed(0)
L1 = ttnn.L1_MEMORY_CONFIG
DR = ttnn.DRAM_MEMORY_CONFIG
nb = dev.dram_grid_size().x
def rep(tag, fn, ref=None, n=None):
try:
o = fn(); ot = ttnn.to_torch(o).float()
if n: ot = ot[..., :n]
p = pcc(ot[..., :1, :], ref[..., :1, :]) if ref is not None else float('nan')
us = time_op(dev, fn)
print(f"{tag:70s} {us:8.1f} us pcc={p:.5f}", flush=True)
except Exception as e:
print(f"{tag:70s} FAIL {str(e).splitlines()[0][:200]}", flush=True)
ck = ttnn.init_device_compute_kernel_config(dev.arch(), math_fidelity=ttnn.MathFidelity.HiFi2, fp32_dest_acc_en=False, packer_l1_acc=True)
ck4 = ttnn.init_device_compute_kernel_config(dev.arch(), math_fidelity=ttnn.MathFidelity.HiFi4, fp32_dest_acc_en=True, packer_l1_acc=True)
def wsh(ncores, width):
cg = ttnn.num_cores_to_corerangeset(ncores, ttnn.CoreCoord(12, 10), row_wise=True)
return ttnn.MemoryConfig(ttnn.TensorMemoryLayout.WIDTH_SHARDED, ttnn.BufferType.L1, ttnn.ShardSpec(cg, [32, width // ncores], ttnn.ShardOrientation.ROW_MAJOR))
for K, N in [(1024, 512), (512, 1024), (1024, 1024), (1024, 128)]:
x_t = torch.randn(1, 1, 32, K); w_t = torch.randn(K, N) / K ** .5; b_t = torch.randn(1, 1, 1, N) * .1
ref = x_t @ w_t + b_t
xi = ttnn.from_torch(x_t, dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT, device=dev, memory_config=DR)
wi = ttnn.from_torch(w_t, dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT, device=dev)
b = ttnn.from_torch(b_t, dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT, device=dev)
cfg = ttnn.MinimalMatmulConfig(compute_with_storage_grid_size=ttnn.CoreCoord(12, 10), M_block_size=1, K_block_size=8, N_block_size=4, subblock_h=1, subblock_w=4)
rep(f"K{K} N{N} minimal_matmul (current)", lambda: ttnn.experimental.minimal_matmul(xi, wi, bias_tensor=b, config=cfg, compute_kernel_config=ck), ref)
rep(f"K{K} N{N} linear default", lambda: ttnn.linear(xi, wi, bias=b, compute_kernel_config=ck), ref)
Np = -(-N // (32 * nb)) * 32 * nb
for wd, wn in [(ttnn.bfloat16, "bf16"), (ttnn.bfloat8_b, "bfp8")]:
grid = ttnn.CoreRangeSet({ttnn.CoreRange(ttnn.CoreCoord(0, 0), ttnn.CoreCoord(nb - 1, 0))})
wmc = ttnn.MemoryConfig(ttnn.TensorMemoryLayout.WIDTH_SHARDED, ttnn.BufferType.DRAM, ttnn.ShardSpec(grid, [K, Np // nb], ttnn.ShardOrientation.ROW_MAJOR))
w = ttnn.from_torch(torch.nn.functional.pad(w_t, (0, Np - N)), dtype=wd, layout=ttnn.TILE_LAYOUT, device=dev, memory_config=wmc)
bp = ttnn.from_torch(torch.nn.functional.pad(b_t, (0, Np - N)), dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT, device=dev)
for nc in [8, 16, 32]:
if (K // 32) % nc or (Np // 32) % nc:
continue
xs = ttnn.to_memory_config(xi, wsh(nc, K))
for ibw in sorted({K // 32 // nc, max(1, K // 32 // nc // 2)}):
pc = ttnn.MatmulMultiCoreReuseMultiCastDRAMShardedProgramConfig(in0_block_w=ibw, per_core_M=1, per_core_N=Np // 32 // nc, fused_activation=None)
for ckn, c in [("HiFi2", ck), ("HiFi4fp32", ck4)]:
rep(f"K{K} N{N} dram-sharded w={wn} cores{nc} ibw{ibw} {ckn}", lambda pc=pc, xs=xs, c=c, nc=nc: ttnn.linear(xs, w, bias=bp, program_config=pc, memory_config=wsh(nc, Np), compute_kernel_config=c), ref, n=N)
# LayerNorm [32,1024]
x_t = torch.randn(1, 1, 32, 1024); g_t = 1 + .1 * torch.randn(1024); bt = .1 * torch.randn(1024)
ref = torch.nn.functional.layer_norm(x_t, (1024,), g_t, bt, 1e-5)
xi = ttnn.from_torch(x_t, dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT, device=dev, memory_config=DR)
g = ttnn.from_torch(g_t.reshape(1, 1, 1, -1), dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT, device=dev)
bb = ttnn.from_torch(bt.reshape(1, 1, 1, -1), dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT, device=dev)
rep("LN [32,1024] interleaved DRAM (current)", lambda: ttnn.layer_norm(xi, weight=g, bias=bb, epsilon=1e-5), ref)
gw = ttnn.from_torch(g_t.reshape(1, 1, -1, 32), dtype=ttnn.bfloat16, layout=ttnn.ROW_MAJOR_LAYOUT, device=dev)
bw = ttnn.from_torch(bt.reshape(1, 1, -1, 32), dtype=ttnn.bfloat16, layout=ttnn.ROW_MAJOR_LAYOUT, device=dev)
for nc in [4, 8, 16, 32]:
mc = wsh(nc, 1024)
xs = ttnn.to_memory_config(xi, mc)
pc = ttnn.LayerNormShardedMultiCoreProgramConfig(compute_with_storage_grid_size=(12, 10), subblock_w=32 // nc, block_h=1, block_w=32 // nc, inplace=False)
rep(f"LN width-sharded {nc} cores", lambda xs=xs, pc=pc, mc=mc: ttnn.layer_norm(xs, weight=gw, bias=bw, epsilon=1e-5, memory_config=mc, program_config=pc), ref)
# residual add width-sharded
mc = wsh(8, 1024)
a = ttnn.to_memory_config(xi, mc)
rep("add width-sharded 8 cores [32,1024]", lambda: ttnn.add(a, a, memory_config=mc), x_t * 2)
rep("add interleaved DRAM [32,1024]", lambda: ttnn.add(xi, xi), x_t * 2)
rep("i2s [32,1024] -> 8 cores", lambda: ttnn.to_memory_config(xi, mc), x_t)
ttnn.close_device(dev)
|