From 3d610f6d2bf36e44cec3adc28a03161e78987ee4 Mon Sep 17 00:00:00 2001 From: qazal <77887910+Qazalin@users.noreply.github.com> Date: Thu, 10 Jul 2025 11:43:36 +0300 Subject: [PATCH] viz: small ui cleanup (#11157) * viz: small ui cleanup * 2 --- tinygrad/viz/js/index.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tinygrad/viz/js/index.js b/tinygrad/viz/js/index.js index 9149594d7f..fa38e4b202 100644 --- a/tinygrad/viz/js/index.js +++ b/tinygrad/viz/js/index.js @@ -1,9 +1,15 @@ -// **** graph renderers +// ** graph helpers const displayGraph = (cls) => { for (const e of document.getElementsByClassName("view")) e.style.display = e.classList.contains(cls) ? "flex" : "none"; } +const ANSI_COLORS = ["#b3b3b3", "#ff6666", "#66b366", "#ffff66", "#6666ff", "#ff66ff", "#66ffff", "#ffffff"]; +const parseColors = (name, defaultColor="#ffffff") => Array.from(name.matchAll(/(?:\u001b\[(\d+)m([\s\S]*?)\u001b\[0m)|([^\u001b]+)/g), + ([_, code, colored_st, st]) => ({ st: colored_st ?? st, color: code != null ? ANSI_COLORS[(parseInt(code)-30+60)%60] : defaultColor })); + +const rect = (s) => (typeof s === "string" ? document.querySelector(s) : s).getBoundingClientRect(); + // ** UOp graph function intersectRect(r1, r2) { @@ -16,8 +22,6 @@ function intersectRect(r1, r2) { return {x:r1.x+dx*scale, y:r1.y+dy*scale}; } -const rect = (s) => (typeof s === "string" ? document.querySelector(s) : s).getBoundingClientRect(); - let [workerUrl, worker, timeout] = [null, null, null]; async function renderDag(graph, additions, recenter=false) { // start calculating the new layout (non-blocking) @@ -95,10 +99,6 @@ async function renderDag(graph, additions, recenter=false) { } -const ANSI_COLORS = ["#b3b3b3", "#ff6666", "#66b366", "#ffff66", "#6666ff", "#ff66ff", "#66ffff", "#ffffff"]; -const parseColors = (name, defaultColor="#ffffff") => [...name.matchAll(/(?:\u001b\[(\d+)m([\s\S]*?)\u001b\[0m)|([^\u001b]+)/g)] - .map(([_, code, colored_st, st]) => ({ st: colored_st ?? st, color: code != null ? ANSI_COLORS[(parseInt(code)-30+60)%60] : defaultColor })); - // ** profiler graph function formatTime(ts, dur=ts) { @@ -126,8 +126,8 @@ async function renderProfiler() { deviceList.style.paddingTop = `${tickSize+padding}px`; const ctx = canvas.getContext("2d"); const { top:canvasTop, height:canvasHeight } = rect(canvas); - // color by name - const nameMap = new Map(); + // color by key (name/category/device) + const colorMap = new Map(); const data = {shapes:[], axes:{}}; for (const [k, { timeline, mem }] of Object.entries(layout)) { if (timeline.shapes.length === 0 && mem.shapes.length == 0) continue; @@ -142,14 +142,14 @@ async function renderProfiler() { const levelHeight = baseHeight-padding; const offsetY = baseY-canvasTop+padding/2; for (const [i,e] of timeline.shapes.entries()) { - const label = parseColors(e.name).map(({ color, st }) => ({ color, st, width:ctx.measureText(st).width })); const colorKey = e.cat ?? e.name; - if (!nameMap.has(colorKey)) { + if (!colorMap.has(colorKey)) { const colors = devColors[k] ?? devColors.DEFAULT; - nameMap.set(colorKey, { fillColor:colors[i%colors.length] }); + colorMap.set(colorKey, colors[i%colors.length]); } + const label = parseColors(e.name).map(({ color, st }) => ({ color, st, width:ctx.measureText(st).width })); // offset y by depth - data.shapes.push({ x:e.st-st, dur:e.dur, name:e.name, height:levelHeight, y:offsetY+levelHeight*e.depth, ref:e.ref, label, ...nameMap.get(colorKey) }); + data.shapes.push({x:e.st-st, dur:e.dur, height:levelHeight, y:offsetY+levelHeight*e.depth, ref:e.ref, label, fillColor:colorMap.get(colorKey)}); } // position shapes on the canvas and scale to fit fixed area const startY = offsetY+(levelHeight*timeline.maxDepth)+padding/2;