Cube-view: HBM pseudo channel ports on edges, UCIe flush to cube border
- HBM pseudo channel ports split to top/bottom edges of HBM zone (32 ports each, 8 per PE, color-coded) - PE→HBM lines connect router to its port group center - Per-PE label: "PE0×8ch" with BW annotation - UCIe blocks flush against cube edges at router positions - UCIe blocks smaller (22×10px) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -468,29 +468,52 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
|
||||
f'Total BW: {total_ch * channel_bw:.0f} GB/s</text>'
|
||||
)
|
||||
|
||||
# ── Pseudo channel port indicators (horizontal bar inside HBM zone) ──
|
||||
port_bar_y = hcy + 15
|
||||
port_bar_w = 8.0 * scale # slightly narrower than HBM zone
|
||||
port_bar_x = hcx - port_bar_w / 2
|
||||
port_w = port_bar_w / total_ch
|
||||
for i in range(total_ch):
|
||||
pe_owner = i // channels_per_pe
|
||||
# Color by PE owner
|
||||
colors = ["#3b82f6", "#60a5fa", "#8b5cf6", "#a78bfa",
|
||||
"#f59e0b", "#fbbf24", "#ef4444", "#f87171"]
|
||||
c = colors[pe_owner % len(colors)]
|
||||
px = port_bar_x + i * port_w
|
||||
parts.append(
|
||||
f' <rect x="{px:.1f}" y="{port_bar_y:.0f}" '
|
||||
f'width="{max(port_w - 0.5, 1):.1f}" height="8" '
|
||||
f'fill="{c}" opacity="0.7"/>'
|
||||
)
|
||||
# Port bar label
|
||||
parts.append(
|
||||
f' <text x="{hcx:.0f}" y="{port_bar_y + 20:.0f}" text-anchor="middle" '
|
||||
f'font-family="monospace" font-size="7" fill="#05966988">'
|
||||
f'{total_ch} ports | {channels_per_pe} per PE (color-coded)</text>'
|
||||
)
|
||||
# ── Pseudo channel ports on HBM top/bottom edges ──
|
||||
# Top edge: 32 ports (PE0..PE3, 8 each), Bottom edge: 32 ports (PE4..PE7)
|
||||
half_ch = total_ch // 2
|
||||
pes_per_half = half_ch // channels_per_pe # 4 PEs per half
|
||||
port_bar_w = hbm_w - 20 # slightly narrower than HBM zone
|
||||
port_w = port_bar_w / half_ch
|
||||
port_h = 8
|
||||
pe_colors = ["#3b82f6", "#60a5fa", "#8b5cf6", "#a78bfa",
|
||||
"#f59e0b", "#fbbf24", "#ef4444", "#f87171"]
|
||||
|
||||
for half_idx, (edge_y, pe_start) in enumerate([
|
||||
(hbm_y + 4, 0), # top edge, PE0-PE3
|
||||
(hbm_y + hbm_h - port_h - 4, pes_per_half), # bottom edge, PE4-PE7
|
||||
]):
|
||||
bar_x = hbm_x + 10
|
||||
for i in range(half_ch):
|
||||
pe_owner = pe_start + i // channels_per_pe
|
||||
c = pe_colors[pe_owner % len(pe_colors)]
|
||||
px = bar_x + i * port_w
|
||||
parts.append(
|
||||
f' <rect x="{px:.1f}" y="{edge_y:.0f}" '
|
||||
f'width="{max(port_w - 0.5, 1):.1f}" height="{port_h}" '
|
||||
f'rx="1" fill="{c}" opacity="0.8"/>'
|
||||
)
|
||||
# Per-PE group labels
|
||||
for p in range(pes_per_half):
|
||||
gx = bar_x + (p * channels_per_pe + channels_per_pe / 2) * port_w
|
||||
label_y = edge_y - 3 if half_idx == 0 else edge_y + port_h + 8
|
||||
parts.append(
|
||||
f' <text x="{gx:.0f}" y="{label_y:.0f}" text-anchor="middle" '
|
||||
f'font-family="monospace" font-size="6" fill="{pe_colors[(pe_start + p) % len(pe_colors)]}">'
|
||||
f'PE{pe_start + p}×{channels_per_pe}ch</text>'
|
||||
)
|
||||
|
||||
# Store port group centers for PE→HBM connection lines (used later)
|
||||
_pe_hbm_targets: dict[int, tuple[float, float]] = {}
|
||||
for half_idx, (edge_y, pe_start) in enumerate([
|
||||
(hbm_y + 4, 0),
|
||||
(hbm_y + hbm_h - port_h - 4, pes_per_half),
|
||||
]):
|
||||
bar_x = hbm_x + 10
|
||||
for p in range(pes_per_half):
|
||||
pe_id = pe_start + p
|
||||
gx = bar_x + (p * channels_per_pe + channels_per_pe / 2) * port_w
|
||||
gy = edge_y if half_idx == 0 else edge_y + port_h
|
||||
_pe_hbm_targets[pe_id] = (gx, gy)
|
||||
|
||||
# ── Router mesh links ──
|
||||
for r in range(n_rows):
|
||||
@@ -589,20 +612,27 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
|
||||
offset_x = (bi - (len(blocks) - 1) / 2) * (blk_w + 4)
|
||||
|
||||
if kind == "ucie":
|
||||
# UCIe: place at cube edge direction
|
||||
# UCIe: place flush against cube edge at router position
|
||||
direction = label.split("-")[1].split(".")[0] if "-" in label else ""
|
||||
ucie_w, ucie_h = 22, 10 # smaller blocks for UCIe ports
|
||||
if direction == "N":
|
||||
bx, by = px + offset_x - blk_w / 2, pad - blk_h - 4
|
||||
bx = px - ucie_w / 2
|
||||
by = pad - ucie_h # flush against top edge
|
||||
blk_w, blk_h = ucie_w, ucie_h
|
||||
elif direction == "S":
|
||||
by_base = pad + cube_h * scale
|
||||
bx, by = px + offset_x - blk_w / 2, by_base + 4
|
||||
bx = px - ucie_w / 2
|
||||
by = pad + cube_h * scale # flush against bottom edge
|
||||
blk_w, blk_h = ucie_w, ucie_h
|
||||
elif direction == "W":
|
||||
bx, by = pad - blk_w - 4, py + offset_x - blk_h / 2
|
||||
bx = pad - ucie_w # flush against left edge
|
||||
by = py - ucie_h / 2
|
||||
blk_w, blk_h = ucie_w, ucie_h
|
||||
elif direction == "E":
|
||||
bx_base = pad + cube_w * scale
|
||||
bx, by = bx_base + 4, py + offset_x - blk_h / 2
|
||||
bx = pad + cube_w * scale # flush against right edge
|
||||
by = py - ucie_h / 2
|
||||
blk_w, blk_h = ucie_w, ucie_h
|
||||
else:
|
||||
bx, by = px + offset_x - blk_w / 2, py - r_size - blk_h - 4
|
||||
bx, by = px - blk_w / 2, py - r_size - blk_h - 4
|
||||
elif kind in ("mcpu", "sram"):
|
||||
# M_CPU/SRAM: place to the left of router (avoid mesh overlap)
|
||||
bx = px - r_size - blk_w - 6
|
||||
@@ -672,40 +702,38 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
|
||||
f'stroke="{style["stroke"]}" stroke-width="1" opacity="0.6"/>'
|
||||
)
|
||||
|
||||
# ── PE router → HBM BW annotation ──
|
||||
if pe_items:
|
||||
pe_hbm_edge = hbm_y if py < hbm_y else hbm_y + hbm_h
|
||||
pe_r_edge = py + r_size if py < hbm_y else py - r_size
|
||||
bw_x = px + 14
|
||||
bw_y = (pe_r_edge + pe_hbm_edge) / 2
|
||||
parts.append(
|
||||
f' <text x="{bw_x:.0f}" y="{bw_y:.0f}" '
|
||||
f'font-family="monospace" font-size="6" fill="#10b98188">'
|
||||
f'{agg_bw:.0f}GB/s</text>'
|
||||
)
|
||||
# (PE→HBM BW annotation drawn in the PE→HBM port group section above)
|
||||
|
||||
# ── Router → HBM_CTRL lines (drawn last, on top of everything) ──
|
||||
# Lines go from router to the HBM zone edge, angled toward HBM center
|
||||
# to visually distinguish from vertical mesh links
|
||||
# ── PE Router → HBM pseudo channel port group lines ──
|
||||
# Each PE router connects to its port group center on the HBM edge
|
||||
for rkey, rval in routers.items():
|
||||
if rval is None:
|
||||
continue
|
||||
attach = rval.get("attach", [])
|
||||
pe_dma_items = [a for a in attach if a.endswith(".dma")]
|
||||
if not pe_dma_items:
|
||||
continue
|
||||
pe_id = int(pe_dma_items[0].split(".")[0].replace("pe", ""))
|
||||
if pe_id not in _pe_hbm_targets:
|
||||
continue
|
||||
rx, ry = rval["pos_mm"]
|
||||
px, py = mm2px(rx, ry)
|
||||
hbm_edge_y = hbm_y if py < hbm_y else hbm_y + hbm_h
|
||||
r_edge_y = py + r_size if py < hbm_y else py - r_size
|
||||
if abs(r_edge_y - hbm_edge_y) > 10:
|
||||
has_pe = any(a.endswith(".dma") for a in rval.get("attach", []))
|
||||
sw = "1.5" if has_pe else "0.7"
|
||||
op = "0.6" if has_pe else "0.15"
|
||||
# Angle toward HBM center x (hcx) — slight offset, not fully straight
|
||||
dx = (hcx - px) * 0.3 # 30% pull toward center
|
||||
parts.append(
|
||||
f' <line x1="{px:.0f}" y1="{r_edge_y:.0f}" '
|
||||
f'x2="{px + dx:.0f}" y2="{hbm_edge_y:.0f}" '
|
||||
f'stroke="#10b981" stroke-width="{sw}" opacity="{op}" '
|
||||
f'stroke-dasharray="4,3"/>'
|
||||
)
|
||||
rpx, rpy = mm2px(rx, ry)
|
||||
tgx, tgy = _pe_hbm_targets[pe_id]
|
||||
r_edge_y = rpy + r_size if rpy < hbm_y else rpy - r_size
|
||||
parts.append(
|
||||
f' <line x1="{rpx:.0f}" y1="{r_edge_y:.0f}" '
|
||||
f'x2="{tgx:.0f}" y2="{tgy:.0f}" '
|
||||
f'stroke="#10b981" stroke-width="1.5" opacity="0.6" '
|
||||
f'stroke-dasharray="4,3"/>'
|
||||
)
|
||||
# BW annotation at midpoint
|
||||
mx = (rpx + tgx) / 2 + 10
|
||||
my = (r_edge_y + tgy) / 2
|
||||
parts.append(
|
||||
f' <text x="{mx:.0f}" y="{my:.0f}" '
|
||||
f'font-family="monospace" font-size="6" fill="#10b98188">'
|
||||
f'{agg_bw:.0f}GB/s</text>'
|
||||
)
|
||||
|
||||
# ── Legend ──
|
||||
ly = h_px - 35
|
||||
|
||||
Reference in New Issue
Block a user