diff --git a/docs/diagrams/cube_view.svg b/docs/diagrams/cube_view.svg
index bdd7536..3809682 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
-
+
r2c1
@@ -182,7 +182,7 @@
r3c0
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 6c42213..04c40cb 100644
--- a/src/kernbench/topology/visualizer.py
+++ b/src/kernbench/topology/visualizer.py
@@ -632,23 +632,49 @@ 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: block → router
+ # Connector line: block → router (45° L-bend)
+ sc = style["stroke"]
if kind in ("mcpu", "sram"):
- # Horizontal connector (block right edge → router left edge)
+ # From block right edge, 45° bend to router
+ x1 = bx + blk_w
+ y1 = by + blk_h / 2
+ x2 = px - r_size
+ y2 = py
+ # 45° bend: go horizontal first, then diagonal
+ mid_x = x2 - abs(y2 - y1)
+ if mid_x < x1:
+ mid_x = (x1 + x2) / 2
parts.append(
- f' '
+ f' '
)
else:
- # Vertical connector (PE above/below router)
- ly1 = by + blk_h if is_top else by
- ly2 = py - r_size if is_top else py + r_size
- parts.append(
- f' '
- )
+ # PE: from block bottom/top edge, 45° bend to router
+ if is_top:
+ x1 = bx + blk_w / 2 + offset_x
+ y1 = by + blk_h
+ x2 = px
+ y2 = py - r_size
+ # 45° bend: go vertical first, then diagonal
+ mid_y = y2 - abs(x2 - x1)
+ if mid_y < y1:
+ mid_y = (y1 + y2) / 2
+ parts.append(
+ f' '
+ )
+ else:
+ x1 = bx + blk_w / 2 + offset_x
+ y1 = by
+ x2 = px
+ y2 = py + r_size
+ mid_y = y2 + abs(x2 - x1)
+ if mid_y > y1:
+ mid_y = (y1 + y2) / 2
+ parts.append(
+ f' '
+ )
# (PE→HBM BW annotation drawn in the PE→HBM port group section above)
@@ -668,10 +694,15 @@ 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
+ # 45° L-bend: vertical from router, then diagonal to HBM port
+ mid_y = tgy - abs(tgx - rpx) if rpy < hbm_y else tgy + abs(tgx - rpx)
+ if rpy < hbm_y:
+ mid_y = max(mid_y, (r_edge_y + tgy) / 2)
+ else:
+ mid_y = min(mid_y, (r_edge_y + tgy) / 2)
parts.append(
- f' '
)
# BW annotation at midpoint
@@ -765,31 +796,43 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
f'{conn}'
)
- # Connector line: port → router
+ # Connector line: port → router (45° L-bend)
rpx, rpy = mm2px(crx, cry)
if direction == "N":
+ x1, y1 = lx, cy_box + ch
+ x2, y2 = rpx, rpy - r_size
+ mid_y = y2 - abs(x2 - x1)
+ mid_y = max(mid_y, (y1 + y2) / 2)
parts.append(
- f' '
+ f' '
)
elif direction == "S":
+ x1, y1 = lx, cy_box
+ x2, y2 = rpx, rpy + r_size
+ mid_y = y2 + abs(x2 - x1)
+ mid_y = min(mid_y, (y1 + y2) / 2)
parts.append(
- f' '
+ f' '
)
elif direction == "W":
+ x1, y1 = cx + cw, cy_box + ch / 2
+ x2, y2 = rpx - r_size, rpy
+ mid_x = x2 - abs(y2 - y1)
+ mid_x = max(mid_x, (x1 + x2) / 2)
parts.append(
- f' '
+ f' '
)
elif direction == "E":
+ x1, y1 = cx, cy_box + ch / 2
+ x2, y2 = rpx + r_size, rpy
+ mid_x = x2 + abs(y2 - y1)
+ mid_x = min(mid_x, (x1 + x2) / 2)
parts.append(
- f' '
+ f' '
)
# ── Legend ──