Show individual routers in cube_view SVG, fix row Y overlap
- cube_view now renders all 32 router nodes from cube_mesh.yaml instead of collapsed "router_mesh" placeholder - Fix mesh_gen row Y position overlap (r1/r2 and r3/r4 had same Y) by adding hbm_gap spacing between PE rows and HBM zone - Add noc_router to visualizer KIND_SIZE for proper sizing - Update cube view tests for individual router nodes 339 passed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -921,21 +921,26 @@ def _build_cube_view(spec: dict) -> ViewGraph:
|
||||
label=name.upper().replace("_", " "),
|
||||
)
|
||||
|
||||
# Router mesh representative node (collapsed for view)
|
||||
router_spec = cube["components"]["noc_router"]
|
||||
cx = cube_w / 2
|
||||
cy = cube_h / 2
|
||||
nodes["router_mesh"] = Node(
|
||||
id="router_mesh", kind=router_spec["kind"], impl=router_spec["impl"],
|
||||
attrs=router_spec["attrs"], pos_mm=(cx + 2.0, cy),
|
||||
label="ROUTER MESH",
|
||||
)
|
||||
# Load mesh data early (needed for router nodes + PE distances)
|
||||
mesh_data = spec.get("_mesh", {})
|
||||
|
||||
# PEs as opaque blocks (no per-PE xbar nodes)
|
||||
# Router nodes from cube_mesh.yaml (explicit in view)
|
||||
router_spec = cube["components"]["noc_router"]
|
||||
routers = mesh_data.get("routers", {})
|
||||
for rkey, rval in routers.items():
|
||||
if rval is None:
|
||||
continue
|
||||
rx, ry = rval["pos_mm"]
|
||||
nodes[rkey] = Node(
|
||||
id=rkey, kind=router_spec["kind"], impl=router_spec["impl"],
|
||||
attrs=router_spec["attrs"], pos_mm=(rx, ry),
|
||||
label=rkey.upper(),
|
||||
)
|
||||
|
||||
# PEs as opaque blocks
|
||||
corners = cube["pe_layout"]["corners"]
|
||||
pe_per_corner = cube["pe_layout"]["pe_per_corner"]
|
||||
corner_pos = _corner_pe_positions(cube_w, cube_h)
|
||||
mesh_data = spec.get("_mesh", {})
|
||||
pe_noc_distances = _compute_pe_noc_distances(
|
||||
mesh_data, corner_pos, corners, pe_per_corner,
|
||||
) if mesh_data else {}
|
||||
@@ -950,76 +955,101 @@ def _build_cube_view(spec: dict) -> ViewGraph:
|
||||
attrs={"corner": corner}, pos_mm=(px, py),
|
||||
label=f"PE{pe_idx}",
|
||||
)
|
||||
# PE ↔ router_mesh (view representation)
|
||||
pe_to_router_bw = clinks.get("pe_to_router_bw_gbs", 256.0)
|
||||
view_edges.append(Edge(
|
||||
src=pid, dst="router_mesh",
|
||||
distance_mm=pe_noc_distances.get(pe_idx, 0.0),
|
||||
bw_gbs=pe_to_router_bw,
|
||||
kind="pe_to_router",
|
||||
))
|
||||
view_edges.append(Edge(
|
||||
src="router_mesh", dst=pid,
|
||||
distance_mm=clinks.get("noc_to_pe_cpu_mm", 0.0),
|
||||
kind="command",
|
||||
))
|
||||
pe_idx += 1
|
||||
|
||||
# router_mesh ↔ hbm_ctrl
|
||||
# View edges based on cube_mesh.yaml attach (mirrors _instantiate_cube logic)
|
||||
pe_to_router_bw = clinks.get("pe_to_router_bw_gbs", 256.0)
|
||||
hbm_to_router_bw = clinks.get("hbm_to_router_bw_gbs", 256.0)
|
||||
view_edges.append(Edge(
|
||||
src="router_mesh", dst="hbm_ctrl",
|
||||
distance_mm=0.0, bw_gbs=hbm_to_router_bw,
|
||||
kind="router_to_hbm",
|
||||
))
|
||||
view_edges.append(Edge(
|
||||
src="hbm_ctrl", dst="router_mesh",
|
||||
distance_mm=0.0, bw_gbs=hbm_to_router_bw,
|
||||
kind="hbm_to_router",
|
||||
))
|
||||
|
||||
# router_mesh ↔ m_cpu
|
||||
view_edges.append(Edge(
|
||||
src="m_cpu", dst="router_mesh",
|
||||
distance_mm=clinks.get("m_cpu_to_router_mm", 0.0),
|
||||
kind="command",
|
||||
))
|
||||
view_edges.append(Edge(
|
||||
src="router_mesh", dst="m_cpu",
|
||||
distance_mm=clinks.get("m_cpu_to_router_mm", 0.0),
|
||||
kind="command",
|
||||
))
|
||||
|
||||
# router_mesh ↔ sram
|
||||
sram_bw = clinks.get("sram_to_router_bw_gbs", 128.0)
|
||||
view_edges.append(Edge(
|
||||
src="router_mesh", dst="sram",
|
||||
distance_mm=0.0, bw_gbs=sram_bw,
|
||||
kind="router_to_sram",
|
||||
))
|
||||
|
||||
ucie_conn_bw_v = ucie_cfg.get("per_connection_bw_gbs", 128.0)
|
||||
for port in ucie_cfg["ports"]:
|
||||
for ci in range(ucie_n_conn):
|
||||
conn_id = f"ucie-{port}.conn{ci}"
|
||||
view_edges.append(Edge(
|
||||
src="router_mesh", dst=conn_id,
|
||||
distance_mm=0.0, bw_gbs=ucie_conn_bw_v,
|
||||
kind="router_to_ucie_conn",
|
||||
))
|
||||
view_edges.append(Edge(
|
||||
src=conn_id, dst=f"ucie-{port}",
|
||||
distance_mm=0.0, kind="ucie_internal",
|
||||
))
|
||||
view_edges.append(Edge(
|
||||
src=f"ucie-{port}", dst=conn_id,
|
||||
distance_mm=0.0, kind="ucie_internal",
|
||||
))
|
||||
view_edges.append(Edge(
|
||||
src=conn_id, dst="router_mesh",
|
||||
distance_mm=0.0, bw_gbs=ucie_conn_bw_v,
|
||||
kind="ucie_conn_to_router",
|
||||
))
|
||||
n_rows = mesh_data.get("mesh", {}).get("rows", 6)
|
||||
n_cols = mesh_data.get("mesh", {}).get("cols", 6)
|
||||
|
||||
# Router ↔ router mesh edges
|
||||
for r in range(n_rows):
|
||||
for c in range(n_cols):
|
||||
rkey = f"r{r}c{c}"
|
||||
if routers.get(rkey) is None:
|
||||
continue
|
||||
src_pos = routers[rkey]["pos_mm"]
|
||||
# Horizontal neighbor
|
||||
for nc in range(c + 1, n_cols):
|
||||
nkey = f"r{r}c{nc}"
|
||||
if routers.get(nkey) is None:
|
||||
continue
|
||||
dist = abs(routers[nkey]["pos_mm"][0] - src_pos[0])
|
||||
view_edges.append(Edge(
|
||||
src=rkey, dst=nkey, distance_mm=round(dist, 2),
|
||||
kind="router_mesh",
|
||||
))
|
||||
break
|
||||
# Vertical neighbor
|
||||
for nr in range(r + 1, n_rows):
|
||||
nkey = f"r{nr}c{c}"
|
||||
if routers.get(nkey) is None:
|
||||
continue
|
||||
dist = abs(routers[nkey]["pos_mm"][1] - src_pos[1])
|
||||
view_edges.append(Edge(
|
||||
src=rkey, dst=nkey, distance_mm=round(dist, 2),
|
||||
kind="router_mesh",
|
||||
))
|
||||
break
|
||||
|
||||
# Component ↔ router edges from attach lists
|
||||
for rkey, rval in routers.items():
|
||||
if rval is None:
|
||||
continue
|
||||
for item in rval.get("attach", []):
|
||||
if item.endswith(".dma"):
|
||||
pe_prefix = item.rsplit(".", 1)[0]
|
||||
pid = pe_prefix.replace("pe", "pe") # "pe0" → "pe0"
|
||||
if pid in nodes:
|
||||
view_edges.append(Edge(
|
||||
src=pid, dst=rkey, distance_mm=0.0,
|
||||
bw_gbs=pe_to_router_bw, kind="pe_to_router",
|
||||
))
|
||||
view_edges.append(Edge(
|
||||
src=rkey, dst=pid, distance_mm=0.0,
|
||||
kind="command",
|
||||
))
|
||||
elif item.endswith(".hbm"):
|
||||
view_edges.append(Edge(
|
||||
src=rkey, dst="hbm_ctrl", distance_mm=0.0,
|
||||
bw_gbs=hbm_to_router_bw, kind="router_to_hbm",
|
||||
))
|
||||
elif item == "m_cpu":
|
||||
view_edges.append(Edge(
|
||||
src="m_cpu", dst=rkey, distance_mm=0.0, kind="command",
|
||||
))
|
||||
view_edges.append(Edge(
|
||||
src=rkey, dst="m_cpu", distance_mm=0.0, kind="command",
|
||||
))
|
||||
elif item == "sram":
|
||||
view_edges.append(Edge(
|
||||
src="sram", dst=rkey, distance_mm=0.0,
|
||||
bw_gbs=sram_bw, kind="router_to_sram",
|
||||
))
|
||||
elif item.startswith("ucie_"):
|
||||
parts = item.split(".")
|
||||
direction = parts[0].replace("ucie_", "").upper()
|
||||
conn_num = parts[1].replace("c", "")
|
||||
conn_id = f"ucie-{direction}.conn{conn_num}"
|
||||
view_edges.append(Edge(
|
||||
src=rkey, dst=conn_id, distance_mm=0.0,
|
||||
bw_gbs=ucie_conn_bw_v, kind="router_to_ucie_conn",
|
||||
))
|
||||
view_edges.append(Edge(
|
||||
src=conn_id, dst=rkey, distance_mm=0.0,
|
||||
bw_gbs=ucie_conn_bw_v, kind="ucie_conn_to_router",
|
||||
))
|
||||
view_edges.append(Edge(
|
||||
src=conn_id, dst=f"ucie-{direction}",
|
||||
distance_mm=0.0, kind="ucie_internal",
|
||||
))
|
||||
view_edges.append(Edge(
|
||||
src=f"ucie-{direction}", dst=conn_id,
|
||||
distance_mm=0.0, kind="ucie_internal",
|
||||
))
|
||||
|
||||
return ViewGraph(
|
||||
name="cube", nodes=nodes, edges=view_edges,
|
||||
|
||||
Reference in New Issue
Block a user