Cube-view: UCIe position/size from topology.yaml (ucie_mm.size=2.0)

UCIe components placed at defined positions from _cube_local_positions
with size from cube.geometry.ucie_mm.size. N/S horizontal, E/W vertical.
Connection ports rendered as color-coded boxes inside UCIe component.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-05 00:11:11 -07:00
parent 66ec6cd40c
commit df81835d84
2 changed files with 94 additions and 122 deletions
+38 -66
View File
@@ -683,9 +683,18 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
f'{agg_bw:.0f}GB/s</text>'
)
# ── UCIe port components (inside cube boundary, on edges) ──
# ── UCIe port components (position/size from topology.yaml) ──
# ucie_mm.size = 2.0mm, positions from _cube_local_positions
ucie_size_mm = cube.get("geometry", {}).get("ucie_mm", {}).get("size", 2.0)
ucie_positions = {
"N": (cube_w / 2, ucie_size_mm / 2), # top center
"S": (cube_w / 2, cube_h - ucie_size_mm / 2), # bottom center
"W": (ucie_size_mm / 2, cube_h / 2), # left center
"E": (cube_w - ucie_size_mm / 2, cube_h / 2), # right center
}
# Collect UCIe connections per direction
ucie_by_dir: dict[str, list[tuple[str, str, float, float]]] = {} # dir → [(conn, rkey, rx, ry)]
ucie_by_dir: dict[str, list[tuple[str, str, float, float]]] = {}
for rkey, rval in routers.items():
if rval is None:
continue
@@ -699,123 +708,86 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
ucie_by_dir.setdefault(direction, []).append((conn, rkey, rx, ry))
ucie_colors = ["#818cf8", "#a78bfa", "#c084fc", "#e879f9"]
ucie_port_inset = 3 # mm inset from cube edge
for direction, conns in ucie_by_dir.items():
conns.sort(key=lambda x: x[0]) # sort by conn name
conns.sort(key=lambda x: x[0])
n_conn = len(conns)
ucx_mm, ucy_mm = ucie_positions.get(direction, (cube_w / 2, cube_h / 2))
ucx, ucy = mm2px(ucx_mm, ucy_mm)
# UCIe component box position (inside cube, along edge)
if direction == "N":
# Horizontal bar along top edge
# Find X span from attached routers
xs = [mm2px(rx, ry)[0] for _, _, rx, ry in conns]
ux1 = min(xs) - 15
ux2 = max(xs) + 15
uw = ux2 - ux1
uh = 18
ux = ux1
uy = pad + ucie_port_inset * scale
elif direction == "S":
xs = [mm2px(rx, ry)[0] for _, _, rx, ry in conns]
ux1 = min(xs) - 15
ux2 = max(xs) + 15
uw = ux2 - ux1
uh = 18
ux = ux1
uy = pad + cube_h * scale - ucie_port_inset * scale - uh
elif direction == "W":
ys = [mm2px(rx, ry)[1] for _, _, rx, ry in conns]
uy1 = min(ys) - 15
uy2 = max(ys) + 15
uw = 18
uh = uy2 - uy1
ux = pad + ucie_port_inset * scale
uy = uy1
elif direction == "E":
ys = [mm2px(rx, ry)[1] for _, _, rx, ry in conns]
uy1 = min(ys) - 15
uy2 = max(ys) + 15
uw = 18
uh = uy2 - uy1
ux = pad + cube_w * scale - ucie_port_inset * scale - uw
uy = uy1
# UCIe box: size from topology, N/S horizontal, E/W vertical
us = ucie_size_mm * scale
if direction in ("N", "S"):
uw, uh = us, us * 0.5
else:
continue
uw, uh = us * 0.5, us
ux = ucx - uw / 2
uy = ucy - uh / 2
# UCIe component background
parts.append(
f' <rect x="{ux:.0f}" y="{uy:.0f}" '
f'width="{uw:.0f}" height="{uh:.0f}" '
f'rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.8"/>'
f'rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.9"/>'
)
# UCIe direction label
parts.append(
f' <text x="{ucx:.0f}" y="{uy - 3:.0f}" text-anchor="middle" '
f'font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">'
f'UCIe-{direction}</text>'
)
# UCIe label
if direction in ("N", "S"):
parts.append(
f' <text x="{ux + uw / 2:.0f}" y="{uy - 3:.0f}" text-anchor="middle" '
f'font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">'
f'UCIe-{direction}</text>'
)
else:
parts.append(
f' <text x="{ux + uw / 2:.0f}" y="{uy - 3:.0f}" text-anchor="middle" '
f'font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">'
f'UCIe-{direction}</text>'
)
# Connection port boxes inside UCIe component
for ci, (conn, rkey, crx, cry) in enumerate(conns):
c_color = ucie_colors[ci % len(ucie_colors)]
if direction in ("N", "S"):
# Horizontal layout
cw = max((uw - 4) / n_conn - 1, 6)
ch = uh - 4
cx = ux + 2 + ci * (cw + 1)
cy = uy + 2
cy_box = uy + 2
else:
# Vertical layout
cw = uw - 4
ch = max((uh - 4) / n_conn - 1, 6)
cx = ux + 2
cy = uy + 2 + ci * (ch + 1)
cy_box = uy + 2 + ci * (ch + 1)
parts.append(
f' <rect x="{cx:.0f}" y="{cy:.0f}" '
f' <rect x="{cx:.0f}" y="{cy_box:.0f}" '
f'width="{cw:.0f}" height="{ch:.0f}" '
f'rx="2" fill="{c_color}" opacity="0.7"/>'
)
# Connection label
lx = cx + cw / 2
ly_t = cy + ch / 2 + 3
ly_t = cy_box + ch / 2 + 3
parts.append(
f' <text x="{lx:.0f}" y="{ly_t:.0f}" text-anchor="middle" '
f'font-family="monospace" font-size="5" fill="white">'
f'{conn}</text>'
)
# Connector line: port box → attached router
# Connector line: port router
rpx, rpy = mm2px(crx, cry)
if direction == "N":
parts.append(
f' <line x1="{lx:.0f}" y1="{cy + ch:.0f}" '
f' <line x1="{lx:.0f}" y1="{cy_box + ch:.0f}" '
f'x2="{rpx:.0f}" y2="{rpy - r_size:.0f}" '
f'stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
)
elif direction == "S":
parts.append(
f' <line x1="{lx:.0f}" y1="{cy:.0f}" '
f' <line x1="{lx:.0f}" y1="{cy_box:.0f}" '
f'x2="{rpx:.0f}" y2="{rpy + r_size:.0f}" '
f'stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
)
elif direction == "W":
parts.append(
f' <line x1="{cx + cw:.0f}" y1="{cy + ch / 2:.0f}" '
f' <line x1="{cx + cw:.0f}" y1="{cy_box + ch / 2:.0f}" '
f'x2="{rpx - r_size:.0f}" y2="{rpy:.0f}" '
f'stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
)
elif direction == "E":
parts.append(
f' <line x1="{cx:.0f}" y1="{cy + ch / 2:.0f}" '
f' <line x1="{cx:.0f}" y1="{cy_box + ch / 2:.0f}" '
f'x2="{rpx + r_size:.0f}" y2="{rpy:.0f}" '
f'stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
)