From 624161f52f6bd5d30f7a4ce022091a7215233e92 Mon Sep 17 00:00:00 2001 From: Yangwook Kang Date: Sat, 4 Apr 2026 17:56:05 -0700 Subject: [PATCH] Update web viewer for router mesh topology (ADR-0019) Remove all xbar/bridge rendering from cube detail view. Replace 8 HBM slices with single HBM_CTRL block. Add green dotted lines showing router-to-HBM connectivity. Update legend, event animation, and PE view NOC destinations. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/kernbench/web/static/index.html | 271 ++++++---------------------- 1 file changed, 56 insertions(+), 215 deletions(-) diff --git a/src/kernbench/web/static/index.html b/src/kernbench/web/static/index.html index 315ed23..3255efa 100644 --- a/src/kernbench/web/static/index.html +++ b/src/kernbench/web/static/index.html @@ -26,8 +26,8 @@ --pe-stroke: #a855f7; --io-fill: #3d2b1f; --io-stroke: #f97316; - --xbar-fill: #1f2d3d; - --xbar-stroke: #06b6d4; + --router-fill: #1f2d3d; + --router-stroke: #06b6d4; --link-color: #475569; --link-active: #3b82f6; } @@ -405,8 +405,8 @@ body { PE
-
- XBAR / NOC +
+ Router Mesh
@@ -716,7 +716,7 @@ function drawCubeNode(svg, x, y, idx) { g.appendChild(pt); } - // Center block: xbar + NOC + // Center block: router mesh g.appendChild(svgEl("rect", { x: x + 30, y: y + 30, width: CUBE_W - 60, height: CUBE_H - 56, rx: 3, fill: "#1f2d3d", stroke: "#06b6d466", "stroke-width": 0.8 @@ -728,7 +728,7 @@ function drawCubeNode(svg, x, y, idx) { "font-size": "7", fill: "#06b6d4aa" }); - xt.textContent = "NOC+XBAR"; + xt.textContent = "Router Mesh"; g.appendChild(xt); // HBM indicators (top and bottom) @@ -871,51 +871,6 @@ function drawCubeView(svg, cubeIdx) { } } - // ── PE router → XBAR_TOP paths (90-degree angled, matching reference) ── - // r0c0 → XBAR_TOP left: down then right - const xbarTopY = OY + 145; // reference: rect at y=145 - const xbarBotY = OY + 355; // reference: rect at y=355 - const xbarX = OX + 150; // reference: x=150 - const xbarW = 400; // reference: width=400 - - svg.appendChild(svgEl("path", { - d: `M ${OX} ${OY+16} V ${xbarTopY+6} H ${xbarX}`, - fill: "none", stroke: "#f97316", "stroke-width": 1.5, "stroke-dasharray": "4,3" - })); - svg.appendChild(svgEl("path", { - d: `M ${OX+140} ${OY+16} V ${xbarTopY} H ${xbarX}`, - fill: "none", stroke: "#f97316", "stroke-width": 1.5, "stroke-dasharray": "4,3" - })); - svg.appendChild(svgEl("path", { - d: `M ${OX+560} ${OY+107} V ${xbarTopY} H ${xbarX+xbarW}`, - fill: "none", stroke: "#f97316", "stroke-width": 1.5, "stroke-dasharray": "4,3" - })); - svg.appendChild(svgEl("path", { - d: `M ${OX+700} ${OY+107} V ${xbarTopY+6} H ${xbarX+xbarW}`, - fill: "none", stroke: "#f97316", "stroke-width": 1.5, "stroke-dasharray": "4,3" - })); - - // ── XBAR_TOP bar ── - svg.appendChild(svgEl("rect", { - x: xbarX, y: xbarTopY, width: xbarW, height: 22, - rx: 5, fill: "#f97316", stroke: "#ea580c", "stroke-width": 2 - })); - const xtT = svgEl("text", { - x: xbarX + xbarW / 2, y: xbarTopY + 15, "text-anchor": "middle", - "font-family": "monospace", "font-size": "9", "font-weight": "bold", fill: "white" - }); - xtT.textContent = "XBAR_TOP | xbar_v1 | 2.0ns"; - svg.appendChild(xtT); - - // ── XBAR_TOP → HBM0-3 arrows ── - const hbmArrowXs = [OX + 225, OX + 320, OX + 415, OX + 475]; - for (const ax of hbmArrowXs) { - svg.appendChild(svgEl("line", { - x1: ax, y1: xbarTopY + 22, x2: ax, y2: OY + 198, - stroke: "#059669", "stroke-width": 1.5 - })); - } - // ── HBM ZONE ── const hbmZoneX = OX + 145, hbmZoneY = OY + 195, hbmZoneW = 410, hbmZoneH = 152; svg.appendChild(svgEl("rect", { @@ -926,181 +881,71 @@ function drawCubeView(svg, cubeIdx) { x: hbmZoneX + hbmZoneW / 2, y: hbmZoneY + 16, "text-anchor": "middle", "font-family": "monospace", "font-size": "9", "font-weight": "bold", fill: "#047857" }); - hzmLabel.textContent = "HBM 9.0 x 5.0 mm | hbm_ctrl_v1 x 8"; + hzmLabel.textContent = "HBM 9.0 x 5.0 mm | hbm_ctrl_v1"; svg.appendChild(hzmLabel); - // HBM0-3 (top row) - const hbmSliceW = 85, hbmSliceH = 28; - const hbmTopSlices = [ - { x: OX + 168, label: "HBM0" }, { x: OX + 260, label: "HBM1" }, - { x: OX + 352, label: "HBM2" }, { x: OX + 444, label: "HBM3" } - ]; - for (const hs of hbmTopSlices) { - const g = svgEl("g", { class: "node-group", "data-id": hs.label.toLowerCase() }); - g.appendChild(svgEl("rect", { - x: hs.x, y: hbmZoneY + 23, width: hbmSliceW, height: hbmSliceH, - rx: 4, fill: "#047857", stroke: "#065f46", "stroke-width": 1.5 - })); - const t = svgEl("text", { - x: hs.x + hbmSliceW / 2, y: hbmZoneY + 23 + 18, "text-anchor": "middle", - "font-family": "monospace", "font-size": "8", "font-weight": "bold", fill: "white" - }); - t.textContent = hs.label; - g.appendChild(t); - svg.appendChild(g); - } + // Single HBM_CTRL block (centered in HBM zone) + const hbmCtrlG = svgEl("g", { class: "node-group", "data-id": "hbm_ctrl" }); + hbmCtrlG.appendChild(svgEl("rect", { + x: hbmZoneX + 40, y: hbmZoneY + 28, width: hbmZoneW - 80, height: 40, + rx: 6, fill: "#047857", stroke: "#065f46", "stroke-width": 1.5 + })); + const hbmCtrlT = svgEl("text", { + x: hbmZoneX + hbmZoneW / 2, y: hbmZoneY + 53, "text-anchor": "middle", + "font-family": "monospace", "font-size": "10", "font-weight": "bold", fill: "white" + }); + hbmCtrlT.textContent = "HBM_CTRL"; + hbmCtrlG.appendChild(hbmCtrlT); + svg.appendChild(hbmCtrlG); // Exclusion zone label const hexLabel = svgEl("text", { - x: hbmZoneX + hbmZoneW / 2, y: hbmZoneY + 75, "text-anchor": "middle", + x: hbmZoneX + hbmZoneW / 2, y: hbmZoneY + 85, "text-anchor": "middle", "font-family": "monospace", "font-size": "7", fill: "#ef4444aa" }); hexLabel.textContent = "Router exclusion: r2c2, r2c3, r3c2, r3c3"; svg.appendChild(hexLabel); - // HBM4-7 (bottom row) - const hbmBotSlices = [ - { x: OX + 168, label: "HBM4" }, { x: OX + 260, label: "HBM5" }, - { x: OX + 352, label: "HBM6" }, { x: OX + 444, label: "HBM7" } + // "All routers connect to HBM" annotation + const hbmAnnot = svgEl("text", { + x: hbmZoneX + hbmZoneW / 2, y: hbmZoneY + 100, "text-anchor": "middle", + "font-family": "monospace", "font-size": "6", fill: "#059669aa" + }); + hbmAnnot.textContent = "All routers → HBM_CTRL (mesh-connected)"; + svg.appendChild(hbmAnnot); + + // ── HBM connectivity indicators (thin green dotted lines from edge routers to HBM zone) ── + // Draw thin green dotted lines from routers adjacent to HBM zone down/up to HBM + const hbmConnRouters = [ + { r: 1, c: 2 }, { r: 1, c: 3 }, // top edge of HBM zone + { r: 4, c: 2 }, { r: 4, c: 3 }, // bottom edge of HBM zone + { r: 2, c: 1 }, { r: 3, c: 1 }, // left edge of HBM zone + { r: 2, c: 4 }, { r: 3, c: 4 }, // right edge of HBM zone ]; - for (const hs of hbmBotSlices) { - const g = svgEl("g", { class: "node-group", "data-id": hs.label.toLowerCase() }); - g.appendChild(svgEl("rect", { - x: hs.x, y: hbmZoneY + hbmZoneH - hbmSliceH - 23 + 10, width: hbmSliceW, height: hbmSliceH, - rx: 4, fill: "#065f46", stroke: "#064e3b", "stroke-width": 1.5 - })); - const t = svgEl("text", { - x: hs.x + hbmSliceW / 2, y: hbmZoneY + hbmZoneH - hbmSliceH - 23 + 10 + 18, "text-anchor": "middle", - "font-family": "monospace", "font-size": "8", "font-weight": "bold", fill: "white" - }); - t.textContent = hs.label; - g.appendChild(t); - svg.appendChild(g); - } - - // ── XBAR_BOT → HBM4-7 arrows (upward) ── - for (const ax of hbmArrowXs) { + for (const hr of hbmConnRouters) { + const rp = rXY(hr.r, hr.c); + // Draw line toward the HBM zone center + const hbmCenterX = hbmZoneX + hbmZoneW / 2; + const hbmCenterY = hbmZoneY + hbmZoneH / 2; + // Compute endpoint clipped to HBM zone edge + let ex = hbmCenterX, ey = hbmCenterY; + if (hr.r <= 1) { ey = hbmZoneY; ex = rp.x; } // top routers → top of HBM zone + else if (hr.r >= 4) { ey = hbmZoneY + hbmZoneH; ex = rp.x; } // bottom routers → bottom of HBM zone + else if (hr.c <= 1) { ex = hbmZoneX; ey = rp.y; } // left routers → left of HBM zone + else { ex = hbmZoneX + hbmZoneW; ey = rp.y; } // right routers → right of HBM zone svg.appendChild(svgEl("line", { - x1: ax, y1: xbarBotY, x2: ax, y2: OY + 315, - stroke: "#059669", "stroke-width": 1.5 + x1: rp.x, y1: rp.y, x2: ex, y2: ey, + stroke: "#05966988", "stroke-width": 1, "stroke-dasharray": "3,3" })); } - // ── XBAR_BOT bar ── - svg.appendChild(svgEl("rect", { - x: xbarX, y: xbarBotY, width: xbarW, height: 22, - rx: 5, fill: "#f97316", stroke: "#ea580c", "stroke-width": 2 - })); - const xbT = svgEl("text", { - x: xbarX + xbarW / 2, y: xbarBotY + 15, "text-anchor": "middle", - "font-family": "monospace", "font-size": "9", "font-weight": "bold", fill: "white" - }); - xbT.textContent = "XBAR_BOT | xbar_v1 | 2.0ns"; - svg.appendChild(xbT); - - // ── PE router → XBAR_BOT paths (90-degree angled) ── - svg.appendChild(svgEl("path", { - d: `M ${OX} ${OY+409} V ${xbarBotY+16} H ${xbarX}`, - fill: "none", stroke: "#f97316", "stroke-width": 1.5, "stroke-dasharray": "4,3" - })); - svg.appendChild(svgEl("path", { - d: `M ${OX+140} ${OY+409} V ${xbarBotY+10} H ${xbarX}`, - fill: "none", stroke: "#f97316", "stroke-width": 1.5, "stroke-dasharray": "4,3" - })); - svg.appendChild(svgEl("path", { - d: `M ${OX+560} ${OY+508} V ${xbarBotY+10} H ${xbarX+xbarW}`, - fill: "none", stroke: "#f97316", "stroke-width": 1.5, "stroke-dasharray": "4,3" - })); - svg.appendChild(svgEl("path", { - d: `M ${OX+700} ${OY+508} V ${xbarBotY+16} H ${xbarX+xbarW}`, - fill: "none", stroke: "#f97316", "stroke-width": 1.5, "stroke-dasharray": "4,3" - })); - - // ── BRIDGES (purple/violet, matching reference) ── - const brgLeftX = OX + 100, brgRightX = OX + 600; - // Left bridge vertical line - svg.appendChild(svgEl("line", { - x1: brgLeftX, y1: xbarTopY + 10, x2: brgLeftX, y2: xbarBotY + 12, - stroke: "#a78bfa", "stroke-width": 2.5, "stroke-dasharray": "8,4" - })); - // Left bridge horizontal stubs - svg.appendChild(svgEl("line", { - x1: brgLeftX, y1: xbarTopY + 6, x2: xbarX, y2: xbarTopY + 6, - stroke: "#a78bfa", "stroke-width": 2, "stroke-dasharray": "6,3" - })); - svg.appendChild(svgEl("line", { - x1: brgLeftX, y1: xbarBotY + 16, x2: xbarX, y2: xbarBotY + 16, - stroke: "#a78bfa", "stroke-width": 2, "stroke-dasharray": "6,3" - })); - // Left bridge label - svg.appendChild(svgEl("rect", { - x: brgLeftX - 28, y: OY + 248, width: 56, height: 30, - rx: 4, fill: "#1e1b4b", stroke: "#a78bfa", "stroke-width": 1.5 - })); - let bt = svgEl("text", { - x: brgLeftX, y: OY + 259, "text-anchor": "middle", - "font-family": "monospace", "font-size": "6", "font-weight": "bold", fill: "#a78bfa" - }); - bt.textContent = "XBAR BRG"; - svg.appendChild(bt); - bt = svgEl("text", { - x: brgLeftX, y: OY + 272, "text-anchor": "middle", - "font-family": "monospace", "font-size": "7", "font-weight": "bold", fill: "#a78bfa" - }); - bt.textContent = "LEFT"; - svg.appendChild(bt); - bt = svgEl("text", { - x: brgLeftX - 36, y: OY + 263, "text-anchor": "end", - "font-family": "monospace", "font-size": "6", fill: "#a78bfa88" - }); - bt.textContent = "3mm"; - svg.appendChild(bt); - - // Right bridge vertical line - svg.appendChild(svgEl("line", { - x1: brgRightX, y1: xbarTopY + 10, x2: brgRightX, y2: xbarBotY + 12, - stroke: "#a78bfa", "stroke-width": 2.5, "stroke-dasharray": "8,4" - })); - // Right bridge horizontal stubs - svg.appendChild(svgEl("line", { - x1: brgRightX, y1: xbarTopY + 6, x2: xbarX + xbarW, y2: xbarTopY + 6, - stroke: "#a78bfa", "stroke-width": 2, "stroke-dasharray": "6,3" - })); - svg.appendChild(svgEl("line", { - x1: brgRightX, y1: xbarBotY + 16, x2: xbarX + xbarW, y2: xbarBotY + 16, - stroke: "#a78bfa", "stroke-width": 2, "stroke-dasharray": "6,3" - })); - // Right bridge label - svg.appendChild(svgEl("rect", { - x: brgRightX - 28, y: OY + 248, width: 56, height: 30, - rx: 4, fill: "#1e1b4b", stroke: "#a78bfa", "stroke-width": 1.5 - })); - bt = svgEl("text", { - x: brgRightX, y: OY + 259, "text-anchor": "middle", - "font-family": "monospace", "font-size": "6", "font-weight": "bold", fill: "#a78bfa" - }); - bt.textContent = "XBAR BRG"; - svg.appendChild(bt); - bt = svgEl("text", { - x: brgRightX, y: OY + 272, "text-anchor": "middle", - "font-family": "monospace", "font-size": "7", "font-weight": "bold", fill: "#a78bfa" - }); - bt.textContent = "RIGHT"; - svg.appendChild(bt); - bt = svgEl("text", { - x: brgRightX + 36, y: OY + 263, - "font-family": "monospace", "font-size": "6", fill: "#a78bfa88" - }); - bt.textContent = "3mm"; - svg.appendChild(bt); - // ── M_CPU (r2c0) and SRAM (r3c0) labels ── const mcpuP = rXY(2, 0); svg.appendChild(svgEl("rect", { x: mcpuP.x - 42, y: mcpuP.y + 18, width: 84, height: 18, rx: 4, fill: "#f59e0b", stroke: "#d97706", "stroke-width": 1.5 })); - bt = svgEl("text", { + let bt = svgEl("text", { x: mcpuP.x, y: mcpuP.y + 31, "text-anchor": "middle", "font-family": "monospace", "font-size": "8", "font-weight": "bold", fill: "white" }); @@ -1358,8 +1203,7 @@ function drawCubeView(svg, cubeIdx) { { color: "#e2e8f0", label: "Relay", textColor: "#475569" }, { color: "#8b5cf6", label: "UCIe Router" }, { color: "#f59e0b", label: "M_CPU/SRAM" }, - { color: "#a78bfa", label: "Bridge", type: "line" }, - { color: "#f97316", label: "XBAR", type: "rect" }, + { color: "#059669", label: "HBM Link", type: "line" }, { color: "#047857", label: "HBM Ctrl", type: "rect" }, { color: "#ef4444", label: "PE (~5mm2)", type: "rect" }, { color: "#8b5cf6", label: "UCIe Port", type: "rect", rectFill: "#1e1b4b" }, @@ -1394,7 +1238,7 @@ function drawCubeView(svg, cubeIdx) { const dpT = svgEl("text", { x: 60, y: legY + 24, "font-family": "monospace", "font-size": "7", fill: "#64748b" }); - dpT.textContent = "Data: PE_DMA→NOC→XBAR→HBM | Cross-half: XBAR_TOP→Bridge(3mm)→XBAR_BOT→HBM4-7"; + dpT.textContent = "Data: PE_DMA → Router Mesh → HBM_CTRL | All traffic routed through 6x6 mesh"; svg.appendChild(dpT); } @@ -1454,7 +1298,7 @@ function drawPeView(svg, cubeIdx, peIdx) { // NOC destinations (inside NOC column) const nocDests = [ - { label: "XBAR", sub: "→ HBM", y: nocTop + 50, fill: "#f97316", bg: "#3d2b1f" }, + { label: "HBM", sub: "ctrl", y: nocTop + 50, fill: "#059669", bg: "#052e16" }, { label: "SRAM", sub: "128x4", y: nocTop + 86, fill: "#f59e0b", bg: "#3d2b1f" }, { label: "UCIe", sub: "inter", y: nocTop + 122, fill: "#8b5cf6", bg: "#1e1b4b" }, { label: "M_CPU", sub: "cmd", y: nocTop + 158, fill: "#f59e0b", bg: "#3d2b1f" }, @@ -1967,7 +1811,7 @@ function applyHotPaths(svg, t) { } } else if (currentView === "cube") { - // ── CUBE VIEW: highlight router mesh links + XBAR paths ── + // ── CUBE VIEW: highlight router mesh links ── const linkTraffic = {}; for (const hop of activeHops) { const linkId = hopToCubeLink(hop); @@ -1984,16 +1828,13 @@ function applyHotPaths(svg, t) { inflight++; } } - // Highlight XBAR/HBM components referenced in events + // Highlight HBM component referenced in events const activeProcesses = allEvents.filter(e => e.type === "process" && e.t_ns <= t && e.t_ns >= t - 30 ); for (const proc of activeProcesses) { const comp = proc.component || ""; - if (comp.includes("xbar_top")) highlightComponent(svg, "xbar_top"); - if (comp.includes("xbar_bot")) highlightComponent(svg, "xbar_bot"); - const hbmMatch = comp.match(/hbm_ctrl\.slice(\d+)/); - if (hbmMatch) highlightComponent(svg, `hbm${hbmMatch[1]}`); + if (comp.includes("hbm_ctrl")) highlightComponent(svg, "hbm_ctrl"); } } else if (currentView === "pe") {