diff --git a/docs/diagrams/cube_view.svg b/docs/diagrams/cube_view.svg
index 605bf3b..24ae6da 100644
--- a/docs/diagrams/cube_view.svg
+++ b/docs/diagrams/cube_view.svg
@@ -135,12 +135,12 @@
r0c0
PE0
-
+
r0c1
PE1
-
+
r0c2
@@ -161,17 +161,17 @@
r1c4
PE2
-
+
r1c5
PE3
-
+
r2c0
-
- M_CPU
-
+
+ M_CPU
+
r2c1
@@ -180,9 +180,9 @@
r2c5
r3c0
-
- SRAM
-
+
+ SRAM
+
r3c1
@@ -193,12 +193,12 @@
r4c0
PE4
-
+
r4c1
PE5
-
+
r4c2
@@ -219,84 +219,84 @@
r5c4
PE6
-
+
r5c5
PE7
-
-
+
+
256GB/s
-
+
256GB/s
-
+
256GB/s
-
+
256GB/s
-
+
256GB/s
-
+
256GB/s
-
+
256GB/s
-
+
256GB/s
UCIe-W
c0
-
+
c1
-
+
c2
-
+
c3
-
+
UCIe-N
c0
-
+
c1
-
+
c2
-
+
c3
-
+
UCIe-E
c0
-
+
c1
-
+
c2
-
+
c3
-
+
UCIe-S
c0
-
+
c1
-
+
c2
-
+
c3
-
+
PE Router
diff --git a/src/kernbench/topology/visualizer.py b/src/kernbench/topology/visualizer.py
index 622c3fa..cd1e30b 100644
--- a/src/kernbench/topology/visualizer.py
+++ b/src/kernbench/topology/visualizer.py
@@ -607,10 +607,14 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
# Use left/right offset for multiple blocks on same router
offset_x = (bi - (len(blocks) - 1) / 2) * (blk_w + 4)
- if kind in ("mcpu", "sram"):
- # M_CPU/SRAM: place to the left of router (avoid mesh overlap)
- bx = px - r_size - blk_w - 6
- by = py - blk_h / 2 + bi * (blk_h + 2)
+ if kind == "mcpu":
+ # M_CPU: place above (north of) router
+ bx = px - blk_w / 2
+ by = py - r_size - blk_h - 8
+ elif kind == "sram":
+ # SRAM: place below (south of) router
+ bx = px - blk_w / 2
+ by = py + r_size + 8
else:
# PE: place above (top half) or below (bottom half)
bx = px + offset_x - blk_w / 2
@@ -632,50 +636,53 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
f'text-anchor="middle" font-family="monospace" font-size="{font_sz}" '
f'font-weight="bold" fill="{style["text"]}">{_escape(label)}'
)
- # Connector line: router → component (diagonal out from router, then straight)
+ # Connector: router ─45°─ straight ─45°─ component
sc = style["stroke"]
- if kind in ("mcpu", "sram"):
- # Router → 45° diagonal → horizontal to block
- x1 = bx + blk_w # block right edge
- y1 = by + blk_h / 2
- x2 = px - r_size # router left edge
- y2 = py
- dy = abs(y2 - y1)
- # From router: diagonal 45° toward block, then horizontal
- mid_x = x2 - dy # 45° means dx == dy
- if mid_x < x1:
- mid_x = x1
+ d = 6 # 45° stub length (px)
+ if kind == "mcpu":
+ # Router top → 45° NW stub → vertical → 45° into block bottom
+ rx2, ry2 = px, py - r_size
+ bxc, byc = bx + blk_w / 2, by + blk_h
parts.append(
- f' '
+ )
+ elif kind == "sram":
+ # Router bottom → 45° SW stub → vertical → 45° into block top
+ rx2, ry2 = px, py + r_size
+ bxc, byc = bx + blk_w / 2, by
+ parts.append(
+ f' '
)
else:
- # PE: Router → 45° diagonal → vertical to block
+ # PE: vertical direction
+ bxc = bx + blk_w / 2 + offset_x
if is_top:
- x1 = bx + blk_w / 2 + offset_x # block center
- y1 = by + blk_h # block bottom
- x2 = px # router center
- y2 = py - r_size # router top
- dx = abs(x2 - x1)
- # From router: 45° diagonal, then vertical to block
- mid_y = y2 - dx
- if mid_y < y1:
- mid_y = y1
+ rx2, ry2 = px, py - r_size # router top
+ byc = by + blk_h # block bottom
+ # 45° stub from router, vertical, 45° into block
+ sx = bxc - px # horizontal shift direction
+ sd = d if sx >= 0 else -d
parts.append(
- f' '
)
else:
- x1 = bx + blk_w / 2 + offset_x
- y1 = by # block top
- x2 = px
- y2 = py + r_size # router bottom
- dx = abs(x2 - x1)
- mid_y = y2 + dx
- if mid_y > y1:
- mid_y = y1
+ rx2, ry2 = px, py + r_size # router bottom
+ byc = by # block top
+ sx = bxc - px
+ sd = d if sx >= 0 else -d
parts.append(
- f' '
)
@@ -697,23 +704,26 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
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
- # From router: 45° diagonal toward HBM port, then vertical to port
- dx = abs(tgx - rpx)
+ # 45° stub from router → vertical → 45° into HBM port
+ d = 8 # stub length
+ sx = tgx - rpx
+ sd = d if sx >= 0 else -d
if rpy < hbm_y:
- # Top half: router bottom → 45° diagonal → vertical down to HBM top
- mid_y = r_edge_y + dx
- if mid_y > tgy:
- mid_y = tgy
+ parts.append(
+ f' '
+ )
else:
- # Bottom half: router top → 45° diagonal → vertical up to HBM bottom
- mid_y = r_edge_y - dx
- if mid_y < tgy:
- mid_y = tgy
- parts.append(
- f' '
- )
+ parts.append(
+ f' '
+ )
# BW annotation at midpoint
mx = (rpx + tgx) / 2 + 10
my = (r_edge_y + tgy) / 2
@@ -807,51 +817,51 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
f'{conn}'
)
- # Connector line: router → UCIe port (diagonal from router, then straight)
+ # Connector: router ─45°stub─ straight ─45°stub─ UCIe port
rpx, rpy = mm2px(crx, cry)
+ d = 6
if direction == "N":
- # Router top → 45° diagonal → vertical to UCIe port
- x2, y2 = rpx, rpy - r_size # router top
- x1, y1 = lx, cy_box + ch # port bottom
- dx = abs(x1 - x2)
- mid_y = y2 - dx
- if mid_y < y1:
- mid_y = y1
+ rx, ry = rpx, rpy - r_size
+ tx, ty = lx, cy_box + ch
+ sx = tx - rx
+ sd = d if sx >= 0 else -d
parts.append(
- f' '
)
elif direction == "S":
- x2, y2 = rpx, rpy + r_size
- x1, y1 = lx, cy_box
- dx = abs(x1 - x2)
- mid_y = y2 + dx
- if mid_y > y1:
- mid_y = y1
+ rx, ry = rpx, rpy + r_size
+ tx, ty = lx, cy_box
+ sx = tx - rx
+ sd = d if sx >= 0 else -d
parts.append(
- f' '
)
elif direction == "W":
- x2, y2 = rpx - r_size, rpy
- x1, y1 = cx + cw, cy_box + ch / 2
- dy = abs(y1 - y2)
- mid_x = x2 - dy
- if mid_x < x1:
- mid_x = x1
+ rx, ry = rpx - r_size, rpy
+ tx, ty = cx + cw, cy_box + ch / 2
+ sy = ty - ry
+ sd = d if sy >= 0 else -d
parts.append(
- f' '
)
elif direction == "E":
- x2, y2 = rpx + r_size, rpy
- x1, y1 = cx, cy_box + ch / 2
- dy = abs(y1 - y2)
- mid_x = x2 + dy
- if mid_x > x1:
- mid_x = x1
+ rx, ry = rpx + r_size, rpy
+ tx, ty = cx, cy_box + ch / 2
+ sy = ty - ry
+ sd = d if sy >= 0 else -d
parts.append(
- f' '
)