Remove xbar/noc remnants, rule-based cube-view connectors

- Delete xbar.py and noc.py (TwoDMeshNocComponent) — unused since router mesh
- Remove xbar_v1/noc_2d_mesh_v1 from components.yaml
- Fix pe_to_xbar → pe_to_router in routing exclusion set
- Fix xbar_to_hbm_bw_gbs → hbm_to_router_bw_gbs in report.py
- Update all docstrings/comments referencing xbar/bridge → router mesh
- Cube-view connectors: rule-based _connector_points helper
  - PE↔router: single diagonal line (not chevron)
  - UCIe N/S: 45°→horizontal→45°
  - UCIe E/W: 45°→vertical→45°
  - HBM ports: 45°→horizontal→45°

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 23:59:12 -07:00
parent 7640635f90
commit eb792e6212
17 changed files with 163 additions and 571 deletions
-3
View File
@@ -28,9 +28,6 @@ components:
switch_v1: kernbench.components.builtin.forwarding:TransitComponent switch_v1: kernbench.components.builtin.forwarding:TransitComponent
noc_v1: kernbench.components.builtin.forwarding:TransitComponent noc_v1: kernbench.components.builtin.forwarding:TransitComponent
ucie_v1: kernbench.components.builtin.forwarding:TransitComponent ucie_v1: kernbench.components.builtin.forwarding:TransitComponent
noc_2d_mesh_v1: kernbench.components.builtin.noc:TwoDMeshNocComponent
xbar_v1: kernbench.components.builtin.xbar:PositionAwareXbarComponent
# IO / Host interface # IO / Host interface
pcie_ep_v1: kernbench.components.builtin.pcie_ep:PcieEpComponent pcie_ep_v1: kernbench.components.builtin.pcie_ep:PcieEpComponent
io_cpu_v1: kernbench.components.builtin.io_cpu:IoCpuComponent io_cpu_v1: kernbench.components.builtin.io_cpu:IoCpuComponent
+38 -38
View File
@@ -135,17 +135,14 @@
<text x="135" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c0</text> <text x="135" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c0</text>
<rect x="119" y="81" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/> <rect x="119" y="81" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/>
<text x="135" y="92" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE0</text> <text x="135" y="92" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE0</text>
<polyline points="135,127 147,115 147,109 135,97" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/> <line x1="135" y1="127" x2="149" y2="97" stroke="#a855f7" stroke-width="1" opacity="0.6"/>
<circle cx="285" cy="135" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/> <circle cx="285" cy="135" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/>
<text x="285" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c1</text> <text x="285" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c1</text>
<rect x="269" y="81" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/> <rect x="269" y="81" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/>
<text x="285" y="92" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE1</text> <text x="285" y="92" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE1</text>
<polyline points="285,127 297,115 297,109 285,97" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/> <line x1="285" y1="127" x2="299" y2="97" stroke="#a855f7" stroke-width="1" opacity="0.6"/>
<circle cx="435" cy="135" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/> <circle cx="435" cy="135" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
<text x="435" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c2</text> <text x="435" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c2</text>
<rect x="419" y="81" width="32" height="16" rx="3" fill="#451a03" stroke="#f59e0b" stroke-width="1"/>
<text x="435" y="92" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#f59e0b">M_CPU</text>
<polyline points="435,127 423,115 423,109 435,97" fill="none" stroke="#f59e0b" stroke-width="1" opacity="0.6"/>
<circle cx="585" cy="135" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="585" cy="135" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
<text x="585" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c3</text> <text x="585" y="138" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r0c3</text>
<circle cx="685" cy="135" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/> <circle cx="685" cy="135" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/>
@@ -156,20 +153,23 @@
<text x="135" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c0</text> <text x="135" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c0</text>
<circle cx="285" cy="260" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="285" cy="260" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
<text x="285" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c1</text> <text x="285" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c1</text>
<circle cx="435" cy="260" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="435" cy="260" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/>
<text x="435" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c2</text> <text x="435" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c2</text>
<rect x="419" y="206" width="32" height="16" rx="3" fill="#451a03" stroke="#f59e0b" stroke-width="1"/>
<text x="435" y="217" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#f59e0b">M_CPU</text>
<line x1="435" y1="252" x2="449" y2="222" stroke="#f59e0b" stroke-width="1" opacity="0.6"/>
<circle cx="585" cy="260" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="585" cy="260" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
<text x="585" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c3</text> <text x="585" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c3</text>
<circle cx="685" cy="260" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/> <circle cx="685" cy="260" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/>
<text x="685" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c4</text> <text x="685" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c4</text>
<rect x="669" y="206" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/> <rect x="669" y="206" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/>
<text x="685" y="217" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE2</text> <text x="685" y="217" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE2</text>
<polyline points="685,252 697,240 697,234 685,222" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/> <line x1="685" y1="252" x2="699" y2="222" stroke="#a855f7" stroke-width="1" opacity="0.6"/>
<circle cx="835" cy="260" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/> <circle cx="835" cy="260" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/>
<text x="835" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c5</text> <text x="835" y="263" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r1c5</text>
<rect x="819" y="206" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/> <rect x="819" y="206" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/>
<text x="835" y="217" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE3</text> <text x="835" y="217" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE3</text>
<polyline points="835,252 847,240 847,234 835,222" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/> <line x1="835" y1="252" x2="849" y2="222" stroke="#a855f7" stroke-width="1" opacity="0.6"/>
<circle cx="135" cy="335" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="135" cy="335" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
<text x="135" y="338" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r2c0</text> <text x="135" y="338" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r2c0</text>
<circle cx="285" cy="335" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="285" cy="335" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
@@ -182,7 +182,7 @@
<text x="135" y="488" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r3c0</text> <text x="135" y="488" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r3c0</text>
<rect x="119" y="523" width="32" height="16" rx="3" fill="#1c1917" stroke="#d97706" stroke-width="1"/> <rect x="119" y="523" width="32" height="16" rx="3" fill="#1c1917" stroke="#d97706" stroke-width="1"/>
<text x="135" y="534" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#d97706">SRAM</text> <text x="135" y="534" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#d97706">SRAM</text>
<polyline points="135,493 123,505 123,511 135,523" fill="none" stroke="#d97706" stroke-width="1" opacity="0.6"/> <line x1="135" y1="493" x2="149" y2="523" stroke="#d97706" stroke-width="1" opacity="0.6"/>
<circle cx="285" cy="485" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="285" cy="485" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
<text x="285" y="488" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r3c1</text> <text x="285" y="488" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r3c1</text>
<circle cx="685" cy="485" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="685" cy="485" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
@@ -193,12 +193,12 @@
<text x="135" y="563" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r4c0</text> <text x="135" y="563" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r4c0</text>
<rect x="119" y="598" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/> <rect x="119" y="598" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/>
<text x="135" y="609" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE4</text> <text x="135" y="609" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE4</text>
<polyline points="135,568 147,580 147,586 135,598" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/> <line x1="135" y1="568" x2="149" y2="598" stroke="#a855f7" stroke-width="1" opacity="0.6"/>
<circle cx="285" cy="560" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/> <circle cx="285" cy="560" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/>
<text x="285" y="563" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r4c1</text> <text x="285" y="563" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r4c1</text>
<rect x="269" y="598" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/> <rect x="269" y="598" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/>
<text x="285" y="609" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE5</text> <text x="285" y="609" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE5</text>
<polyline points="285,568 297,580 297,586 285,598" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/> <line x1="285" y1="568" x2="299" y2="598" stroke="#a855f7" stroke-width="1" opacity="0.6"/>
<circle cx="435" cy="560" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="435" cy="560" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
<text x="435" y="563" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r4c2</text> <text x="435" y="563" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r4c2</text>
<circle cx="585" cy="560" r="8" fill="#334155" stroke="#475569" stroke-width="1"/> <circle cx="585" cy="560" r="8" fill="#334155" stroke="#475569" stroke-width="1"/>
@@ -219,84 +219,84 @@
<text x="685" y="688" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r5c4</text> <text x="685" y="688" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r5c4</text>
<rect x="669" y="723" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/> <rect x="669" y="723" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/>
<text x="685" y="734" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE6</text> <text x="685" y="734" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE6</text>
<polyline points="685,693 697,705 697,711 685,723" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/> <line x1="685" y1="693" x2="699" y2="723" stroke="#a855f7" stroke-width="1" opacity="0.6"/>
<circle cx="835" cy="685" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/> <circle cx="835" cy="685" r="8" fill="#475569" stroke="#64748b" stroke-width="1"/>
<text x="835" y="688" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r5c5</text> <text x="835" y="688" text-anchor="middle" font-family="monospace" font-size="6" fill="white">r5c5</text>
<rect x="819" y="723" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/> <rect x="819" y="723" width="32" height="16" rx="3" fill="#2d1f3d" stroke="#a855f7" stroke-width="1"/>
<text x="835" y="734" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE7</text> <text x="835" y="734" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#a855f7">PE7</text>
<polyline points="835,693 847,705 847,711 835,723" fill="none" stroke="#a855f7" stroke-width="1" opacity="0.6"/> <line x1="835" y1="693" x2="849" y2="723" stroke="#a855f7" stroke-width="1" opacity="0.6"/>
<polyline points="135,143 147,155 147,277 324,289" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/> <polyline points="135,143 208,216 251,216 324,289" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/>
<text x="239" y="216" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text> <text x="239" y="216" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text>
<polyline points="285,143 297,155 297,277 431,289" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/> <polyline points="285,143 358,216 358,216 431,289" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/>
<text x="368" y="216" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text> <text x="368" y="216" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text>
<polyline points="685,268 673,280 673,277 539,289" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/> <polyline points="685,268 674,278 549,278 539,289" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/>
<text x="622" y="278" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text> <text x="622" y="278" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text>
<polyline points="835,268 823,280 823,277 646,289" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/> <polyline points="835,268 824,278 657,278 646,289" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/>
<text x="751" y="278" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text> <text x="751" y="278" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text>
<polyline points="135,552 147,540 147,543 324,531" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/> <polyline points="135,552 146,542 313,542 324,531" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/>
<text x="239" y="542" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text> <text x="239" y="542" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text>
<polyline points="285,552 297,540 297,543 431,531" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/> <polyline points="285,552 296,542 421,542 431,531" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/>
<text x="368" y="542" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text> <text x="368" y="542" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text>
<polyline points="685,677 673,665 673,543 539,531" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/> <polyline points="685,677 612,604 612,604 539,531" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/>
<text x="622" y="604" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text> <text x="622" y="604" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text>
<polyline points="835,677 823,665 823,543 646,531" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/> <polyline points="835,677 762,604 719,604 646,531" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" stroke-dasharray="4,3"/>
<text x="751" y="604" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text> <text x="751" y="604" font-family="monospace" font-size="6" fill="#10b98188">256GB/s</text>
<rect x="65" y="360" width="50" height="100" rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.9"/> <rect x="65" y="360" width="50" height="100" rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.9"/>
<text x="90" y="357" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">UCIe-W</text> <text x="90" y="357" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">UCIe-W</text>
<rect x="67" y="362" width="46" height="23" rx="2" fill="#818cf8" opacity="0.7"/> <rect x="67" y="362" width="46" height="23" rx="2" fill="#818cf8" opacity="0.7"/>
<text x="90" y="376" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c0</text> <text x="90" y="376" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c0</text>
<polyline points="127,135 117,145 123,145 113,374" fill="none" stroke="#818cf8" stroke-width="1" opacity="0.5"/> <polyline points="127,135 120,142 120,366 113,374" fill="none" stroke="#818cf8" stroke-width="1" opacity="0.5"/>
<rect x="67" y="386" width="46" height="23" rx="2" fill="#a78bfa" opacity="0.7"/> <rect x="67" y="386" width="46" height="23" rx="2" fill="#a78bfa" opacity="0.7"/>
<text x="90" y="400" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c1</text> <text x="90" y="400" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c1</text>
<polyline points="127,260 117,270 123,270 113,398" fill="none" stroke="#a78bfa" stroke-width="1" opacity="0.5"/> <polyline points="127,260 120,267 120,390 113,398" fill="none" stroke="#a78bfa" stroke-width="1" opacity="0.5"/>
<rect x="67" y="410" width="46" height="23" rx="2" fill="#c084fc" opacity="0.7"/> <rect x="67" y="410" width="46" height="23" rx="2" fill="#c084fc" opacity="0.7"/>
<text x="90" y="424" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c2</text> <text x="90" y="424" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c2</text>
<polyline points="127,560 117,550 123,550 113,422" fill="none" stroke="#c084fc" stroke-width="1" opacity="0.5"/> <polyline points="127,560 120,553 120,428 113,422" fill="none" stroke="#c084fc" stroke-width="1" opacity="0.5"/>
<rect x="67" y="434" width="46" height="23" rx="2" fill="#e879f9" opacity="0.7"/> <rect x="67" y="434" width="46" height="23" rx="2" fill="#e879f9" opacity="0.7"/>
<text x="90" y="448" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c3</text> <text x="90" y="448" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c3</text>
<polyline points="127,685 117,675 123,675 113,446" fill="none" stroke="#e879f9" stroke-width="1" opacity="0.5"/> <polyline points="127,685 120,678 120,452 113,446" fill="none" stroke="#e879f9" stroke-width="1" opacity="0.5"/>
<rect x="435" y="65" width="100" height="50" rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.9"/> <rect x="435" y="65" width="100" height="50" rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.9"/>
<text x="485" y="62" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">UCIe-N</text> <text x="485" y="62" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">UCIe-N</text>
<rect x="437" y="67" width="23" height="46" rx="2" fill="#818cf8" opacity="0.7"/> <rect x="437" y="67" width="23" height="46" rx="2" fill="#818cf8" opacity="0.7"/>
<text x="448" y="93" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c0</text> <text x="448" y="93" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c0</text>
<polyline points="135,127 145,117 145,123 448,113" fill="none" stroke="#818cf8" stroke-width="1" opacity="0.5"/> <polyline points="135,127 142,120 442,120 448,113" fill="none" stroke="#818cf8" stroke-width="1" opacity="0.5"/>
<rect x="461" y="67" width="23" height="46" rx="2" fill="#a78bfa" opacity="0.7"/> <rect x="461" y="67" width="23" height="46" rx="2" fill="#a78bfa" opacity="0.7"/>
<text x="472" y="93" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c1</text> <text x="472" y="93" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c1</text>
<polyline points="285,127 295,117 295,123 472,113" fill="none" stroke="#a78bfa" stroke-width="1" opacity="0.5"/> <polyline points="285,127 292,120 466,120 472,113" fill="none" stroke="#a78bfa" stroke-width="1" opacity="0.5"/>
<rect x="485" y="67" width="23" height="46" rx="2" fill="#c084fc" opacity="0.7"/> <rect x="485" y="67" width="23" height="46" rx="2" fill="#c084fc" opacity="0.7"/>
<text x="496" y="93" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c2</text> <text x="496" y="93" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c2</text>
<polyline points="685,127 675,117 675,123 496,113" fill="none" stroke="#c084fc" stroke-width="1" opacity="0.5"/> <polyline points="685,127 678,120 504,120 496,113" fill="none" stroke="#c084fc" stroke-width="1" opacity="0.5"/>
<rect x="509" y="67" width="23" height="46" rx="2" fill="#e879f9" opacity="0.7"/> <rect x="509" y="67" width="23" height="46" rx="2" fill="#e879f9" opacity="0.7"/>
<text x="520" y="93" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c3</text> <text x="520" y="93" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c3</text>
<polyline points="835,127 825,117 825,123 520,113" fill="none" stroke="#e879f9" stroke-width="1" opacity="0.5"/> <polyline points="835,127 828,120 528,120 520,113" fill="none" stroke="#e879f9" stroke-width="1" opacity="0.5"/>
<rect x="855" y="360" width="50" height="100" rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.9"/> <rect x="855" y="360" width="50" height="100" rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.9"/>
<text x="880" y="357" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">UCIe-E</text> <text x="880" y="357" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">UCIe-E</text>
<rect x="857" y="362" width="46" height="23" rx="2" fill="#818cf8" opacity="0.7"/> <rect x="857" y="362" width="46" height="23" rx="2" fill="#818cf8" opacity="0.7"/>
<text x="880" y="376" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c0</text> <text x="880" y="376" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c0</text>
<polyline points="843,135 853,145 847,145 857,374" fill="none" stroke="#818cf8" stroke-width="1" opacity="0.5"/> <polyline points="843,135 850,142 850,367 857,374" fill="none" stroke="#818cf8" stroke-width="1" opacity="0.5"/>
<rect x="857" y="386" width="46" height="23" rx="2" fill="#a78bfa" opacity="0.7"/> <rect x="857" y="386" width="46" height="23" rx="2" fill="#a78bfa" opacity="0.7"/>
<text x="880" y="400" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c1</text> <text x="880" y="400" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c1</text>
<polyline points="843,260 853,270 847,270 857,398" fill="none" stroke="#a78bfa" stroke-width="1" opacity="0.5"/> <polyline points="843,260 850,267 850,391 857,398" fill="none" stroke="#a78bfa" stroke-width="1" opacity="0.5"/>
<rect x="857" y="410" width="46" height="23" rx="2" fill="#c084fc" opacity="0.7"/> <rect x="857" y="410" width="46" height="23" rx="2" fill="#c084fc" opacity="0.7"/>
<text x="880" y="424" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c2</text> <text x="880" y="424" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c2</text>
<polyline points="843,560 853,550 847,550 857,422" fill="none" stroke="#c084fc" stroke-width="1" opacity="0.5"/> <polyline points="843,560 850,553 850,428 857,422" fill="none" stroke="#c084fc" stroke-width="1" opacity="0.5"/>
<rect x="857" y="434" width="46" height="23" rx="2" fill="#e879f9" opacity="0.7"/> <rect x="857" y="434" width="46" height="23" rx="2" fill="#e879f9" opacity="0.7"/>
<text x="880" y="448" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c3</text> <text x="880" y="448" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c3</text>
<polyline points="843,685 853,675 847,675 857,446" fill="none" stroke="#e879f9" stroke-width="1" opacity="0.5"/> <polyline points="843,685 850,678 850,452 857,446" fill="none" stroke="#e879f9" stroke-width="1" opacity="0.5"/>
<rect x="435" y="705" width="100" height="50" rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.9"/> <rect x="435" y="705" width="100" height="50" rx="3" fill="#1e1b4b" stroke="#8b5cf6" stroke-width="1.5" opacity="0.9"/>
<text x="485" y="702" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">UCIe-S</text> <text x="485" y="702" text-anchor="middle" font-family="monospace" font-size="7" font-weight="bold" fill="#8b5cf6">UCIe-S</text>
<rect x="437" y="707" width="23" height="46" rx="2" fill="#818cf8" opacity="0.7"/> <rect x="437" y="707" width="23" height="46" rx="2" fill="#818cf8" opacity="0.7"/>
<text x="448" y="733" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c0</text> <text x="448" y="733" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c0</text>
<polyline points="135,693 145,703 145,697 448,707" fill="none" stroke="#818cf8" stroke-width="1" opacity="0.5"/> <polyline points="135,693 142,700 442,700 448,707" fill="none" stroke="#818cf8" stroke-width="1" opacity="0.5"/>
<rect x="461" y="707" width="23" height="46" rx="2" fill="#a78bfa" opacity="0.7"/> <rect x="461" y="707" width="23" height="46" rx="2" fill="#a78bfa" opacity="0.7"/>
<text x="472" y="733" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c1</text> <text x="472" y="733" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c1</text>
<polyline points="285,693 295,703 295,697 472,707" fill="none" stroke="#a78bfa" stroke-width="1" opacity="0.5"/> <polyline points="285,693 292,700 466,700 472,707" fill="none" stroke="#a78bfa" stroke-width="1" opacity="0.5"/>
<rect x="485" y="707" width="23" height="46" rx="2" fill="#c084fc" opacity="0.7"/> <rect x="485" y="707" width="23" height="46" rx="2" fill="#c084fc" opacity="0.7"/>
<text x="496" y="733" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c2</text> <text x="496" y="733" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c2</text>
<polyline points="685,693 675,703 675,697 496,707" fill="none" stroke="#c084fc" stroke-width="1" opacity="0.5"/> <polyline points="685,693 678,700 504,700 496,707" fill="none" stroke="#c084fc" stroke-width="1" opacity="0.5"/>
<rect x="509" y="707" width="23" height="46" rx="2" fill="#e879f9" opacity="0.7"/> <rect x="509" y="707" width="23" height="46" rx="2" fill="#e879f9" opacity="0.7"/>
<text x="520" y="733" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c3</text> <text x="520" y="733" text-anchor="middle" font-family="monospace" font-size="5" fill="white">c3</text>
<polyline points="835,693 825,703 825,697 520,707" fill="none" stroke="#e879f9" stroke-width="1" opacity="0.5"/> <polyline points="835,693 828,700 528,700 520,707" fill="none" stroke="#e879f9" stroke-width="1" opacity="0.5"/>
<rect x="60" y="865" width="10" height="10" rx="2" fill="#3b82f6" stroke="#475569" stroke-width="0.5"/> <rect x="60" y="865" width="10" height="10" rx="2" fill="#3b82f6" stroke="#475569" stroke-width="0.5"/>
<text x="74" y="874" font-family="monospace" font-size="8" fill="#94a3b8">PE Router</text> <text x="74" y="874" font-family="monospace" font-size="8" fill="#94a3b8">PE Router</text>
<rect x="147" y="865" width="10" height="10" rx="2" fill="#f59e0b" stroke="#475569" stroke-width="0.5"/> <rect x="147" y="865" width="10" height="10" rx="2" fill="#f59e0b" stroke="#475569" stroke-width="0.5"/>

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

+2 -2
View File
@@ -116,7 +116,7 @@ def _fmt_util(eff: float, bn: float | None) -> str:
def _short_name(node_id: str) -> str: def _short_name(node_id: str) -> str:
"""Shorten node id: keep last 2 segments to avoid ambiguity (xbar.pe0 vs pe0).""" """Shorten node id: keep last 2 segments to avoid ambiguity (router.pe0 vs pe0)."""
parts = node_id.split(".") parts = node_id.split(".")
return ".".join(parts[-2:]) if len(parts) >= 2 else node_id return ".".join(parts[-2:]) if len(parts) >= 2 else node_id
@@ -366,7 +366,7 @@ def run_probe(topology_path: str, case_filter: str | None = None) -> int:
# --- PE DMA Summary Table --- # --- PE DMA Summary Table ---
print() print()
print(f"=== PE DMA Latency (pe_dma -> xbar -> HBM, data={nbytes}B) ===") print(f"=== PE DMA Latency (pe_dma -> router -> HBM, data={nbytes}B) ===")
print(f" {'Case':<26} {'Target':<28} {'Actual':>8}" print(f" {'Case':<26} {'Target':<28} {'Actual':>8}"
f" {'Ovhd':>6} {'Drain':>6} {'Wire':>5} {'Ovhd%':>6} {'Drain%':>7}" f" {'Ovhd':>6} {'Drain':>6} {'Wire':>5} {'Ovhd%':>6} {'Drain%':>7}"
f" {'Eff.BW':>8} {'BN.BW':>8} {'Util%':>6}") f" {'Eff.BW':>8} {'BN.BW':>8} {'Util%':>6}")
+1 -1
View File
@@ -137,7 +137,7 @@ def _extract_peaks(spec: dict | None) -> tuple[float, float]:
gemm_attrs = comps.get("pe_gemm", {}).get("attrs", {}) gemm_attrs = comps.get("pe_gemm", {}).get("attrs", {})
peak_tflops = float(gemm_attrs.get("peak_tflops_f16", 0.0)) peak_tflops = float(gemm_attrs.get("peak_tflops_f16", 0.0))
cube_links = cube.get("links", {}) cube_links = cube.get("links", {})
hbm_bw = float(cube_links.get("xbar_to_hbm_bw_gbs", 0.0)) hbm_bw = float(cube_links.get("hbm_to_router_bw_gbs", 0.0))
return peak_tflops, hbm_bw return peak_tflops, hbm_bw
-224
View File
@@ -1,224 +0,0 @@
from __future__ import annotations
from collections.abc import Generator
from typing import TYPE_CHECKING, Any
import simpy
from kernbench.components.base import ComponentBase
if TYPE_CHECKING:
from kernbench.components.context import ComponentContext
from kernbench.topology.types import Node
class TwoDMeshNocComponent(ComponentBase):
"""2D mesh NOC modeled as a single smart node.
Latency model:
- Traversal latency = Manhattan distance between prev_hop and next_hop
node positions, split into XY segments, traversed with pipeline.
- overhead_ns (from node.attrs) is added once per traversal.
Contention model:
- Each directed XY segment is a simpy.Resource(capacity=1).
- Pipeline: next segment's resource is requested before the current
segment's timeout completes, so a free downstream segment is acquired
immediately (wormhole-style cut-through).
- Two transactions sharing a segment (same row or column band) contend.
Concurrency:
- _worker spawns an independent SimPy process per transaction, so the
NOC is never serialized at the node level — only at segment resources.
"""
def __init__(self, node: Node, ctx: ComponentContext | None = None) -> None:
super().__init__(node, ctx)
self._env: simpy.Environment | None = None
self._links: dict[tuple, simpy.Resource] = {}
self._x_grid: list[float] = []
self._y_grid: list[float] = []
def start(self, env: simpy.Environment) -> None:
self._env = env
self._build_grid()
super().start(env)
def run(self, env: simpy.Environment, nbytes: int) -> Generator:
yield env.timeout(0)
# ── Grid construction ────────────────────────────────────────────
def _build_grid(self) -> None:
if not self.ctx:
return
mesh = self.ctx.spec.get("_mesh") if self.ctx.spec else None
if mesh:
self._build_grid_from_mesh(mesh)
else:
self._build_grid_from_positions()
def _build_grid_from_mesh(self, mesh: dict) -> None:
"""Build XY grid from cube_mesh.yaml router positions (authoritative)."""
origin_x, origin_y = self._cube_origin()
xs: set[float] = set()
ys: set[float] = set()
for key, router in mesh.get("routers", {}).items():
if router is not None:
xs.add(round(origin_x + router["pos_mm"][0], 2))
ys.add(round(origin_y + router["pos_mm"][1], 2))
self._x_grid = sorted(xs)
self._y_grid = sorted(ys)
def _build_grid_from_positions(self) -> None:
"""Fallback: infer grid from all node positions in the cube."""
cube_prefix = self.node.id.rsplit(".", 1)[0]
xs: set[float] = set()
ys: set[float] = set()
for node_id, pos in self.ctx.positions.items():
if node_id.startswith(cube_prefix + ".") and pos is not None:
xs.add(round(pos[0], 2))
ys.add(round(pos[1], 2))
self._x_grid = sorted(xs)
self._y_grid = sorted(ys)
def _cube_origin(self) -> tuple[float, float]:
"""Compute absolute origin (top-left) of this cube from cube_id."""
parts = self.node.id.split(".")
cube_str = [p for p in parts if p.startswith("cube")][0]
cube_id = int(cube_str[4:])
spec = self.ctx.spec
sip_spec = spec.get("sip", {})
cube_spec = spec.get("cube", {})
mesh_w = sip_spec.get("cube_mesh", {}).get("w", 4)
cube_w = cube_spec.get("geometry", {}).get("cube_mm", {}).get("w", 17.0)
cube_h = cube_spec.get("geometry", {}).get("cube_mm", {}).get("h", 14.0)
seam = sip_spec.get("links", {}).get("inter_cube_mesh", {}).get(
"distance_mm_across_seam", 1.0)
col = cube_id % mesh_w
row = cube_id // mesh_w
return (col * (cube_w + seam), row * (cube_h + seam))
def _get_link(self, key: tuple) -> simpy.Resource:
if key not in self._links:
assert self._env is not None
self._links[key] = simpy.Resource(self._env, capacity=1)
return self._links[key]
# ── Worker ───────────────────────────────────────────────────────
def _worker(self, env: simpy.Environment) -> Generator:
while True:
txn: Any = yield self._inbox.get()
env.process(self._route(env, txn))
def _route(self, env: simpy.Environment, txn: Any) -> Generator:
prev_hop = txn.path[txn.step - 1] if txn.step > 0 else None
next_hop = txn.next_hop
overhead_ns = float(self.node.attrs.get("overhead_ns", 0.0))
links: list[tuple[tuple, float]] = []
if prev_hop and next_hop and self.ctx:
src_pos = self.ctx.positions.get(prev_hop)
dst_pos = self.ctx.positions.get(next_hop)
if src_pos and dst_pos:
links = self._xy_links(src_pos, dst_pos)
if links:
yield from self._traverse(env, links, overhead_ns)
else:
yield env.timeout(overhead_ns)
if next_hop:
yield self.out_ports[next_hop].put(txn.advance())
else:
drain = getattr(txn, "drain_ns", 0.0)
if drain > 0:
yield env.timeout(drain)
txn.done.succeed()
# ── XY routing and pipelined link traversal ──────────────────────
def _traverse(
self,
env: simpy.Environment,
links: list[tuple[tuple, float]],
overhead_ns: float,
) -> Generator:
"""Pipeline: request next segment before current timeout finishes."""
ns_per_mm = self.ctx.ns_per_mm # type: ignore[union-attr]
# Acquire first link
first_key, _ = links[0]
current_resource = self._get_link(first_key)
current_req = current_resource.request()
yield current_req
for i, (_, dist_mm) in enumerate(links):
# Request next link before current timeout (pipeline)
if i + 1 < len(links):
next_key, _ = links[i + 1]
next_resource = self._get_link(next_key)
next_req = next_resource.request()
yield env.timeout(dist_mm * ns_per_mm + (overhead_ns if i == 0 else 0.0))
current_resource.release(current_req)
if i + 1 < len(links):
yield next_req # usually already fulfilled (pipeline)
current_resource = next_resource
current_req = next_req
def _xy_links(
self,
src: tuple[float, float],
dst: tuple[float, float],
) -> list[tuple[tuple, float]]:
"""XY routing: horizontal segment first, then vertical.
Returns list of (link_key, dist_mm) pairs, where link_key uniquely
identifies a directed segment shared across concurrent transactions.
"""
x0, y0 = src
x1, y1 = dst
links: list[tuple[tuple, float]] = []
# Horizontal segment at y≈y0
if abs(x0 - x1) > 1e-9:
y_band = self._snap(y0, self._y_grid)
for xa, xb in self._segments(x0, x1, self._x_grid):
d = abs(xb - xa)
if d > 1e-9:
lo, hi = (xa, xb) if xa < xb else (xb, xa)
dir_h = "E" if xb > xa else "W"
links.append((("H", round(y_band, 2), round(lo, 2), round(hi, 2), dir_h), d))
# Vertical segment at x≈x1
if abs(y0 - y1) > 1e-9:
x_band = self._snap(x1, self._x_grid)
for ya, yb in self._segments(y0, y1, self._y_grid):
d = abs(yb - ya)
if d > 1e-9:
lo, hi = (ya, yb) if ya < yb else (yb, ya)
dir_v = "S" if yb > ya else "N"
links.append((("V", round(x_band, 2), round(lo, 2), round(hi, 2), dir_v), d))
return links
@staticmethod
def _snap(val: float, grid: list[float]) -> float:
if not grid:
return val
return min(grid, key=lambda g: abs(g - val))
@staticmethod
def _segments(a: float, b: float, grid: list[float]) -> list[tuple[float, float]]:
"""Consecutive (p_i, p_{i+1}) pairs covering range [a, b] using grid waypoints."""
if abs(a - b) < 1e-9:
return []
lo, hi = (a, b) if a < b else (b, a)
pts = [lo] + [g for g in grid if lo + 1e-9 < g < hi - 1e-9] + [hi]
pairs = [(pts[i], pts[i + 1]) for i in range(len(pts) - 1)]
if a > b:
pairs = [(p2, p1) for p1, p2 in reversed(pairs)]
return pairs
+1 -1
View File
@@ -96,7 +96,7 @@ class PeDmaComponent(PeEngineBase):
request=sub_request, path=path, step=0, request=sub_request, path=path, step=0,
nbytes=cmd.nbytes, done=sub_done, drain_ns=drain_ns, nbytes=cmd.nbytes, done=sub_done, drain_ns=drain_ns,
) )
# Send to next hop (path[0] is pe_dma itself, path[1] is xbar) # Send to next hop (path[0] is pe_dma itself, path[1] is router)
if len(path) > 1: if len(path) > 1:
yield self.out_ports[path[1]].put(sub_txn.advance()) yield self.out_ports[path[1]].put(sub_txn.advance())
# DMA channel released after issue # DMA channel released after issue
-168
View File
@@ -1,168 +0,0 @@
"""Position-aware XBAR component.
Models crossbar latency as base_overhead_ns + internal_distance * ns_per_mm,
where internal_distance is the Manhattan distance between the entry port
(PE router attachment) and exit port (HBM slice logical position) within
the crossbar matrix.
PE router positions come from cube_mesh.yaml (via ctx.spec["_mesh"]).
HBM slice positions are uniformly distributed across the HBM physical width.
"""
from __future__ import annotations
from collections.abc import Generator
from typing import TYPE_CHECKING, Any
import simpy
from kernbench.components.base import ComponentBase
if TYPE_CHECKING:
from kernbench.components.context import ComponentContext
from kernbench.topology.types import Node
class PositionAwareXbarComponent(ComponentBase):
"""XBAR with position-dependent latency based on PE-to-slice distance.
Latency = base_overhead_ns + |entry_port_x - exit_port_x| * ns_per_mm
Entry/exit port X positions are determined from the transaction path:
- PE_DMA nodes: router X from cube_mesh.yaml
- HBM slices: uniformly distributed across HBM physical width
- Bridge nodes: physical X from topology positions
- NOC: resolved by scanning path for PE_DMA node
"""
def __init__(self, node: Node, ctx: ComponentContext | None = None) -> None:
super().__init__(node, ctx)
self._base_overhead_ns = float(node.attrs.get("overhead_ns", 0.0))
self._pe_router_xs: dict[str, float] = {}
self._slice_xs: dict[str, float] = {}
self._bridge_xs: dict[str, float] = {}
self._ns_per_mm: float = 0.0
def start(self, env: simpy.Environment) -> None:
self._build_position_map()
super().start(env)
def run(self, env: simpy.Environment, nbytes: int) -> Generator:
yield env.timeout(self._base_overhead_ns)
# ── Position map construction ─────────────────────────────────
def _build_position_map(self) -> None:
if not self.ctx or not self.ctx.spec:
return
mesh = self.ctx.spec.get("_mesh")
if not mesh:
return
self._ns_per_mm = self.ctx.ns_per_mm
cube_prefix = self.node.id.rsplit(".", 1)[0]
xbar_name = self.node.id.rsplit(".", 1)[1]
is_top = xbar_name == "xbar_top"
xbar_key = "top" if is_top else "bottom"
# PE router X positions from mesh attachments
routers_list = mesh.get("xbar", {}).get(xbar_key, {}).get("routers", [])
for router_id in routers_list:
router_data = mesh["routers"].get(router_id)
if router_data is None:
continue
router_x = router_data["pos_mm"][0]
for attach in router_data.get("attach", []):
if attach.endswith(".dma"):
pe_name = attach.split(".")[0]
pe_dma_id = f"{cube_prefix}.{pe_name}.pe_dma"
self._pe_router_xs[pe_dma_id] = router_x
# HBM slice X positions: uniformly distributed across HBM width
cube_spec = self.ctx.spec.get("cube", {})
cube_w = cube_spec.get("geometry", {}).get("cube_mm", {}).get("w", 17.0)
hbm_w = cube_spec.get("geometry", {}).get("hbm_mm", {}).get("w", 9.0)
n_slices = cube_spec.get("memory_map", {}).get("hbm_slices_per_cube", 8)
half = n_slices // 2
hbm_left = (cube_w - hbm_w) / 2
if is_top:
slice_range = range(half)
else:
slice_range = range(half, n_slices)
n = len(list(slice_range))
for i, sl in enumerate(slice_range):
if n > 1:
x = hbm_left + i * hbm_w / (n - 1)
else:
x = cube_w / 2
self._slice_xs[f"{cube_prefix}.hbm_ctrl.slice{sl}"] = x
# Bridge X positions from topology positions
for node_id, pos in self.ctx.positions.items():
if node_id.startswith(cube_prefix + ".bridge.") and pos is not None:
origin_x = self._cube_origin_x()
self._bridge_xs[node_id] = pos[0] - origin_x
def _cube_origin_x(self) -> float:
"""Compute absolute X origin of this cube."""
parts = self.node.id.split(".")
cube_str = [p for p in parts if p.startswith("cube")][0]
cube_id = int(cube_str[4:])
spec = self.ctx.spec
sip_spec = spec.get("sip", {})
cube_spec = spec.get("cube", {})
mesh_w = sip_spec.get("cube_mesh", {}).get("w", 4)
cube_w = cube_spec.get("geometry", {}).get("cube_mm", {}).get("w", 17.0)
seam = sip_spec.get("links", {}).get("inter_cube_mesh", {}).get(
"distance_mm_across_seam", 1.0)
col = cube_id % mesh_w
return col * (cube_w + seam)
# ── Worker override ───────────────────────────────────────────
def _worker(self, env: simpy.Environment) -> Generator:
while True:
txn: Any = yield self._inbox.get()
env.process(self._position_aware_forward(env, txn))
def _position_aware_forward(
self, env: simpy.Environment, txn: Any,
) -> Generator:
prev_hop = txn.path[txn.step - 1] if txn.step > 0 else None
next_hop = txn.next_hop
overhead = self._base_overhead_ns
if prev_hop and next_hop and self._ns_per_mm > 0:
entry_x = self._get_port_x(prev_hop, txn.path)
exit_x = self._get_port_x(next_hop, txn.path)
if entry_x is not None and exit_x is not None:
overhead = self._base_overhead_ns + abs(entry_x - exit_x) * self._ns_per_mm
yield env.timeout(overhead)
if next_hop:
yield self.out_ports[next_hop].put(txn.advance())
else:
drain = getattr(txn, "drain_ns", 0.0)
if drain > 0:
yield env.timeout(drain)
txn.done.succeed()
def _get_port_x(self, node_id: str, path: list[str]) -> float | None:
"""Resolve the X position of an XBAR port from node context."""
# Direct lookup: PE DMA
if node_id in self._pe_router_xs:
return self._pe_router_xs[node_id]
# Direct lookup: HBM slice
if node_id in self._slice_xs:
return self._slice_xs[node_id]
# Direct lookup: bridge
if node_id in self._bridge_xs:
return self._bridge_xs[node_id]
# NOC: scan path for PE DMA node
if "noc" in node_id:
for p in path:
if p in self._pe_router_xs:
return self._pe_router_xs[p]
return None
+3 -3
View File
@@ -81,7 +81,7 @@ class PathRouter:
# Edge kinds excluded from M_CPU DMA adjacency: prevents routing through # Edge kinds excluded from M_CPU DMA adjacency: prevents routing through
# PE-internal pipeline nodes when computing DMA paths. # PE-internal pipeline nodes when computing DMA paths.
_MCPU_DMA_EXCLUDE = {"pe_internal", "pe_to_xbar"} _MCPU_DMA_EXCLUDE = {"pe_internal", "pe_to_router"}
_UCIE_KINDS = {"ucie_internal", "ucie_conn_to_router", "router_to_ucie_conn", _UCIE_KINDS = {"ucie_internal", "ucie_conn_to_router", "router_to_ucie_conn",
"ucie_conn_to_noc", "noc_to_ucie_conn", "ucie_mesh", "ucie_conn_to_noc", "noc_to_ucie_conn", "ucie_mesh",
@@ -124,9 +124,9 @@ class PathRouter:
return self._run_dijkstra(self._adj_all, m_cpu_id, dst_hbm_id) return self._run_dijkstra(self._adj_all, m_cpu_id, dst_hbm_id)
def find_memory_path(self, src: str, dst: str) -> list[str]: def find_memory_path(self, src: str, dst: str) -> list[str]:
"""Direct memory path: pcie_ep → io_noc → cube → xbar → hbm_ctrl. """Direct memory path: pcie_ep → io_noc → cube → router mesh → hbm_ctrl.
Uses _adj_mcpu_dma which excludes pe_internal and pe_to_xbar edges, Uses _adj_mcpu_dma which excludes pe_internal and pe_to_router edges,
preventing routing through PE pipeline nodes. preventing routing through PE pipeline nodes.
""" """
return self._run_dijkstra(self._adj_mcpu_dma, src, dst) return self._run_dijkstra(self._adj_mcpu_dma, src, dst)
+3 -3
View File
@@ -19,9 +19,9 @@ class GraphEngine:
"""simpy-based discrete-event simulation engine. """simpy-based discrete-event simulation engine.
Request routing: Request routing:
MemoryWrite/Read: pcie_ep → io_noc → cube → xbar → hbm_ctrl (m_cpu bypass) MemoryWrite/Read: pcie_ep → io_noc → cube → router mesh → hbm_ctrl (m_cpu bypass)
KernelLaunch: pcie_ep → io_noc → io_cpu → io_noc → cube → m_cpu → PE KernelLaunch: pcie_ep → io_noc → io_cpu → io_noc → cube → m_cpu → PE
PeDmaMsg: pe_dma → xbar → hbm_ctrl (direct probe) PeDmaMsg: pe_dma → router mesh → hbm_ctrl (direct probe)
Component implementations are DI-injectable via component_overrides (ADR-0007 D3). Component implementations are DI-injectable via component_overrides (ADR-0007 D3).
""" """
@@ -261,7 +261,7 @@ class GraphEngine:
done.succeed() done.succeed()
def _process_memory_direct(self, key: str, request: Any, done: simpy.Event): def _process_memory_direct(self, key: str, request: Any, done: simpy.Event):
"""Direct memory path: pcie_ep → io_noc → cube → xbar → hbm_ctrl. """Direct memory path: pcie_ep → io_noc → cube → router mesh → hbm_ctrl.
MemoryWrite: data flows forward (nbytes on wires), drain at hbm_ctrl terminal. MemoryWrite: data flows forward (nbytes on wires), drain at hbm_ctrl terminal.
MemoryRead: command flows forward (nbytes=0), hbm_ctrl sends data back on MemoryRead: command flows forward (nbytes=0), hbm_ctrl sends data back on
+1 -1
View File
@@ -287,7 +287,7 @@ def _generate_probe_d2h(graph, edge_map) -> list[dict]:
def _generate_probe_pe_dma(graph, edge_map) -> list[dict]: def _generate_probe_pe_dma(graph, edge_map) -> list[dict]:
"""PE DMA probes: pe_dma → xbar → HBM.""" """PE DMA probes: pe_dma → router mesh → HBM."""
from kernbench.policy.address.phyaddr import PhysAddr from kernbench.policy.address.phyaddr import PhysAddr
from kernbench.policy.routing.router import AddressResolver, PathRouter from kernbench.policy.routing.router import AddressResolver, PathRouter
+91 -97
View File
@@ -385,6 +385,55 @@ def _escape(text: str) -> str:
return text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;") return text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
# ── Connector helper ─────────────────────────────────────────────────
def _connector_points(
rx: float, ry: float, cx: float, cy: float
) -> str:
"""Return SVG polyline points for a rule-based connector.
Horizontal-dominant (|dx| >= |dy|): 45° → horizontal straight → 45°.
Vertical-dominant (|dy| > |dx|): 45° → vertical straight → 45°.
Near-equal or tiny distance: single straight line.
"""
dx = cx - rx
dy = cy - ry
adx, ady = abs(dx), abs(dy)
# Trivial distance → single line
# Near-45° diagonal for short distances only (e.g. PE↔router)
if adx + ady < 4 or (abs(adx - ady) < 4 and adx + ady < 80):
return f"{rx:.0f},{ry:.0f} {cx:.0f},{cy:.0f}"
sx = 1 if dx >= 0 else -1
sy = 1 if dy >= 0 else -1
if adx >= ady:
# Horizontal-dominant: stubs handle vertical, straight is horizontal
stub = ady / 2
if stub < 2:
return f"{rx:.0f},{ry:.0f} {cx:.0f},{cy:.0f}"
r45x = rx + sx * stub
r45y = ry + sy * stub
c45x = cx - sx * stub
c45y = cy - sy * stub # r45y == c45y (horizontal)
else:
# Vertical-dominant: stubs handle horizontal, straight is vertical
stub = adx / 2
if stub < 2:
return f"{rx:.0f},{ry:.0f} {cx:.0f},{cy:.0f}"
r45x = rx + sx * stub
r45y = ry + sy * stub
c45x = cx - sx * stub
c45y = cy - sy * stub # r45x == c45x (vertical)
return (
f"{rx:.0f},{ry:.0f} {r45x:.0f},{r45y:.0f} "
f"{c45x:.0f},{c45y:.0f} {cx:.0f},{cy:.0f}"
)
# ── Cube-specific renderer ────────────────────────────────────────── # ── Cube-specific renderer ──────────────────────────────────────────
@@ -637,55 +686,39 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
f'text-anchor="middle" font-family="monospace" font-size="{font_sz}" ' f'text-anchor="middle" font-family="monospace" font-size="{font_sz}" '
f'font-weight="bold" fill="{style["text"]}">{_escape(label)}</text>' f'font-weight="bold" fill="{style["text"]}">{_escape(label)}</text>'
) )
# Connector: router ─45°─ straight45°─ component # Connector: rule-based (short → 45° line, long → 45°-straight-45°)
sc = style["stroke"] sc = style["stroke"]
d = 12 # 45° stub length (px)
# Determine start (router edge) and end (component edge) points
bxc = bx + blk_w / 2 # component center x
if kind == "mcpu": if kind == "mcpu":
# Router top → 45° NW stub → vertical → 45° into block bottom rx0, ry0 = px, py - r_size # router top
rx2, ry2 = px, py - r_size cx0, cy0 = bxc, by + blk_h # component bottom
bxc, byc = bx + blk_w / 2, by + blk_h
parts.append(
f' <polyline points="'
f'{rx2:.0f},{ry2:.0f} {rx2 - d:.0f},{ry2 - d:.0f} '
f'{rx2 - d:.0f},{byc + d:.0f} {bxc:.0f},{byc:.0f}" '
f'fill="none" stroke="{sc}" stroke-width="1" opacity="0.6"/>'
)
elif kind == "sram": elif kind == "sram":
# Router bottom → 45° SW stub → vertical → 45° into block top rx0, ry0 = px, py + r_size # router bottom
rx2, ry2 = px, py + r_size cx0, cy0 = bxc, by # component top
bxc, byc = bx + blk_w / 2, by elif is_top:
rx0, ry0 = px, py - r_size # router top
cx0, cy0 = bx + blk_w / 2 + offset_x, by + blk_h # component bottom
else:
rx0, ry0 = px, py + r_size # router bottom
cx0, cy0 = bx + blk_w / 2 + offset_x, by # component top
# PE/M_CPU/SRAM directly above/below router (same X):
# single diagonal line from router center to component right edge
if abs(cx0 - rx0) < 2 and abs(cy0 - ry0) > 4:
cx0 = bx + blk_w - 2
parts.append( parts.append(
f' <polyline points="' f' <line x1="{rx0:.0f}" y1="{ry0:.0f}" '
f'{rx2:.0f},{ry2:.0f} {rx2 - d:.0f},{ry2 + d:.0f} ' f'x2="{cx0:.0f}" y2="{cy0:.0f}" '
f'{rx2 - d:.0f},{byc - d:.0f} {bxc:.0f},{byc:.0f}" ' f'stroke="{sc}" stroke-width="1" opacity="0.6"/>'
f'fill="none" stroke="{sc}" stroke-width="1" opacity="0.6"/>'
) )
else: else:
# PE: vertical direction pts = _connector_points(rx0, ry0, cx0, cy0)
bxc = bx + blk_w / 2 + offset_x parts.append(
if is_top: f' <polyline points="{pts}" '
rx2, ry2 = px, py - r_size # router top f'fill="none" stroke="{sc}" stroke-width="1" opacity="0.6"/>'
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' <polyline points="'
f'{rx2:.0f},{ry2:.0f} {rx2 + sd:.0f},{ry2 - d:.0f} '
f'{rx2 + sd:.0f},{byc + d:.0f} {bxc:.0f},{byc:.0f}" '
f'fill="none" stroke="{sc}" stroke-width="1" opacity="0.6"/>'
)
else:
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' <polyline points="'
f'{rx2:.0f},{ry2:.0f} {rx2 + sd:.0f},{ry2 + d:.0f} '
f'{rx2 + sd:.0f},{byc - d:.0f} {bxc:.0f},{byc:.0f}" '
f'fill="none" stroke="{sc}" stroke-width="1" opacity="0.6"/>'
)
# (PE→HBM BW annotation drawn in the PE→HBM port group section above) # (PE→HBM BW annotation drawn in the PE→HBM port group section above)
@@ -705,26 +738,13 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
rpx, rpy = mm2px(rx, ry) rpx, rpy = mm2px(rx, ry)
tgx, tgy = _pe_hbm_targets[pe_id] tgx, tgy = _pe_hbm_targets[pe_id]
r_edge_y = rpy + r_size if rpy < hbm_y else rpy - r_size r_edge_y = rpy + r_size if rpy < hbm_y else rpy - r_size
# 45° stub from router → vertical → 45° into HBM port # Rule-based connector: router → HBM port group
d = 12 # stub length pts = _connector_points(rpx, r_edge_y, tgx, tgy)
sx = tgx - rpx parts.append(
sd = d if sx >= 0 else -d f' <polyline points="{pts}" '
if rpy < hbm_y: f'fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" '
parts.append( f'stroke-dasharray="4,3"/>'
f' <polyline points="' )
f'{rpx:.0f},{r_edge_y:.0f} {rpx + sd:.0f},{r_edge_y + d:.0f} '
f'{rpx + sd:.0f},{tgy - d:.0f} {tgx:.0f},{tgy:.0f}" '
f'fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" '
f'stroke-dasharray="4,3"/>'
)
else:
parts.append(
f' <polyline points="'
f'{rpx:.0f},{r_edge_y:.0f} {rpx + sd:.0f},{r_edge_y - d:.0f} '
f'{rpx + sd:.0f},{tgy + d:.0f} {tgx:.0f},{tgy:.0f}" '
f'fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.6" '
f'stroke-dasharray="4,3"/>'
)
# BW annotation at midpoint # BW annotation at midpoint
mx = (rpx + tgx) / 2 + 10 mx = (rpx + tgx) / 2 + 10
my = (r_edge_y + tgy) / 2 my = (r_edge_y + tgy) / 2
@@ -818,53 +838,27 @@ def _render_cube_view_svg(view: ViewGraph, spec: dict) -> str:
f'{conn}</text>' f'{conn}</text>'
) )
# Connector: router ─45°stub─ straight ─45°stub─ UCIe port # Connector: rule-based router → UCIe port
rpx, rpy = mm2px(crx, cry) rpx, rpy = mm2px(crx, cry)
d = 10
if direction == "N": if direction == "N":
rx, ry = rpx, rpy - r_size rx, ry = rpx, rpy - r_size
tx, ty = lx, cy_box + ch tx, ty = lx, cy_box + ch
sx = tx - rx
sd = d if sx >= 0 else -d
parts.append(
f' <polyline points="'
f'{rx:.0f},{ry:.0f} {rx + sd:.0f},{ry - d:.0f} '
f'{rx + sd:.0f},{ty + d:.0f} {tx:.0f},{ty:.0f}" '
f'fill="none" stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
)
elif direction == "S": elif direction == "S":
rx, ry = rpx, rpy + r_size rx, ry = rpx, rpy + r_size
tx, ty = lx, cy_box tx, ty = lx, cy_box
sx = tx - rx
sd = d if sx >= 0 else -d
parts.append(
f' <polyline points="'
f'{rx:.0f},{ry:.0f} {rx + sd:.0f},{ry + d:.0f} '
f'{rx + sd:.0f},{ty - d:.0f} {tx:.0f},{ty:.0f}" '
f'fill="none" stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
)
elif direction == "W": elif direction == "W":
rx, ry = rpx - r_size, rpy rx, ry = rpx - r_size, rpy
tx, ty = cx + cw, cy_box + ch / 2 tx, ty = cx + cw, cy_box + ch / 2
sy = ty - ry
sd = d if sy >= 0 else -d
parts.append(
f' <polyline points="'
f'{rx:.0f},{ry:.0f} {rx - d:.0f},{ry + sd:.0f} '
f'{tx + d:.0f},{ry + sd:.0f} {tx:.0f},{ty:.0f}" '
f'fill="none" stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
)
elif direction == "E": elif direction == "E":
rx, ry = rpx + r_size, rpy rx, ry = rpx + r_size, rpy
tx, ty = cx, cy_box + ch / 2 tx, ty = cx, cy_box + ch / 2
sy = ty - ry else:
sd = d if sy >= 0 else -d continue
parts.append( pts = _connector_points(rx, ry, tx, ty)
f' <polyline points="' parts.append(
f'{rx:.0f},{ry:.0f} {rx + d:.0f},{ry + sd:.0f} ' f' <polyline points="{pts}" '
f'{tx - d:.0f},{ry + sd:.0f} {tx:.0f},{ty:.0f}" ' f'fill="none" stroke="{c_color}" stroke-width="1" opacity="0.5"/>'
f'fill="none" stroke="{c_color}" stroke-width="1" opacity="0.5"/>' )
)
# ── Legend ── # ── Legend ──
ly = h_px - 35 ly = h_px - 35
+4 -6
View File
@@ -37,7 +37,7 @@ def _hbm_pa(pe_id: int = 0) -> int:
def _node(impl: str, overhead_ns: float = 0.0) -> Node: def _node(impl: str, overhead_ns: float = 0.0) -> Node:
return Node(id="test", kind="xbar", impl=impl, attrs={"overhead_ns": overhead_ns}, pos_mm=None) return Node(id="test", kind="noc_router", impl=impl, attrs={"overhead_ns": overhead_ns}, pos_mm=None)
# ── 1. unknown impl → error ────────────────────────────────────────── # ── 1. unknown impl → error ──────────────────────────────────────────
@@ -55,7 +55,7 @@ def test_registry_unknown_impl_raises_error():
def test_transit_component_yields_overhead_ns(): def test_transit_component_yields_overhead_ns():
"""TransitComponent.run() yields exactly node.attrs['overhead_ns'] ns.""" """TransitComponent.run() yields exactly node.attrs['overhead_ns'] ns."""
node = _node("xbar_v1", overhead_ns=3.0) node = _node("forwarding_v1", overhead_ns=3.0)
comp = TransitComponent(node) comp = TransitComponent(node)
env = simpy.Environment() env = simpy.Environment()
@@ -119,10 +119,9 @@ def test_engine_component_model_latency():
"""MemoryRead D2H latency for local cube0 (4096B). """MemoryRead D2H latency for local cube0 (4096B).
Bypass path (m_cpu bypass): pcie_ep → io_noc → conn → io_ucie → cube_ucie Bypass path (m_cpu bypass): pcie_ep → io_noc → conn → io_ucie → cube_ucie
→ conn → noc → xbar_top → hbm_ctrl.slice0 → conn → router mesh → hbm_ctrl
Path goes through xbar_top (overhead_ns=2.0) instead of per-PE xbar. Path goes through router mesh. Latency must be positive and reasonable.
Latency must be positive and reasonable.
""" """
graph = _graph() graph = _graph()
engine = GraphEngine(graph) engine = GraphEngine(graph)
@@ -134,7 +133,6 @@ def test_engine_component_model_latency():
h = engine.submit(msg) h = engine.submit(msg)
engine.wait(h) engine.wait(h)
_, trace = engine.get_completion(h) _, trace = engine.get_completion(h)
# Verify positive latency; exact value depends on path through xbar_top
assert trace["total_ns"] > 0 assert trace["total_ns"] > 0
+8 -11
View File
@@ -1,18 +1,15 @@
"""Tests for #5+#6 CUBE NOC Router Mesh + Position-Aware XBAR. """Tests for CUBE NOC Explicit Router Mesh (ADR-0019).
Phase 1 verification: all tests FAIL until Phase 2 implements production code.
Key changes verified: Key changes verified:
- Single NOC node per cube with internal router mesh simulation - Explicit router nodes per cube from cube_mesh.yaml (6×6 grid)
- Auto-layout generates cube_mesh.yaml (6x6 grid for n_connections=4) - Auto-layout generates cube_mesh.yaml with PE/UCIe/M_CPU/SRAM attachments
- Position-aware XBAR (top/bottom) replaces per-PE xbar chaining
- Mesh file caching with source_hash change detection - Mesh file caching with source_hash change detection
- Path routing: PE_DMA → NOC → XBAR_top/bot → HBM_CTRL - Path routing: PE_DMA → router mesh → HBM_CTRL
Latency invariant after refactor: Latency invariant:
Local HBM: PE_DMA → Router(overhead) → XBAR → HBM_CTRL Local HBM: PE_DMA → Router(overhead) → HBM_CTRL
Cross-row: PE_DMA → Router → mesh traverse → Router → XBAR → bridge → XBAR → HBM_CTRL Cross-row: PE_DMA → Router → mesh hops → Router → HBM_CTRL
Cross-cube: PE_DMA → Router → mesh → UCIe → ... → mesh → XBAR → HBM_CTRL Cross-cube: PE_DMA → Router → mesh → UCIe → ... → mesh → HBM_CTRL
""" """
import pytest import pytest
-2
View File
@@ -24,7 +24,6 @@ from kernbench.components.builtin import (
IoCpuComponent, IoCpuComponent,
MCpuComponent, MCpuComponent,
PcieEpComponent, PcieEpComponent,
PositionAwareXbarComponent,
SramComponent, SramComponent,
TransitComponent, TransitComponent,
) )
@@ -232,7 +231,6 @@ def test_m_cpu_terminal_no_ctx_completes():
("forwarding_v1", TransitComponent), ("forwarding_v1", TransitComponent),
("noc_v1", TransitComponent), ("noc_v1", TransitComponent),
("ucie_v1", TransitComponent), ("ucie_v1", TransitComponent),
("xbar_v1", PositionAwareXbarComponent),
("pcie_ep_v1", PcieEpComponent), ("pcie_ep_v1", PcieEpComponent),
("io_cpu_v1", IoCpuComponent), ("io_cpu_v1", IoCpuComponent),
("m_cpu_v1", MCpuComponent), ("m_cpu_v1", MCpuComponent),
+3 -3
View File
@@ -1,7 +1,7 @@
"""Tests for H2D writes and PE DMA probe latency invariants. """Tests for H2D writes and PE DMA probe latency invariants.
H2D tests use MemoryWriteMsg (pcie_ep → io_cpu → m_cpu → hbm_ctrl → response). H2D tests use MemoryWriteMsg (pcie_ep → io_cpu → m_cpu → hbm_ctrl → response).
PE DMA tests use PeDmaMsg (direct pe_dma → xbar → hbm_ctrl injection). PE DMA tests use PeDmaMsg (direct pe_dma → router mesh → hbm_ctrl injection).
""" """
from pathlib import Path from pathlib import Path
@@ -118,7 +118,7 @@ def test_h2d_local_cube_cut_through():
"""H2D to local cube with cut-through should be < 50ns for 4096B. """H2D to local cube with cut-through should be < 50ns for 4096B.
Full command path: pcie_ep → io_cpu → ucie → noc → m_cpu Full command path: pcie_ep → io_cpu → ucie → noc → m_cpu
DMA: m_cpu → noc → xbar → hbm_ctrl (drain once at terminal) DMA: m_cpu → router mesh → hbm_ctrl (drain once at terminal)
Plus response path back. Plus response path back.
With store-and-forward each hop would serialize; cut-through keeps it low. With store-and-forward each hop would serialize; cut-through keeps it low.
""" """
@@ -205,7 +205,7 @@ def test_pe_dma_local_bottleneck_hbm():
def test_pe_dma_same_half_bottleneck_hbm(): def test_pe_dma_same_half_bottleneck_hbm():
"""PE DMA pe0→slice1 (same half via xbar_top): bottleneck = HBM effective BW.""" """PE DMA pe0→pe1 HBM (same row via router mesh): bottleneck = HBM effective BW."""
bn = _pe_dma_bottleneck(src_cube=0, src_pe=0, dst_pe=1) bn = _pe_dma_bottleneck(src_cube=0, src_pe=0, dst_pe=1)
expected = _hbm_effective_bw() expected = _hbm_effective_bw()
assert bn == expected, f"Same-half PE DMA bottleneck {bn}, expected {expected}" assert bn == expected, f"Same-half PE DMA bottleneck {bn}, expected {expected}"
+6 -6
View File
@@ -158,9 +158,9 @@ def test_pe_dma_to_router():
def test_command_path_m_cpu_router_pe_cpu(): def test_command_path_m_cpu_router_pe_cpu():
es = _edge_set(_graph()) es = _edge_set(_graph())
cp = "sip0.cube0" cp = "sip0.cube0"
# m_cpu <-> r0c2 (bidirectional command) # m_cpu <-> r1c2 (bidirectional command)
assert (f"{cp}.m_cpu", f"{cp}.r0c2") in es assert (f"{cp}.m_cpu", f"{cp}.r1c2") in es
assert (f"{cp}.r0c2", f"{cp}.m_cpu") in es assert (f"{cp}.r1c2", f"{cp}.m_cpu") in es
# router -> pe_cpu for each PE (command kind) # router -> pe_cpu for each PE (command kind)
assert (f"{cp}.r0c0", f"{cp}.pe0.pe_cpu") in es assert (f"{cp}.r0c0", f"{cp}.pe0.pe_cpu") in es
assert (f"{cp}.r5c5", f"{cp}.pe7.pe_cpu") in es assert (f"{cp}.r5c5", f"{cp}.pe7.pe_cpu") in es
@@ -416,8 +416,8 @@ def test_cube_view_hbm_router():
def test_cube_view_m_cpu_router(): def test_cube_view_m_cpu_router():
"""Cube view: m_cpu connects to its router r0c2.""" """Cube view: m_cpu connects to its router r1c2."""
v = _graph().cube_view v = _graph().cube_view
ves = {(e.src, e.dst) for e in v.edges} ves = {(e.src, e.dst) for e in v.edges}
assert ("m_cpu", "r0c2") in ves assert ("m_cpu", "r1c2") in ves
assert ("r0c2", "m_cpu") in ves assert ("r1c2", "m_cpu") in ves
+2 -2
View File
@@ -55,7 +55,7 @@ cube:
ucie_mm: { size: 2.0 } ucie_mm: { size: 2.0 }
pe_layout: pe_layout:
corners: [NW, NE, SW, SE] # N corners → xbar top row; S corners → xbar bottom row corners: [NW, NE, SW, SE] # N corners → top PE rows; S corners → bottom PE rows
pe_per_corner: 2 # total PEs per cube: 4 * 2 = 8 pe_per_corner: 2 # total PEs per cube: 4 * 2 = 8
pe_template: pe_template:
@@ -97,7 +97,7 @@ cube:
# Physical placement of non-PE components (mm coordinates) # Physical placement of non-PE components (mm coordinates)
placement: placement:
m_cpu: { pos_mm: [7.5, 2.0] } # top center area, near UCIe-N m_cpu: { pos_mm: [7.5, 3.0] } # top center, below UCIe-N
sram: { pos_mm: [1.5, 9.0] } # left side, below HBM zone sram: { pos_mm: [1.5, 9.0] } # left side, below HBM zone
ucie: ucie: