diff --git a/tinygrad/viz/js/index.js b/tinygrad/viz/js/index.js index 74f3e1d5e5..5209fd6c2e 100644 --- a/tinygrad/viz/js/index.js +++ b/tinygrad/viz/js/index.js @@ -208,7 +208,7 @@ async function renderProfiler(path, unit) { // support non realtime x axis units const formatTime = unit === "realtime" ? formatMicroseconds : (s) => `${s} ${unit}`; const profiler = d3.select("#profiler").html(""); - const buf = await (await fetch(path)).arrayBuffer(); + const buf = cache[path] ?? await fetchValue(path); const view = new DataView(buf); let offset = 0; const u8 = () => { const ret = view.getUint8(offset); offset += 1; return ret; } @@ -593,6 +593,11 @@ hljs.registerLanguage("cpp", (hljs) => ({ contains: [{ begin: '\\b(?:float|half)[0-9]+\\b', className: 'type' }, ...hljs.getLanguage('cpp').contains] })); +async function fetchValue(path) { + const res = await fetch(path); + return (await (res.headers.get("content-type") === "application/json" ? res.json() : res.arrayBuffer())); +} + var ret = []; var cache = {}; var ctxs = null; @@ -650,7 +655,7 @@ async function main() { // ** left sidebar context list if (ctxs == null) { ctxs = [{ name:"Profiler", steps:[] }]; - for (const r of (await (await fetch("/ctxs")).json())) ctxs.push(r); + for (const r of await fetchValue("/ctxs")) ctxs.push(r); const ctxList = document.querySelector(".ctx-list"); for (const [i,{name, steps}] of ctxs.entries()) { const ul = ctxList.appendChild(document.createElement("ul")); @@ -703,8 +708,8 @@ async function main() { } // ** Disassembly view if (ckey.startsWith("/render")) { - if (step.fmt === "timeline") return renderProfiler(ckey, "clk"); // cycles on the x axis - if (!(ckey in cache)) cache[ckey] = ret = await (await fetch(ckey)).json(); + if (!(ckey in cache)) cache[ckey] = ret = await fetchValue(ckey); + if (ret instanceof ArrayBuffer) return renderProfiler(ckey, "clk"); // cycles on the x axis displaySelection("#custom"); metadata.innerHTML = ""; const root = d3.create("div").classed("raw-text", true).node(); diff --git a/tinygrad/viz/serve.py b/tinygrad/viz/serve.py index ed1aed51f2..cdf31c395f 100755 --- a/tinygrad/viz/serve.py +++ b/tinygrad/viz/serve.py @@ -219,8 +219,7 @@ def load_sqtt(profile:list[ProfileEvent]) -> None: for name,waves in rctx.inst_execs.items(): events:list[ProfileEvent] = [] prg = trace.keys[r].ret if (r:=ref_map.get(name)) else None - steps.append(first:={"name":prg.name if prg is not None else name, "query":f"/render?ctx={len(ctxs)}&step={len(steps)}&fmt=counters", - "depth":0, "fmt":"timeline"}) + steps.append(first:={"name":prg.name if prg is not None else name, "query":f"/render?ctx={len(ctxs)}&step={len(steps)}&fmt=counters", "depth":0}) # Idle: The total time gap between the completion of previous instruction and the beginning of the current instruction. # The idle time can be caused by: