每代远程 SFLAG 编码器
此页上的每个地址、偏移量、立即数、位移位和字符串都是从
libtpu-0.0.40-cp314轮中的libtpu.so中精确读取字节的(构建libtpu_lts_20260413_b_RC00,BuildID md589edbbe81c5b328a958fe628a9f2207d;未剥离 — 完整的 C++ 符号)。其他版本有所不同。地址是二进制文件自己的 VMA(.text/.rodataVMA == 文件偏移量;.data.rel.ro文件偏移量 = VMA −0x200000)。
摘要
针对对等芯片的 SFLAG 计数器(ICI 屏障的跨芯片一半)的同步标志写入不能使用本地 SFLAG 编号。对等方的标志位于该芯片的 VMEM 中,通过 ICI 结构到达,并且写入必须携带一个远程地址,该地址同时命名哪个芯片和哪个片上标志。 libtpu 使用一系列功能构建该地址:每芯片一代 *远程同步标志编码器,每个编码器都在单个 FunctionRegistry 中的 tpu::TpuVersion 密钥下注册。本页记录了该系列 - 注册表、五个每代编码器变体及其字节精确位布局、JfDf 编码之前应用的芯片 ID 重新映射 (MapLogicalToPhysicalChipId),以及两者如何组成 VsyncAddRemote 最终写入的跨芯片远程 SFLAG VMEM 地址。
决定性的结构结果是以 TpuVersion 为关键的两户分割。 V1/基于坐标的编码器(JfDf,对于 kJellyfish=0 和 kDragonfish=1)是唯一消耗物理芯片 ID 并支持多播的一代:它在第 20 位打包芯片 X 坐标,在第 21 位打包 MapLogicalToPhysicalChipId 输出,一个 0x40位 12-17 处的同步标志段、位 18 处的固定远程标记以及位 19 处的条件多播位。V2/核心索引相关编码器(Pufferfish=2、Viperfish=3、Ghostlite=4)完全丢弃物理芯片 ID 和多播布尔值;它们将逻辑芯片坐标(Pufferfish 上为 12 位,Viperfish/Ghostlite 上为 14 位)屏蔽到单个字段中,并让接收端 NIU + 路由引擎解析物理布局。 Pufferfish 和 Viperfish/Ghostlite 之间的芯片字段加宽了 12→14 位 — 在 DMA-id 和跟踪芯片 ID 字段中独立见证了相同的每代 pod 地址加宽。
SFLAG number 公式(本地保留块算术)位于 屏障到 SFLAG 的绑定 上;每个代号保留的整数位于 按代号编译器保留 上;跨芯片 data memref(非 SFLAG 内存的类似重新标记)位于 get_remote_memref 上。此页面拥有每代远程 SFLAG 编码器、芯片 ID 映射和远程地址组合。
重新实现,合约为:
- 远程 SFLAG 地址是位封装的 VMEM 字,而不是重新计算的平面指针。 它构建为 LLO 标量操作链(
SimmU32const、SandU32掩码、SshllU32左移、SshrlU32右移、SaddS32在按值LloRegionBuilder上添加、SorU32或);当芯片坐标操作数是编译时常量时,简化器常量折叠。结果用注释"remote sync flag address"标记。 - 调度通过由四个同级静态初始化器填充的
FunctionRegistry在TpuVersion上键入。 五个Register调用(键0/1/2/3/4,跨 jellyfish/pufferfish/viperfish/ghostlite static-init TU 分割)映射到四个不同的编码器(JfDf 由kJellyfish和kDragonfish共享)。未知版本LOG(FATAL)或"Unsupported version: "。 - 只有 JfDf 消耗物理芯片 ID 并支持多播。 调度程序始终运行
MapLogicalToPhysicalChipId并始终将结果 + 对等CoreLocationBase传递给每个编码器,但 V2 包装器丢弃两者并从逻辑坐标重建其芯片字段。河豚LOG(FATAL)s 多播; Viperfish/Ghostlite 默默地丢弃了布尔值。 MapLogicalToPhysicalChipId是纯粹的拓扑坐标变换,而不是 DeviceAssignment 查找。 它通过程序网格将逻辑芯片 ID 非线性化为(row, col, z),通过每核子切片原点进行转换,针对物理芯片边界进行边界检查,并在物理边界上重新线性化 - 馈送 JfDf仅位 21 字段。
| 消费者 | VsyncAddRemote @0x1d522f40 → EncodeRemoteSyncFlagAddress + CreateVectorSyncFlagAddRemote |
| 调度员 | LloRegionBuilder::EncodeRemoteSyncFlagAddress @0x1d54da40 |
| 注册表 | GetRemoteSyncFlagEncoderRegistry()::r @0x2257e488 (FunctionRegistry<tpu::TpuVersion, …>) |
| 注册商 | …_jellyfish.cc @0x2135b720(键 0,1 → JfDf)· …_pufferfish.cc @0x2135bb30(键 2)· …_viperfish.cc @0x2135bc00(键 3)· ghostlite_dma_utils.cc @0x2135be70(键 4)— 对地址注册表进行 5 次 Register 调用,分为 4 个 TU |
| V1 编码器(第 0/1 代) | EncodeRemoteSyncFlagAddressJfDf @0x1d5aa620(基于坐标,物理芯片+组播) |
| V2 编码器(第 2/3/4 代) | pufferfish @0x1d5ae1a0 / viperfish @0x1d5af9c0 / ghostlite @0x1d5affc0(相对核心索引) |
| 芯片 ID 重新映射 | MapLogicalToPhysicalChipId @0x1d519f40(3-D 混合基数;仅限 JfDf) |
| 版本字段 | Target+0x398 (tpu::TpuVersion),来自 [[[builder]+0x38]+0x10]+0x398 |
| SFLAG 段常量 | DefaultSyncFlagSegmentId() @0x1d62da60 = 0x40 |
| 信心 | 已确认(反编译锚定),除非行或标注另有说明 |
1. 编码器所在位置 — VsyncAddRemote 和调度程序
跨芯片同步标志凸点是 LLO 原语 VectorSyncFlagAddRemote。 LloRegionBuilder::VsyncAddRemote @0x1d522f40 是生成它的瘦构建器,它的第一步是对远程地址进行编码:
// VsyncAddRemote(LloValue* sflag, CoreLocationBase const& peer, LloValue* value, bool multicast) // 0x1d522f40
LloValue* addr = EncodeRemoteSyncFlagAddress(this, sflag, peer, multicast); // the per-gen address encode
LloInstruction* inst = LloInstruction::CreateVectorSyncFlagAddRemote(addr, value, /*region=*/*this, …);
return LloRegion::AppendInstruction(*this, inst, 0, …);
```text
因此编码后的地址是远程SFLAG-add指令的操作数0; `value`(增量)和区域是其余的。编码是唯一有趣的工作——下游的所有内容都是简单的指令附加。 (颗粒跨步变体 `VsyncAddRemoteInGranules` @`0x1d54e4e0` 和集合变体 `VsyncSetRemote` @`0x1d54e120` 到达相同的编码器。)
`LloRegionBuilder::EncodeRemoteSyncFlagAddress(LloValue* sflag, CoreLocationBase const& peer, bool multicast)` @`0x1d54da40` 是每代调度程序。从反编译中逐字节重新确认,它运行四个阶段:
```c
function EncodeRemoteSyncFlagAddress(builder, sflag, peer, multicast): // 0x1d54da40
// [1] VALIDATE: sflag must be in the kSflag memory space (or a supported alias).
if ((sflag[+0xb] & 0x7c) != 0x18: // MS kSflag fast path
&& !(target.SupportsRemoteSyncFlagInTpuEmbeddingSpace() // vtable[+0x7b0]
&& ((sflag[+0xb]>>2)&0x1f) ∈ {0x9,0xa}) // kBarnaCoreS{mem,flag}
&& !(target.SupportsSparseCore() // vtable[+0x260]
&& (sflag[+0xb]&0x7c)==0x30)): // kSparseCoreSequencerSflag
RetCheck("remote_sync_flag->memory_space() == MemorySpace::kSflag || …") // + ToMnemonic(sflag)
// [2] REMAP: logical chip-id → physical (JfDf consumes this; V2 ignore it).
phys_chip_id = MapLogicalToPhysicalChipId(builder, peer.CoreLocationBase[+0],
/*operand_name=*/"EncodeRemoteSyncFlagAddress()"/*29 chars*/,
/*multicast=*/false) // 0x1d519f40
// [3] DECOMPOSE peer for the encoder ABI.
x_coord = peer.CoreLocationBase[+8] // the X chip-coord
core_idx = (int)peer.CoreLocationBase[+0x10] // the core index (0x18-byte POD)
// [4] DISPATCH on TpuVersion.
version = Target[+0x398] // [[[builder]+0x38]+0x10]+0x398, tpu::TpuVersion
encoder = GetRemoteSyncFlagEncoderRegistry().Get(version) // 0x1d54e020
if (encoder.empty()): LOG(FATAL) "Unsupported version: " << version // 0x1d54dce9
return encoder(sflag, &x_coord, multicast, phys_chip_id, /*builder copy=*/*this)注意 — 调度程序将
multicast=false传递到MapLogicalToPhysicalChipId(第 2 阶段),无论调用者的multicast参数如何;调用者的multicast仅转发到编码器(第 4 阶段)。重映射自身的多播参数控制其直通条件之一(§4),并且与地址级多播位无关。明白了 — 读取的
Target+0x398版本是注册表项的类型见证。第 8252 行的LOG(FATAL)("Unsupported version: " << LogMessage<tpu::TpuVersion>(…)) 将密钥键入为tpu::TpuVersion,这是注册表未命中时的唯一行为 - 没有回退编码器,因此版本不是五个注册密钥之一的芯片无法发出远程同步标志写入。
2.注册表和五个TpuVersion注册
GetRemoteSyncFlagEncoderRegistry()::r @0x2257e488(guard @0x2257e490)是一个惰性单例 FunctionRegistry<tpu::TpuVersion, LloValue*(LloValue* sflag, CoreLocationBase const&, bool multicast, LloValue* phys_chip_id, LloRegionBuilder)>,内部是一个 absl::flat_hash_map<TpuVersion, shared_ptr<MapValue>>。Get 路径 @0x1d54e020 采用共享互斥体(Mutex::lock_shared),执行 raw_hash_set::find,并在未命中时返回默认的空 std::function(随后由 dispatcher 的 LOG(FATAL) 捕获)。
它填充在四个同级静态初始化 TU 中,每个 TU 在地址注册表中运行一次或两次 FunctionRegistry::Register @0x1d5aa7a0 (r @0x2257e488) — 总共五个注册:
_GLOBAL__sub_I_remote_sync_flag_encoder_jellyfish.cc@0x2135b720寄存器 JfDf @0x1d5aa620两次 — 键1(movl $0x1@0x2135b74d) 然后键0(movl $0x0@0x2135b7be) — 并且还为同级 core-id 和 DMA 覆盖注册表提供种子。_GLOBAL__sub_I_remote_sync_flag_encoder_pufferfish.cc@0x2135bb30为密钥2(movl $0x2@0x2135bb51) 注册 Pufferfish @0x1d5af8a0。_GLOBAL__sub_I_remote_sync_flag_encoder_viperfish.cc@0x2135bc00为密钥3(movl $0x3@0x2135bc21) 注册 Viperfish @0x1d5af900。_GLOBAL__sub_I_ghostlite_dma_utils.cc@0x2135be70为密钥4(movl $0x4@0x2135be95) 注册 Ghostlite @0x1d5b01e0。
TpuVersion 键是第三个 Register 参数(stack-movl 立即数); Register bool 返回被丢弃到每代 kRegister…/kUnused… 全局变量中。
TpuVersion 密钥 | 助记词 | 编码器已注册(注册表包装器) | 算术实现 | 家族 |
|---|---|---|---|---|
| 0 | kJellyfish | EncodeRemoteSyncFlagAddressJfDf @0x1d5aa620 | (基于自坐标) | V1 |
| 1 | kDragonfish | EncodeRemoteSyncFlagAddressJfDf @0x1d5aa620 | 与 kJellyfish 相同的编码器 | V1 |
| 2 | kPufferfish | EncodeRemoteSyncFlagAddressPufferfish @0x1d5af8a0 | pufferfish::dma_utils::… @0x1d5ae1a0(12位芯片) | V2 |
| 3 | kViperfish | EncodeRemoteSyncFlagAddressViperfish @0x1d5af900 | viperfish::dma_utils::… @0x1d5af9c0(14位芯片) | V2 |
| 4 | kGhostlite | EncodeRemoteSyncFlagAddressGhostlite @0x1d5b01e0 | ghostlite::dma_utils::… @0x1d5affc0(14位,字节与VF相同) | V2 |
Ghostlite 是 glc 系列 v6e(营销名称为“Trillium”)。密钥 0/1/2/3/4 是根据每个注册商的 [rbp] 存储的 movl 立即数进行字节确认的(§2);完整 .text 中每个编码器地址的 LEA 仅与其注册商匹配。
注意 — 注册表包装器(名为
EncodeRemoteSyncFlagAddress{Pufferfish,Viperfish,Ghostlite}的符号)携带完整的 5 参数注册表签名(LloValue*, CoreLocationBase const&, bool, LloValue*, LloRegionBuilder)。dma_utils命名空间中的每代 算术实现 带有更精简的 3 参数签名(LloValue* sflag, CoreLocationBase const&, LloRegionBuilder)- 没有phys_chip_id,没有multicast。包装器的存在纯粹是为了在尾部调用 impl 之前丢弃这两个额外的参数(对于 Pufferfish,如果设置了multicast,则丢弃到LOG(FATAL))。EncodeRemoteSyncFlagAddressViperfish@0x1d5af900和…Ghostlite@0x1d5b01e0是裸露的单行尾调用。
3. 每代位打包公式
所有编码器都将地址构建为 LLO 标量操作链。 只有 JfDf 标记结果 set_annotation_if_not_constant("remote sync flag address"); V2 dma_utils impls (@0x1d5ae1a0/0x1d5af9c0/0x1d5affc0) 携带无注释调用 - 字节确认。这两个家庭所携带的物品有所不同。
3.1 二族表
一代 (TpuVersion) | 地址公式 | 芯片源码 | 芯片领域 | 核心/段字段 | 组播 | 使用phys_chip_id |
|---|---|---|---|---|---|---|
水母 0 / 龙鱼 1 (JfDf @0x1d5aa620) | sflag | (CLB[+8] << 0x14) | (phys_chip_id << 0x15) | 0x40000 | (0x40 << 0xc) | (mc ? 0x80000 : 0) | phys_chip_id(位 21)+ CLB[+8] X 坐标(位 20) | 位 21(物理) | seg 0x40 @ 位 12-17,标记位 18,mc 位 19 | YES(位 19,有条件) | 是(位 21) |
河豚 2 (@0x1d5ae1a0) | sflag | (0x8000 | (core_sub << 0xe)) | ((CLB[+0] & 0xfff) << 0x12) | CLB[+0] 逻辑芯片坐标 | 0xfff(12 位)@ 位 18 | core_sub @ 位 14,段 0x8000 @ 位 15 | 编号 (LOG(FATAL) "is_multicast == false") | NO |
毒蛇鱼 3 (@0x1d5af9c0) | sflag | (0x8000 | (core_sub << 0xe)) | ((CLB[+0] & 0x3fff) << 0x11) | CLB[+0] 逻辑芯片坐标 | 0x3fff(14 位)@ 位 17 | core_sub @ 位 14,段 0x8000 @ 位 15 | NO(布尔值被丢弃) | NO |
Ghostlite 4 (@0x1d5affc0) | (与 Viperfish 字节相同) | CLB[+0] 逻辑芯片坐标 | 0x3fff(14 位)@ 位 17 | core_sub @ 位 14,段 0x8000 @ 位 15 | NO(布尔值被丢弃) | NO |
其中,对于 V2 编码器:
core_sub = (CoreLocationBase[+8] & 3),则+2iff sflag 操作数位于 sflag 类MemorySpace中。 PF门为((sflag[+0xb]>>2)&0x1f) − 9 ≤ 1(即MS ∈{0x9,0xa}); VF/GL 门是(((sflag[+0xb]>>2)&0x1d) | 2) == 0xe。- 折叠
(0x20000 + (core_sub << 0x10)) >> 2在算术上等于(0x8000 | (core_sub << 0xe))(针对core_sub0..5 进行验证)。 V2 编码器按字面意思计算0x20000-add />>2形式(SimmU32(0x20000)、SshllU32(core,0x10)、SaddS32、SshrlU32(.,2)),简化器将其解析为位0x8000 | core_sub<<14。
DefaultSyncFlagSegmentId() @0x1d62da60 是 asic_sw::deepsea::jxc::DefaultSyncFlagSegmentId(),并且是常数 0x40 (mov eax,0x40; ret); JfDf 将其左移 0xc 以将其置于第 12-17 位。
3.2 JfDf — V1 坐标编码器(字节精确)
// EncodeRemoteSyncFlagAddressJfDf(LloValue* sflag, CoreLocationBase const& peer,
// bool multicast, LloValue* phys_chip_id, LloRegionBuilder) // 0x1d5aa620
x_coord = peer[+8]
addr = SorU32(sflag, SshllU32(x_coord, SimmU32(0x14))) // | X << 20
addr = SorU32(addr, SshllU32(phys_chip_id, SimmU32(0x15))) // | phys_chip << 21
addr = SorU32(addr, SimmU32(0x40000)) // | remote marker (bit 18)
addr = SorU32(addr, SimmU32(DefaultSyncFlagSegmentId() << 0xc)) // | 0x40 << 12 (bits 12..17)
if (multicast):
VLOG(1) "Set multicast in EncodeRemoteSyncFlagAddress" // remote_sync_flag_encoder_jellyfish.cc:30
addr = SorU32(addr, SimmU32(0x80000)) // | multicast (bit 19) CONDITIONAL
set_annotation_if_not_constant(addr, "remote sync flag address")
return addr
```text
这是唯一一个读取 `phys_chip_id`(`MapLogicalToPhysicalChipId` 输出,参数 4)的编码器,也是唯一一个其多播位是有条件的编码器。 `VLOG(1)` 站点 (`remote_sync_flag_encoder_jellyfish.cc:30`) 是多播路径上的唯一诊断。
> **明白了 —** `0x80000` 多播位**不**固定:它在 `multicast` 参数 (`if (v8) … SorU32(.., 0x80000)`) 上门控。非多播 JfDf 远程写入*不会*设置位 19。
### 3.3 Pufferfish / Viperfish / Ghostlite — V2 核心索引相对编码器(字节精确)
```c
// pufferfish::dma_utils::EncodeRemoteSyncFlagAddress(LloValue* sflag,
// CoreLocationBase const& peer, LloRegionBuilder) // 0x1d5ae1a0
core_sub = SandU32(peer[+8], SimmU32(3)) // CLB[+8] & 3
if (((sflag[+0xb] >> 2) & 0x1f) ∈ {9,10}): // sflag-class MS gate (PF)
core_sub = SaddS32(core_sub, SimmS32(2)) // + 2
chip = SshllU32( SandU32(peer[+0], SimmU32(0xfff)), SimmU32(0x12)) // (CLB[+0] & 0xfff) << 18
seg = SshrlU32( SaddS32(SimmU32(0x20000), SshllU32(core_sub, SimmU32(0x10))), SimmU32(2))
// = 0x8000 | (core_sub << 14)
addr = SorU32(seg, sflag) // | sflag (RAW)
return SorU32(chip, addr) // | chip fieldviperfish::dma_utils::EncodeRemoteSyncFlagAddress @0x1d5af9c0 形状相同,有两处不同:MS 门为 (((sflag[+0xb]>>2)&0x1d)|2) == 0xe,芯片字段为 (CLB[+0] & 0x3fff) << 0x11(14 位掩码,移位 17)。 ghostlite::dma_utils::EncodeRemoteSyncFlagAddress @0x1d5affc0 与 Viperfish 字节相同(掩码 0x3fff @0x1d5b0052,移位 0x11 @0x1d5b0070)。
河豚包装 @0x1d5af8a0 是多播被拒绝的地方:
// EncodeRemoteSyncFlagAddressPufferfish(LloValue* sflag, CoreLocationBase const&,
// bool multicast, LloValue* /*phys, discarded*/, LloRegionBuilder) // 0x1d5af8a0
if (multicast):
LOG(FATAL) << MakeCheckOpString(1,0,"is_multicast == false") // remote_sync_flag_encoder_pufferfish.cc:13
return pufferfish::dma_utils::EncodeRemoteSyncFlagAddress(sflag, peer, builder) // drops phys + multicast
```text
> **GOTCHA —** 屏蔽的 V2 字段是 **芯片坐标** `CLB[+0]`(PF 上的 `& 0xfff`,VF/GL 上的 `& 0x3fff`),已移位,与 *raw* 中的 `sflag` 或 - 它不是 `sflag & 0xfff`。 `CoreIndex() << 0xd` 移位属于*不同*功能 — 请参阅§3.4。
### 3.4 地址编码器不是什么——同级 core-id 编码器
每个V2 `dma_utils` TU还定义了`RemoteSyncFlagCoreIdEncoder(TpuSequencerType, sflag, core, builder)`(PF @`0x1d5ae2e0` / VF @`0x1d5afb00` / GL @`0x1d5b0100`): `SimmU32(seq==TC?2 : seq==SC?4 : FATAL)` → `SaddS32(., core ?: CoreIndex())` → `SshllU32(., 0xd)` → `SorU32(sflag, .)`。这构建了 *DMA 描述符的 * sflag 槽的 **core-selector** 字段(`CoreIndex() << 0xd`,位 13),并在 **单独的** 注册表中注册,`GetRemoteSyncFlagCoreIdEncoderRegistry()::r` @`0x2257e468` (guard @`0x2257e470`) — 不是此处记录的地址注册表。两者很容易混淆:**地址**编码器(本页)包含*芯片坐标*; **core-id** 编码器打包*核心索引*。它们是不同注册表中的不同功能。
### 3.5 12→14芯片场拓宽
V2芯片字段从12位(Pufferfish,掩码`0xfff`,移位18)拓宽到14位(Viperfish/Ghostlite,掩码`0x3fff`,移位17)。这与二进制文件中另外两个独立的芯片 ID 字段(DMA-id 芯片字段 (11→14) 和跟踪芯片 ID 字段 (12→14))中看到的每代 Pod 地址加宽相同。远程 SFLAG 地址芯片字段是同一扩展的第三个独立见证者。 JfDf 在结构上不属于这种模式:它采用*双字段*芯片方案(X 坐标位于位 20,物理芯片 ID 位于位 21)而不是单个屏蔽芯片字段,因此“每代宽度增长”观察适用于 V2 (PF→VF/GL) 系列,以 JfDf 作为 V1 坐标基线。
---
## 4. `MapLogicalToPhysicalChipId` — 芯片 ID 重新映射(仅限 JfDf)
在调度之前,调度程序始终在对等方的逻辑芯片坐标上运行 `LloRegionBuilder::MapLogicalToPhysicalChipId(LloValue* chip_id, string_view operand_name, bool multicast)` @`0x1d519f40`。结果作为 `phys_chip_id` 馈送到每个编码器,但只有 JfDf 读取它(位 21); V2编码器忽略它并直接使用`CLB[+0]`。
它是**混合基数 3-D 拓扑坐标变换**,而不是 `DeviceAssignment` 数组索引。不需要`DeviceAssignment`;它纯粹在芯片 ID `LloValue`、`Target` 网络网格基数和每核 SMEM 拓扑字上运行。它消耗的逻辑芯片 ID 是由副本组扁平化(二项式/平面信息表解析器)上游生成的,而不是在这里。
### 4.1 门(否则直通)
```c
function MapLogicalToPhysicalChipId(chip_id, operand_name, multicast): // 0x1d519f40
if (chip_id == null): return null
if (Target[+0x930] != 1): return chip_id // remap disabled for this target
cap = Target_subobject.vtable[+0x18]() // "is logical==physical / non-subslice" virtual
if (!multicast && cap): return chip_id // remap is a no-op for this topology
// IDEMPOTENCE: if chip_id is a const/opcode in {0xdb..0xe4} or opcode 0x2c whose annotation
// is already kSubslicePhysicalChipId/kSubsliceLogicalChipId → already mapped.
// (the (chip_id_opcode − 219) >= 0xA && != 44 test, then the annotation guard
// LloCheckForFailure "inst->annotation() != kSubslicePhysicalChipId")
… // (remap below)如果没有任何直通条件触发,则重新映射将运行并重新注释结果 "subslice-physical-chip-id",幂等性防护随后会在任何后续调用中识别该结果。
4.2 重映射(混合基重线性化)
// [1] un-linearize the logical chip-id over the program mesh (column-fastest)
(row, col, z) = ToChipCoordinates(chip_id) // 0x1d51a3a0
// col ← chip_id % Target::NetworkColumns() (0x1d6158c0) → struct[+8]
// row ← (chip_id/NC) % Target::NetworkRows() (0x1d615880) → struct[+0]
// z ← (chip_id/NC) / NetworkRows() → struct[+0x10]
// ⇒ logical chip_id = z*(NRows*NCol) + row*NCol + col
// [2] add the per-core subslice origin (where THIS slice sits in the physical pod)
origin = LoadSubsliceOffset() // 0x1d519280; base-0x400 SMEM triple
C0 = row + origin[0] // physical row
C1 = col + origin[1] // physical column
C2 = z + origin[2] // physical z / slice plane
// [3] bound-check against the physical mesh bounds (per-sequencer-type)
bounds = LoadPhysicalChipBounds() // 0x1d518dc0; base-0x400 SMEM triple
// B0 = rows_bound, B1 = cols_bound, B2 = z_bound
ScheckLt(C1, B1) FATAL "Invalid logical column: …"
ScheckLt(C0, B0) FATAL "Invalid logical row: …"
ScheckLt(C2, B2) FATAL "Invalid logical z: …" // hint "topology must be 2d for limited ICI routing"
// [4] re-linearize with the PHYSICAL bounds as radix (column-fastest)
phys = ((C2 * B0 + C0) * B1) + C1 // = z_phys*(rows_bound*cols_bound)
// + row_phys*cols_bound + col_phys
set_annotation_if_not_constant(phys, "subslice-physical-chip-id")
return phys
```text
`ToChipCoordinates` @`0x1d51a3a0` 通过 `NetworkColumns`/`NetworkRows` 进行两个 `SdivmodU32` 解码。 `LoadSubsliceOffset` @`0x1d519280` 从每核 SMEM 读取 `Target::SubsliceOriginLocationWordOffset()` @`0x1d617ce0` 并通过两个 `SdivmodU32`-by-`0x400` (注释)解包基本 `0x400` (10 位)三元组`"encoded subslice offset"`)。 `LoadPhysicalChipBounds` @`0x1d518dc0` 按定序器类型选择字偏移量 (`Target[+0x268]`: TensorCore=0 → `PhysicalChipBoundsLocationWordOffset` @`0x1d617c60`; BarnaCore=1 → `BarnaCorePhysicalChipBoundsLocationWordOffset` @`0x1d6183e0`; else FATAL) 并解压相同的内容底座-`0x400` 三联。重新线性化是两个`SmulU32` + 三个`SaddS32`(列添加是最后一项)。
> **注意 —** 反编译中确认的线性化字节是 `SaddS32(SmulU32(SmulU32(C2, B0)+C0 via SaddS32, B1), C1)` — 即 `((z·rows_bound + row)·cols_bound) + col`,其中 `B0`=row-bound,`B1`=col-bound。 `z` 边界检查带有提示 `"topology must be 2d for limited ICI routing"`,这意味着在有限 ICI 拓扑上 `z` 必须为 0(2-D Pod)。
### 4.3 它是如何组成的 — V1 与 V2
重映射的输出仅通过 **JfDf 的 bit-21 字段**到达地址。 V2 编码器将逻辑芯片坐标 (`CLB[+0]`) 直接传送到其单个掩码芯片字段中,并让接收侧 NIU + 路由引擎在运行时解析物理布局。这是每个家庭的差异:
| | V1(JfDf,第 0/1 代) | V2(PF/VF/GL,第2/3/4代) |
|---|---|---|
| 芯片 ID 是否已写入地址? | **物理**(重映射输出,位 21) | **逻辑**(CLB[+0],屏蔽) |
| 物理布局已解决 编译时的 | (重映射) 运行时的 | (片上 NIU + 路由) |
| 芯片坐标方案 | 两个字段:X@20 + phys@21 | 一字段:chip@17/18 |
| 组播 | 条件位 19 | 不受支持(PF 致命;VF/GL 下降) |
> **GOTCHA — V2 NIU 放置。** 因为 V2 编码器从不消耗 `phys_chip_id`,所以 `MapLogicalToPhysicalChipId` 预传递对于 Pufferfish/Viperfish/Ghostlite 来说是“死活”——调度程序计算它(甚至可能在绑定违规时致命),但 V2 包装器丢弃它。因此,V2 地址通过其*逻辑*坐标来命名芯片;将逻辑坐标转换为物理结构端点是片上 NIU/路由引擎的工作,而不是编译器的工作。跨芯片 *data*-memref 路径做出相同的选择 - 请参阅 [get_remote_memref](../collectives/get-remote-memref.md),其中对等 core-id 作为单独的操作数而不是折叠到指针中。
---
## 5. 端到端数据路径
将调度程序、重映射和每代编码器放在一起,跨芯片远程 SFLAG 地址按以下顺序构建:
| 舞台 | 功能(VMA) | 输出 |
|---|---|---|
| 消费者 | `VsyncAddRemote` @`0x1d522f40` | 呼叫调度员,则 `CreateVectorSyncFlagAddRemote(addr, value)` |
| MS-kSflag 验证 | `EncodeRemoteSyncFlagAddress` @`0x1d54da40` | RetCheck `sflag` 是否不在 kSflag(或支持的别名)MS 中 |
| 逻辑→物理芯片重映射 | `MapLogicalToPhysicalChipId` @`0x1d519f40` | `phys_chip = ((z+oz)·Brow + (row+orow))·Bcol + (col+ocol)` |
| ↳ 逻辑网格解码 | `ToChipCoordinates` @`0x1d51a3a0` | `(row,col,z)` 通过 NCol/NRows divmod(列最快) |
| ↳ 子切片原点 | `LoadSubsliceOffset` @`0x1d519280` | 基础-`0x400` 原点三重(每核 SMEM) |
| ↳ 物理边界 | `LoadPhysicalChipBounds` @`0x1d518dc0` | 基础-`0x400` 边界三重(每个定序器类型 SMEM) |
| 版本发货 | `GetRemoteSyncFlagEncoderRegistry().Get(ver)` @`0x1d54e020` | per-`TpuVersion` 编码器闭合 |
| JfDf 编码(gen 0/1) | `EncodeRemoteSyncFlagAddressJfDf` @`0x1d5aa620` | `sflag\|X<<20\|phys<<21\|0x40000\|0x40<<12\|(mc?0x80000)` |
| 河豚编码(第 2 代) | `pufferfish::dma_utils::…` @`0x1d5ae1a0` | `sflag\|(0x8000\|core<<14)\|((chip&0xfff)<<18)` |
| Viperfish 编码(第 3 代) | `viperfish::dma_utils::…` @`0x1d5af9c0` | `sflag\|(0x8000\|core<<14)\|((chip&0x3fff)<<17)` |
| Ghostlite 编码(第 4 代) | `ghostlite::dma_utils::…` @`0x1d5affc0` | (与 Viperfish 字节相同) |
| 注释(仅限 JfDf) | `set_annotation_if_not_constant` | `"remote sync flag address"`(V2 impls不注释) |
| (消费者)发射 | `CreateVectorSyncFlagAddRemote` | 远程 SFLAG 添加指令,编码地址作为操作数 0 |
---
## 6. 验证说明
> `libtpu.so` v0.0.40 中的字节精确:
>
> - **调度程序** `EncodeRemoteSyncFlagAddress` @`0x1d54da40`:带有 SupportsRemoteSyncFlagInTpuEmbeddingSpace (vtable+0x7b0, MS ∈ {9,10}) 和 SupportsSparseCore 的 `(sflag[+0xb]&0x7c)==0x18` kSflag 门(vtable+0x260, MS `0x30`) 交替; RetCheck 字符串 `"remote_sync_flag->memory_space() == MemorySpace::kSflag || …kBarnaCoreSmem … kBarnaCoreSflag … kSparseCoreSequencerSflag"`; `MapLogicalToPhysicalChipId(…, operand "EncodeRemoteSyncFlagAddress()" [29 chars], multicast=0)`; `version = Target[+0x398]`;然后使用 `(sflag, &x_coord, multicast, phys_chip_val, &builder)` 调用注册表 `Get`; `LOG(FATAL) "Unsupported version: "` 在第 8252 行 — 准确。
> - **`VsyncAddRemote`** @`0x1d522f40`:`EncodeRemoteSyncFlagAddress` 然后 `CreateVectorSyncFlagAddRemote(addr, value)` 然后 `AppendInstruction` — 准确。
> - **JfDf** @`0x1d5aa620`:`SshllU32(CLB[+8],0x14)`、`SshllU32(phys_chip,0x15)`、`0x40000`、`DefaultSyncFlagSegmentId()<<0xc`、`if(multicast)` 下的条件 `0x80000` 与`VLOG(1) "Set multicast in EncodeRemoteSyncFlagAddress"` 站点,注释 `"remote sync flag address"` — 准确(多播位是有条件的)。
> - **河豚** @`0x1d5ae1a0`:`core_sub = CLB[+8]&3`,MS门`((sflag[+0xb]>>2)&0x1f)−9 ≤ 1` → `+2`,芯片`(CLB[+0]&0xfff)<<0x12`,折叠`(SimmU32(0x20000)+core<<0x10)>>2`,`SorU32(.,sflag)`, `SorU32(chip,.)` — 准确。
> - **Viperfish** @`0x1d5af9c0`:MS 门 `(((sflag[+0xb]>>2)&0x1d)|2)==0xe`,芯片 `(CLB[+0]&0x3fff)<<0x11` — 准确; **Ghostlite** @`0x1d5affc0` 字节相同 (`0x3fff`/`<<0x11`)。
> - **PF 包装** @`0x1d5af8a0`:`if(multicast) LOG(FATAL) "is_multicast == false"` (pufferfish.cc:13) 然后 3-arg 尾部调用; **VF/GL 包装** @`0x1d5af900`/`0x1d5b01e0` 裸尾呼叫掉落 `phys`+`multicast`。
> - **注册商**(地址注册表 `r` @`0x2257e488`、`Register` @`0x1d5aa7a0`):四个 TU 中的五个注册 — `…_jellyfish.cc` @`0x2135b720` (JfDf @`0x1d5aa620`,按键 `1` @`0x2135b74d` 和 `0` @`0x2135b7be`),`…_pufferfish.cc` @`0x2135bb30` (按键 `2` @`0x2135bb51`), `…_viperfish.cc` @`0x2135bc00`(按键 `3` @`0x2135bc21`),`ghostlite_dma_utils.cc` @`0x2135be70`(按键 `4` @`0x2135be95`,编码器 LEA `0x1d5b01e0` @`0x2135beb2`) — 准确。 jellyfish TU 还播种 core-id 注册表(`r` @`0x2257e468`、`Register` @`0x1d5ae3c0`)和 DMA 覆盖注册表(`r` @`0x2257e478`)。只有 JfDf 注释了其结果; V2 `dma_utils` 意味着不进行 `set_annotation` 调用。
> - **`MapLogicalToPhysicalChipId`** @`0x1d519f40`:门 `Target[+0x930]==1`、`!multicast && vtable[+0x18]()` 直通、`(opcode−219)>=0xA && !=44` + `kSubslicePhysicalChipId` 注释幂等性防护、`ToChipCoordinates → LoadSubsliceOffset → 3× SaddS32 → LoadPhysicalChipBounds → 3× ScheckLt (column/row/z) → SmulU32/SaddS32/SmulU32/SaddS32 → annotation "subslice-physical-chip-id"` — 准确。
> - **`DefaultSyncFlagSegmentId`** @`0x1d62da60` = `0x40` (`mov eax,0x40; ret`)。
>
> **[高/未单独字段命名]**
>
> - V2折叠中`core_sub`(位14-16)和`0x8000`段标记(位15)之间的确切位边界:折叠`(0x8000 | core_sub<<0xe)`在算术上是精确的,但位15是否是独立于`core_sub`的固定段标记(其本身可以达到5) → 设置位 15/16) 没有单独固定。编码器对它们进行 OR/ADD,因此它们共存于同一字段区域。
> - `Target+0x930` 使能字节和 `vtable[+0x18]` 功能虚拟在 `Target` 配置子对象上:偏移量和调用是字节确认的;字段/方法*名称*(“映射逻辑→物理启用”和“非子切片/逻辑==物理”谓词)归因于`kSubslice*`注释使用,而不是来自proto/RTTI源。
> - VF/GL `+2` 门 (`(((MS>>2)&0x1d)|2)==0xe`) 与 PF 的 `{9,10}` 的承认 MS 集是字节确认的,但未针对完整的 `MemorySpace` 枚举进行枚举。
---
## 交叉引用
### 屏障子系统(本节)
- [屏障和同步标志 — 剖面图](overview.md) — SFLAG 屏障模型和生产者→归一化器→降低流量,该编码器是跨芯片腿。
- [屏障到 SFLAG 的绑定](barrier-to-sflag-binding.md) — 本地 SFLAG *数字* 公式 (`base+count+N`);此页面是他们的跨芯片*地址*伴侣。
- [按代号编译器保留](per-codename-compiler-reserved.md) — 本地 sflag 操作数从中提取的每个 `(codename, deployment)` 保留的 SFLAG 整数。
- [复制品屏障](replica-barrier.md) — 其跨芯片臂使用这些编码器的副本组内树屏障。
### 同级子系统
- [get_remote_memref](../collectives/get-remote-memref.md) — 跨芯片 *data* memref(仅基指针重新标记;对等 id 作为单独的操作数) — 相同的“边界处的逻辑 id,NIU 解决数据放置”模型而不是 sflags。
- [StartRemoteDma](../collectives/start-remote-dma.md) — 全部远程 DMA 生成器 + `SubsliceToFullSliceGlobalCoreId`,消耗远程基础的传输。
- [返回索引](../index.md)