From be6d5383517d0451170ff183ba528d39355a6fb3 Mon Sep 17 00:00:00 2001 From: qazal <77887910+Qazalin@users.noreply.github.com> Date: Wed, 10 Dec 2025 07:16:42 -0500 Subject: [PATCH] viz: add kernel walltime to pmc scoreboard (#13638) * viz: add kernel walltime to pmc scoreboard * fix typing * tiny TracingKey refactor * key on kernel name --- tinygrad/viz/js/index.js | 2 +- tinygrad/viz/serve.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tinygrad/viz/js/index.js b/tinygrad/viz/js/index.js index 01d0e9296f..82cd76cd98 100644 --- a/tinygrad/viz/js/index.js +++ b/tinygrad/viz/js/index.js @@ -787,7 +787,7 @@ async function main() { } const td = tr.append("td").classed(ret.cols[i], true); // string format scalar values - if (!Array.isArray(value)) { td.text(typeof value === "string" ? value : formatUnit(value)); continue; } + if (!Array.isArray(value)) { td.text(typeof value === "string" ? value : ret.cols[i] === "Duration" ? formatMicroseconds(value) : formatUnit(value)); continue; } // display arrays in a bar graph td.classed("pct-row", true); const bar = td.append("div"); diff --git a/tinygrad/viz/serve.py b/tinygrad/viz/serve.py index 093b011535..eb5dcf60e6 100755 --- a/tinygrad/viz/serve.py +++ b/tinygrad/viz/serve.py @@ -223,8 +223,11 @@ def row_tuple(row:str) -> tuple[int, ...]: return tuple(int(x.split(":")[1]) for def load_sqtt(profile:list[ProfileEvent]) -> None: from tinygrad.runtime.ops_amd import ProfileSQTTEvent, ProfilePMCEvent counter_events:dict[tuple[str, int], list[ProfileSQTTEvent|ProfilePMCEvent]] = {} + durations:dict[str, list[float]] = {} for e in profile: if isinstance(e, (ProfilePMCEvent, ProfileSQTTEvent)): counter_events.setdefault((e.kern, e.exec_tag), []).append(e) + if isinstance(e, ProfileRangeEvent) and e.device.startswith("AMD") and e.en is not None: + durations.setdefault(str(e.name), []).append(float(e.en-e.st)) if not counter_events: return # ** init decoder from extra.sqtt.roc import decode @@ -281,7 +284,7 @@ def load_sqtt(profile:list[ProfileEvent]) -> None: ptr += 1 rows.append(row) steps.append(create_step("PMC", ("/pmc", len(ctxs), len(steps)), {"rows":rows, "cols":agg_cols}, depth=1)) - all_runs["rows"].append((key[0], *[r[1] for r in rows])) + all_runs["rows"].append((key[0], durations[key[0]].pop(0), *[r[1] for r in rows])) for cu in prg_cu: events = [ProfilePointEvent(unit, "start", unit, ts=Decimal(0)) for unit in units]+cu_events[cu] steps.append(create_step(f"{cu} {len(cu_events[cu])}", ("/counters", len(ctxs), len(steps)), @@ -289,7 +292,7 @@ def load_sqtt(profile:list[ProfileEvent]) -> None: for k in sorted(wave_insts.get(cu, []), key=row_tuple): data = wave_insts[cu][k] steps.append(create_step(k.replace(cu, ""), ("/sqtt-insts", len(ctxs), len(steps)), data, loc=data["loc"], depth=2)) - all_runs["cols"] = ["Kernel", *all_runs["cols"]] + all_runs["cols"] = ["Kernel", "Duration", *all_runs["cols"]] ctxs.append({"name":"Counters", "steps":steps}) def device_sort_fn(k:str) -> tuple[int, str, int]: