ICR Node-Fabric DMA Band
地址适用于 libtpu-0.0.40-cp314 wheel 中的
libtpu.so。其他版本会不同。二进制:extracted/libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so(build-id89edbbe81c5b328a958fe628a9f2207d,buildlibtpu_lts_20260413_b_RC00;.textVMA == file offset,base0xe63c000;.data.rel.roVMA −0x200000= file offset)。所有地址都是 VMA。Demangled 名称和偏移已与 IDA 反编译交叉核对。
摘要
本页记录 ICR(inter-chip-router)Node-Fabric DMA band:四个设备 trace-point ID:48, 50, 51, 91。deepsea DMA-timeline 生产者以这些 ID 为键重建一次 node-fabric DMA 传输,并把每个 ID 的 payload 路由进两个以 dma_id 为键的 map 之一,最终成为 "ICI Ingress" / "ICI Egress" 时间线 span。
ICR 位于片上网络边缘:它是接收暂存的 Node-Fabric DMA 描述符(由 Tensor Core Sequencer 发出),并将其字节 向外 推送到 ICI router(egress),或接收从 router 到达的 ICI data packet 并将其 本地 落地(ingress)的引擎。硬件在这条路径上发出四个不同的 trace point。生产者 ConvertTpuTraceToXPlane<pxc> 读取线上的 ID,按 ID 分派,从消息的 trace_id_header 中提取 38-bit dma_id,并把 {begin_gtc, end_gtc, byte_count} 累积到每个 dma_id 的槽位中。四个 ID 清晰分组:91 + 50 形成 egress span,48 + 51 形成 ingress span。
整个 band 的核心是三点,重新实现者必须全部做对:
- band-ID → message-class → producer-role 表。 四个 ID 各自携带 不同 的 protobuf 消息,并在 begin/end span 中扮演 不同 角色(begin marker、end marker、byte-count source,或二者兼具)。
byte_count累积规则。 OCI-message 一侧(ID 51)加上msg_data << 9(固定 512-byte OCI message 粒度);descriptor 一侧(ID 91)加上length << {9 or 2},移位由 descriptor 自身的length_granuleenum 选择。descriptor 的byte_count来源是length,不是program_counter。- 两个 map 的 egress/ingress 分离。 两个独立的、以
dma_id为键的flat_hash_map<uint64, DmaTransfer>分别保存 egress 集合(IDs 50 + 91 → lane 55 "To ICI Router")和 ingress 集合(IDs 48 + 51 → lane 54 "From ICI Router");span 的 kind tag(3 egress / 2 ingress)由它落入哪个 map 固定决定。
**范围:**线上的
nf_descriptor记录布局(ICR 消费的暂存 descriptor)见nf-descriptor.md。这些 span 如何渲染为事件/统计信息的 XPlane 侧解码见../profiling/icr-dma-timeline-band.md。本页负责 ICR DMA band ID、48/50/51/91 payload 解码,以及生产者中的 ICR route path。
| Band IDs | 48, 50, 51, 91(仅有的四个 DMA-timeline source ID) |
| 生产者 | ConvertTpuTraceToXPlane<pxc::…::TraceEntry>{lambda} @0xf26c6e0 |
| GetMerged ID 集合 | {91, 50, 48, 51}:打包的 0x320000005B @0xf26c7bf,扩展 48/51 |
dma_id 提取器 | TraceEntryWrapper<pxc>::GetDmaId(int) @0xf699ca0(单一调用者) |
dma_id 宽度 | 38 bits = txn_id[0:21] | (core_id&7)<<21 | (chip_id&0x3fff)<<24 |
| Egress map → span | IDs 50 + 91 → tag 3 → lane 55 "To ICI Router" / "ICI Egress" |
| Ingress map → span | IDs 48 + 51 → tag 2 → lane 54 "From ICI Router" / "ICI Ingress" |
| 渲染器 | ConvertDmaTransfersToXPlane @0xf254bc0 |
| 证据等级 | 重新实现级 / 已确认(字节锚定) |
1. 四个 band ID 及其消息
生产者不会为 DMA 时间线查看 OCI command band(IDs 22/26/96,即 OciCommon* write/read commands):该 band 可由 GetDmaId 解码,但本 pass 没有调用者以它为键。DMA 时间线完全由下方四个 ID 构建,这些 ID 从 trace-entry 子消息的 trace_point_id 字段读取(0xf26c8fb 处分派中的 ecx = [submsg + 0x18])。
每个 ID 都映射到 asic_sw::driver::deepsea::pxc::profiler 命名空间中的一个 protobuf message class,由生产者在信任 entry + 0x20 处的 live message 指针前于 entry + 0x28 验证的 oneof case 标识(否则回退到 *_globals_ prototype)。这些 oneof case 已在 GetDmaId 和生产者中共同确认。
| ID | Message class(pxc::profiler::) | oneof | Globals prototype | 生产者角色 |
|---|---|---|---|---|
| 48 | IciPacketDataPacketQueuedForLocalIngress | 29 (0x1d) | …_globals_ | BEGIN + END markers(ingress) |
| 50 | OciMessageGeneratedInIcrEgressDma | 31 (0x1f) | …_globals_ | 仅 END_GTC(egress,受 done == 1 门控) |
| 51 | OciMessageGeneratedInIcrIngressDma | 32 (0x20) | …_globals_ | BYTE_COUNT msg_data << 9(ingress) |
| 91 | OciDescriptorCommonIssuedFromTcs | 48 (0x30) | …_globals_ | BEGIN_GTC + BYTE_COUNT length << g(egress) |
这些
oneofcase 在GetDmaId(0xf699ca0)中按字节精确确认:case 48 → [rdi+0x28]==0x1d、case 50 → 0x1f、case 51 → 0x20、case 91 → 0x30。生产者在各个 per-ID 分支中重新检查相同 case(*(_DWORD)(v16+40)= 子消息oneofdiscriminator)。四个消息都把trace_id_header放在 cpp-offset0x18(field 1),因此整个 band 的dma_id提取是统一的。
四个 ID 在生产者序言中组装为 GetMerged 请求集合:
movabs rax, 0x320000005B @0xf26c7bf ; packs {91 = 0x5B, 50 = 0x32}
mov DWORD [r15+0x8], 0x30 @0xf26c7d9 ; 48
mov DWORD [r15+0xc], 0x33 @0xf26c7ff ; 51
call GetMerged @0xf26ba80 @0xf26c81d ; size-4 set {91, 50, 48, 51}
```text
(在反编译中,这是生产者第 117/119/124 行的单个 store:`*v9 = 0x320000005B; v10[2] = 48; v10[3] = 51;`。)
---
## 2. per-ID payload 解码
下面的字段偏移是 C++ 内存布局(`cpp_offset`,取自每个消息的 `TcParseTable` FieldEntry 行,步长 `0x10`,`cpp_offset` 位于 row+6),字段名由 carved descriptor pool 确认。只有加粗字段会被 DMA pass 读取;其余字段会被解码进 proto,但被该生产者 **丢弃**(它只保留从 `trace_id_header` 派生出的 `dma_id`、GTC 时间戳和大小)。
### 2.1 ID 48:`IciPacketDataPacketQueuedForLocalIngress`(9 个字段)
已经从 router 到达并排队等待本地落地的 ICI data packet。它是唯一通过两个尾部 bool 标志向 ingress span 同时提供 **begin** 和 **end** 时间戳的 ID;C++ 将这两个标志打包在 `+0x32` / `+0x33`。
| 字段 | 名称 | cpp off | 角色 |
|-------|------|---------|------|
| f1 | `trace_id_header` | `0x18` | `dma_id` 来源 |
| f2 | `router_link_port_id` | `0x20` | (丢弃) |
| f3 | `virtual_channel` | `0x24` | (丢弃) |
| f4 | `link_targets` | `0x28` | (丢弃) |
| f5 | `local_ingress_target` (bool) | `0x30` | (丢弃) |
| f6 | `multicast` (bool) | `0x31` | (丢弃) |
| f7 | `dst_chip_id` | `0x2c` | (丢弃) |
| f8 | **`first_packet_in_dma`** (bool) | `0x32` | **BEGIN marker** |
| f9 | **`last_packet_in_dma`** (bool) | `0x33` | **END marker** |
> **注意:**单个 ID-48 事件可以同时设置 *两个* marker(同一 packet 上 `first` 和 `last` 都为 true),从而生成一个自包含的 ingress span。在反编译中,这是 `if (*((_BYTE*)v27 + 50) == 1) {begin…}` 然后 `if (*((_BYTE*)v27 + 51) == 1) {end…}`(偏移 `0x32` = decimal 50,`0x33` = 51)。
### 2.2 IDs 50 / 51:`OciMessageGeneratedInIcr{Egress,Ingress}Dma`(7 个字段,布局相同)
ICR 在将 DMA 向外移动(egress,ID 50)或向内移动(ingress,ID 51)时生成的 OCI message。两者字段布局相同;生产者对它们做非对称处理(见 §4)。
| 字段 | 名称 | cpp off | 角色 |
|-------|------|---------|------|
| f1 | `trace_id_header` | `0x18` | `dma_id` 来源 |
| f2 | **`msg_data`** (uint32) | `0x20` | **BYTE_COUNT 来源**(ID 51) |
| f3 | **`done`** (bool) | `0x24` | **END 门控**(ID 50,`done == 1`) |
| f4 | `msg_type` (enum) | `0x28` | `{PRIVATE, PUBLIC}`(丢弃) |
| f5 | `opcode` (enum) | `0x2c` | `{WRITE_NO_DONE, WRITE_WITH_DONE, INC_NO_DONE, INC_WITH_DONE}`(丢弃) |
| f7 | `node_type` (enum) | `0x30` | `0..6 = TCS/BC/CMQ/HBMQ/UHI/ICR/QNM`(payload 标签,**不是** line key;丢弃) |
| f6 | `addr` (uint32) | `0x34` | (丢弃) |
### 2.3 ID 91:`OciDescriptorCommonIssuedFromTcs`(17 个字段)
由 Tensor Core Sequencer 发出的暂存 Node-Fabric DMA descriptor,即 egress 发送侧。这是 [`nf_descriptor`](nf-descriptor.md) 记录的片上类似物;它携带完整的 src/dst endpoint 和三个 sync-flag target,但 DMA pass 只读取 gate、size 和 granule。
| 字段 | 名称 | cpp off | 角色 |
|-------|------|---------|------|
| f1 | `trace_id_header` | `0x18` | `dma_id` 来源 |
| f2 | **`dma_type`** (enum) | `0x20` | **GATE**(`== DMA_TYPE_REMOTEUNICAST = 2`) |
| f3..f8 | `src_mem_*` / `dst_mem_*` / `*_opcode` | `0x24`..`0x38` | endpoint(丢弃) |
| f9..f14 | `src_sync_flag_*` / `dst_sync_flag_{0,1}_*` | `0x3c`..`0x50` | sync target(丢弃) |
| f15 | `program_counter` | `0x54` | (丢弃) |
| f16 | **`length`** (uint32) | `0x58` | **BYTE_COUNT 来源** |
| f17 | **`length_granule`** (enum) | `0x5c` | **SHIFT 选择器** |
Enums:`DmaTypeValues {LOCAL=0, CHIP2HOST=1, REMOTEUNICAST=2, REMOTEMULTICAST=3}`;`LengthGranuleValues {LENGTH_GRANULE_512B=0, LENGTH_GRANULE_4B=1}`。
> **小心:**C++ 内存顺序是 `program_counter`(`0x54`)、`length`(`0x58`)、`length_granule`(`0x5c`),也就是 `_InternalParse` 字段顺序。生产者的 `byte_count` 读取 `0x58`(`length`),**不是** `0x54`(`program_counter`)。反编译中的字段索引:`*((unsigned int*)v25 + 22)` = `0x58` = `length`;`*((_DWORD*)v25 + 23)` = `0x5c` = `length_granule`。
---
## 3. ICR 路由路径(生产者分派)
对于每个 merged trace entry,生产者先计算 `dma_id` key,然后按 ID 分派,应用该 ID 的 gate,在相应 map 中查找或插入 `dma_id` 槽位,并写入它的贡献。分派和 `dma_id` 提取发生在 per-ID 分支 **之前**,所以非 DMA entry(没有 `dma_id`)会被提前丢弃。
```text
ConvertTpuTraceToXPlane<pxc>{lambda} @0xf26c6e0
│
├─ GetMerged({91,50,48,51}) @0xf26c81d
│
└─ for each merged entry:
gtc = TraceHeader.timestamp (f3, @hdr+0x20) @0xf26c8cd (rbx)
dma_id = GetDmaId(entry, selector=0) @0xf26c8d9 → §3.1
if (dma_id.present == 0) drop @0xf26c8de (test dl,1)
key = dma_id @0xf26c8e7 ([rbp-0x38])
id = trace_entry_submsg.trace_point_id (@+0x18) @0xf26c8fb
switch (id):
91 → gate dma_type==2 → MAP_A.find_or_insert(key) → begin_gtc + byte_count(length<<g) + tag=3
50 → gate done==1 → MAP_A.find_or_insert(key) → end_gtc
48 → MAP_B.find_or_insert(key) → {begin_gtc if first, end_gtc if last} + tag=2
51 → MAP_B.find_or_insert(key) → byte_count += msg_data<<9
on a slot that already has begin_present && end_present → flush (push_back to the map's vector,
clear present flags) then reopen3.1 38-bit dma_id 提取
GetDmaId(int)(0xf699ca0)有 恰好一个调用者(0xf26c8d9 处的生产者,以 selector = 0 调用),这是通过完整 .text e8-rel32 扫描证明的。对于四个 band ID,每个 switch 分支都会验证 oneof([rdi+0x28]),加载 live message 的 trace_id_header(每个消息的 field 1,位于 +0x18),并汇合到共同尾部来组合 38-bit ID:
eax = trace_id_header.transaction_id (@hdr+0x18)
edx = trace_id_header.core_id (@hdr+0x1c)
ecx = trace_id_header.chip_id (@hdr+0x20)
dma_id = (transaction_id & 0xFF) // bits 0:8 (movzx al)
| (transaction_id & 0x1FFF00) // bits 8:21
| ((core_id & 7) << 21) // bits 21:24
| ((chip_id & 0x3FFF) << 24) // bits 24:38
present = 1
```text
在反编译中(LABEL_172):`v4 = (transaction_id & 0x1FFF00) | ((core_id & 7) << 21) | ((chip_id & 0x3FFF) << 24); return v4 | (uint8)transaction_id;`。`chip_id` mask 为 14 bits;结果宽度为 38 bits。`oneof` 不匹配会回退到每个 ID 的 `TraceIdHeader` globals,若其为空,则回退到共享的全零 `TraceIdHeader_globals_`(`dma_id == 0`)。
### 3.2 per-ID store block(字节精确)
> **ID 91(egress,MAP_A):begin + bytes:**位于 LABEL_9(`0xf26c865`):
> `slot[+0x8] = gtc; slot[+0x10] = 1 (begin_present); shift = (length_granule == 0) ? 9 : 2; slot[+0x28] = length << shift; slot[+0x40] = 3 (tag)`。
> 反编译:`v15 = 2; if (!*((_DWORD*)v25 + 23)) v15 = 9; _R15[5] = (uint64)*((uint*)v25 + 22) << v15; *((_DWORD*)_R15 + 16) = 3;`。`byte_count` 用 `mov` 写入(覆盖),因为 descriptor begin 会先把槽位清零初始化(`+0x8`/`+0x28`/`+0x40` 处的 `vpxor`/`vmovdqu ymm0` clear)。
>
> **ID 50(egress,MAP_A):仅 end:**受 `done == 1` 门控(`*((_BYTE*)v24 + 36) == 1`,`0x24`)。存储 `slot[+0x18] = gtc (end_gtc); slot[+0x20] = 1 (end_present)`。没有 begin,没有 bytes;只有 *已完成* 的 egress message 才贡献 end timestamp。
>
> **ID 48(ingress,MAP_B):两个 marker:**`if (first_packet_in_dma == 1)` → `slot[+0x8] = gtc; slot[+0x10] = 1; slot[+0x28] = 0; slot[+0x40] = 2`。`if (last_packet_in_dma == 1)` → `slot[+0x18] = gtc; slot[+0x20] = 1; tag = 2`。
>
> **ID 51(ingress,MAP_B):仅 bytes:**`slot[+0x28] += msg_data << 9`。反编译:`*(_QWORD*)(_RDX + 40) += (uint)(*((_DWORD*)v29 + 8) << 9);`(`*((_DWORD*)v29 + 8)` = `+0x20` = `msg_data`)。这是累加(`+=`),不是覆盖,因此同一 `dma_id` 上的多个 ingress message 会求和。没有 GTC store。
---
## 4. `byte_count` 累积规则
`byte_count` 位于 map-value 槽位 `+0x28`(以及 merged-span 形式的 `+0x20`)。它会在同一 `dma_id` 事件之间 **累积**;但 descriptor begin 例外,它会用 `mov` 写入一个刚刚清零初始化的槽位。存在两套不同的缩放规则:
| 侧 | ID | 来源字段 | 缩放 | 生产者位置 | 粒度含义 |
|------|----|--------------|-------|---------------|-----------------|
| OCI | 51 | `msg_data`(f2,`+0x20`) | `<< 9`(×512,固定) | `0xf26cedb` | 512-B OCI message line |
| OCI | 50 | —(仅 end_gtc) | — | — | — |
| descr | 91 | `length`(f16,`+0x58`) | `<< (granule==0 ? 9 : 2)` | `0xf26c880` | 见 `length_granule` |
| ICI | 48 | —(仅 marker) | — | — | — |
**OCI message 粒度(ID 51)。** OCI message 长度单位固定为 512 B(OCI message 中没有 granule 字段),因此 `byte_count += msg_data × 512`。ID 50 携带 *相同* 的 `msg_data` 字段,但生产者把它路由到 end-GTC store;egress 一侧的 bytes 来自 descriptor(ID 91),不是 egress message。
**descriptor 粒度(ID 91)。** 移位由 descriptor 自身的 `length_granule` 选择:
```text
length_granule == 0 (LENGTH_GRANULE_512B) → shift 9 → length × 512 (512-byte granules)
length_granule == 1 (LENGTH_GRANULE_4B) → shift 2 → length × 4 (4-byte words)陷阱:
+0x58来源是length(f16),不是program_counter;program_counter(f15)位于+0x54,在该路径上未被读取。512-B / 4-B 粒度含义来自LengthGranuleValuesenum,而不是移位幅度。
为什么 ID 91 覆盖而 ID 51 累加。 ID 91 是 descriptor begin:它先把槽位清零,然后写入 byte_count = length << g。ID 51 是进入某个槽位的 OCI-message arrival,该槽位可能已经持有 descriptor 的 begin(egress 情况)或先前的 ingress message,因此它做 +=。实践中两者从不共享槽位:ID 91/50 落入 MAP_A,ID 48/51 落入 MAP_B。
5. 两个 map 的 egress/ingress 分离及其渲染的 span
生产者维护 两个独立的 flat_hash_map<uint64, DmaTransfer>,均以 dma_id 为键(policy FlatHashMapPolicy<unsigned long, DmaTransfer>;通过 PrepareInsertSmallNonSoo / PrepareInsertLarge 插入;key 由 HashKey<Hash<unsigned long>> 哈希)。四个 ID 按方向划分到它们:
| Map | 内容 | Begin 来源 | End 来源 | Bytes | Flush → vector | Tag | Lane |
|---|---|---|---|---|---|---|---|
| MAP_A(egress) | 91 descriptor + 50 egress msg | ID 91(descriptor) | ID 50(egress msg,done==1) | ID 91 length×g | vec_A | 3 | 55 "To ICI Router" |
| MAP_B(ingress) | 48 ICI packet + 51 ingress msg | ID 48 first_packet | ID 48 last_packet | ID 51 msg_data×512 | vec_B | 2 | 54 "From ICI Router" |
当一个槽位在已经同时持有 begin_present 和 end_present 时再次被触碰,生产者会把已完成的 DmaTransfer push_back 到该 map 的输出 vector,并清除 present 标志(flush-and-reopen),因此复用的 dma_id 会打开一个新的 span。配对 key 始终是 38-bit dma_id:descriptor begin(MAP_A)与共享 dma_id 的 egress-message end 配对;ICI first-/last-packet marker(MAP_B)与共享 dma_id 的 ingress-message bytes 配对。
5.1 渲染(lane + XEvent)
ConvertDmaTransfersToXPlane(0xf254bc0)消费每个 vector,并把 GTC span 发射到 TPU component lane,按 kind tag 分支:
GetOrCreateLine(63) → MemcpyH2D (host DMA, unused on pxc ICR band)
GetOrCreateLine(64) → MemcpyD2H (host DMA, unused on pxc ICR band)
GetOrCreateLine(54) → TpuComponentName(54) = "From ICI Router" ← ingress
GetOrCreateLine(55) → TpuComponentName(55) = "To ICI Router" ← egress
EventMetadata("ICI Ingress", 11) ← tag 2
EventMetadata("ICI Egress", 10) ← tag 3
…
duration = end_gtc − begin_gtc; if (end <= begin) skip; AddEvent(line, begin, duration)
```text
kind tag 选择分支:tag 2 → lane 54 / "ICI Ingress",tag 3 → lane 55 / "ICI Egress"(tags 4/5 跳过;6/7 是 host-DMA Memcpy 分支,本 band 不使用)。没有 begin 的 span(在其 map 中没有先前 begin 的 end/byte-count 事件)会保留清零初始化的 `tag == 0` 并被丢弃(`tag - 2; if (above) skip`)。
> **方向检查:**Ingress(数据 *从* ICI router 到达)= ID 48 `…QueuedForLocalIngress` + ID 51 `…GeneratedInIcrIngressDma` → lane 54 "From ICI Router"。Egress(数据离开并前往 router)= ID 50 `…GeneratedInIcrEgressDma` + ID 91 descriptor `…IssuedFromTcs`(发送侧)→ lane 55 "To ICI Router"。lane 名称与四个 trace point 的线上方向一致。
---
## 6. 结构体 / 表偏移(参考)
> **`DmaTransfer`**(map value,alloc `0x58` = 88 B):`+0x0` `dma_id`(key)· `+0x8` `begin_gtc` · `+0x10` `begin_present`(bool)· `+0x18` `end_gtc` · `+0x20` `end_present`(bool)· `+0x28` `byte_count` · `+0x40` kind tag(uint32,2 | 3)。merged-span 形式是 map-value `+0x8`:`+0x0` `begin_gtc`(sort key)· `+0x8` `begin_present` · `+0x10` `end_gtc` · `+0x18` `end_present` · `+0x20` `byte_count` · `+0x38` kind tag。
>
> **`TraceHeader`**(pxc):`trace_point_id` `+0x18` · `block_id` `+0x1c` · `timestamp`(uint64)`+0x20`。
> **`TraceIdHeader`**(pxc):`transaction_id` `+0x18` · `core_id` `+0x1c` · `chip_id` `+0x20`。
>
> **关键位置:**producer `0xf26c6e0` · GetMerged `0xf26ba80`(调用于 `0xf26c81d`)· `GetDmaId` `0xf699ca0`(单一调用者 `0xf26c8d9`)· id-91 begin `0xf26c865` · id-51 bytes `0xf26cedb` · id-50 end `0xf26cf41` · id-48 markers `0xf26ce60`/`0xf26ce85` · renderer `0xf254bc0` · `AddEvent(GtcSpan)` `0xf1df1e0`。
---
## 7. 该 band 不会带入 span 的内容
> **注意:**此 DMA pass 会丢弃除 `trace_id_header`(→ `dma_id`)、GTC 时间戳和大小之外的所有 payload 字段。ID-48 的 `router_link_port_id` / `virtual_channel` / `link_targets`,以及 ID-91 的 src/dst mem-id、core-id、opcode 和三个 sync-flag target 会被解码到 proto 中,但 **不会** 在 pxc 上复制到 `DmaTransfer` span;它们必须由单独的 XPlane pass 渲染。pxc span 只携带 `{begin, end, bytes, tag}`。精确的时间顺序(对于一个 `dma_id`,ID-91 begin 是否总是在匹配的 ID-50 end 之前?)是运行时属性,静态解码无法证明;flush-and-reopen 逻辑会处理再次触碰已完整槽位的情况。
该精确四 ID 生产者在每代(vfc/vlc/glc/gfc)上的等价物超出本文范围:`GetDmaId(int)` 仅限 pxc template,较新世代把 DMA band 折叠进一个(可能内联的)按家族区分的生产者,并使用更宽的 ID。`{48,50,51,91}` key set 以及 `msg_data×512` / `length×granule` byte-count 规则是否跨世代不变,尚未验证。
---
## 交叉引用
- [`nf-descriptor.md`](nf-descriptor.md):线上的 Node-Fabric DMA descriptor 记录(ID-91 追踪的暂存 descriptor)。
- [`overview.md`](overview.md):ICI routing section map;route table 和 net_router schedule 如何供给本 band 所观察的 ICI DMA 层。
- [`net-router-pipeline.md`](net-router-pipeline.md):驱动本 band 计时传输的 per-collective DMA program。
- [`route-table-generation.md`](route-table-generation.md):ICR auto-route 查询的每链路路由表。
- [`../profiling/icr-dma-timeline-band.md`](../profiling/icr-dma-timeline-band.md):48/50/51/91 span 的 XPlane 侧渲染(lanes 54/55,"ICI Ingress" / "ICI Egress" events)。
- [`../profiling/payload-uhi-oci-ici-dma.md`](../profiling/payload-uhi-oci-ici-dma.md):这些消息所属的 OCI/ICI DMA trace-point payload catalog。
- [`../dma/intra-chip-descriptor.md`](../dma/intra-chip-descriptor.md):该跨芯片 node-fabric 路径的片内 descriptor 对应物。