扭曲环面形状折叠
本页所有地址均适用于
libtpu-0.0.40-cp314wheel 中的libtpu.so(build-id89edbbe81c5b328a958fe628a9f2207d,构建libtpu_lts_20260413_b_RC00)。其他版本会有所不同。.textVMA 等于文件偏移(基址0xe63c000);所有地址均为 VMA。以下每个符号都存在于完整符号二进制中,并已与 IDA 反编译结果交叉核对。
摘要
只有当 ICI 切片恰好有两种不同的轴长度时,扭曲环面才会被接纳:一条短轴 K 和一条长轴 2K = 2·K,并且每条轴都必须是二者之一。随后 (num-2K-axes, num-K-axes) 这对计数会把切片归入 三种 TwistedTorusShape 情形之一,而这三种也是扭曲环面支持的仅有形状:当门控失败时,切片构建器发出的唯一错误字符串逐字为 "TPU twisted torus only supports k*k*2k and k*2k*2k and k*2k*nk slice shapes."(CreateTpuSliceTopology 0x1ff939c0,topology_helper.cc)。本页是折叠目录:说明 K_K_2K、K_2K_2K 和 K_2K_NK 各自如何把加倍轴上的环重新穿回短 K 轴上,以及 megacore 偶/奇设备拆分如何与所得平面配对。
所有形状共享的机制是 +K-mod-2K 接缝,也就是打破折叠环死锁的日期线(见 扭曲环面 — 概览)。一个 2K 芯片的 reduce-scatter 环不能在一条物理加倍轴上作为平坦闭环存在,否则前向和返回两半会争用同一批 ICI 链路;相反,该环先沿短 K 轴行走(K 个芯片),再沿加倍轴跳 +K,然后第二次沿 K 轴行走。这两个长度为 K 的片段落在加倍维度的两半上。每个形状不同的是接缝接触多少条加倍轴:K_K_2K(一条 2K 轴)应用单轴 +K 接缝;K_2K_2K(两条 2K 轴)同时对两条轴应用接缝,即对角 (+K, +K) 偏移。K_2K_NK(字面长度为 n·K、n > 2 的长轴)只是路由层概念:在 jellyfish collective 内部,它只能以 n = 2 情形进入,因此通过同一套 num2K ∈ {1,2} 机制折叠。
折叠由 GetReplicaPair3DOnTwistedTorus(0x1c893400)计算,按 (num2K, arg) 分派。实时 v0.0.40 collective 使用的是 arg-0(单阶段)折叠,本页对其进行字节级解码。megacore 拆分是 Phase1 中应用的一个独立且正交的决策(GetPhase1ReplicaGroups 0x137d3de0):组数为 2K · LogicalDevicesPerChip,当一个芯片呈现两个逻辑设备(非 megacore,2 核)时触发偶/奇 {2m, 2m+1} 拆分,而不是在 megacore 模式下触发。
对重新实现而言,形状折叠目录的契约是:
- 三形状门控。
UpdateMinMaxDims(0x137d0260)通过两个致命CHECK把三条长度规约为K、2K和两类轴计数;计数对选择形状。不存在第四种形状。 - 逐形状接缝扇出。
num2K(1对2)是区分K_K_2K与K_2K_2K的那个参数:它就是被加上+K-mod-2K接缝的加倍轴数量。K_2K_NK会规约为这两者之一。 - 统一折叠。 一个闭式形式覆盖“哪条轴是
K”的全部三种物理朝向:coord(K-axis) = t mod K,coord(2K-axis) = (var + seam) mod 2K,其中seam = (t mod 2K ≥ K) ? K : 0,t是K轴的循环变量。 - megacore 平面拆分。 Phase1 组数
= 2K · LogicalDevicesPerChip;{2m, 2m+1}偶/奇拆分是 2 逻辑设备(非 megacore 2 核)情形,不是 megacore 模式。
| 形状枚举 | TwistedTorusShape {UNSPECIFIED, K_K_2K, K_2K_2K, K_2K_NK} |
| 形状门控 | TwistedTorusND::UpdateMinMaxDims 0x137d0260(两个致命 CHECK) |
| 门控 CHECK 1 | max_dim_size_ == 2 * min_dim_size_ ("Max. dim size should be 2 times the min. in a twisted torus") |
| 门控 CHECK 2 | num_min_dims_ + num_max_dims_ == num_dims_ ("Dimension sizes should either be maximum or minimum") |
| 切片形状错误字符串 | "TPU twisted torus only supports k*k*2k and k*2k*2k and k*2k*nk slice shapes."(CreateTpuSliceTopology 0x1ff939c0) |
| 区分参数 | num2K = num_max_dims_([obj+0x600]):1→K_K_2K,2→K_2K_2K |
| 坐标折叠 | GetReplicaPair3DOnTwistedTorus 0x1c893400(按 (num2K, arg) 分派;num_max_dims == 2 CHECK 门控 num2K ∉ {1,2}) |
| megacore 拆分 | GetPhase1ReplicaGroups 0x137d3de0,组数 2K · LogicalDevicesPerChip(0)(0x20ad3020) |
| 置信度 | 高(反编译验证过的形状 CHECK、逐字切片形状字符串、折叠分派、组数公式),除非某行/标注另有说明 |
1. 形状门控 — 三种形状,没有第四种
在任何折叠运行前,TwistedTorusND::UpdateMinMaxDims(0x137d0260)会把三条环面长度规约为两个标量和两个计数。两个致命 CHECK 定义了“twisted”,而计数对就是分类器:
function UpdateMinMaxDims(target): // 0x137d0260
// reduce the three axis extents to short K and long 2K
min_dim_size_ = min extent // [obj+0x5f8] (this+191)
max_dim_size_ = max extent // [obj+0x5f0] (this+190)
CHECK_EQ(max_dim_size_, 2 * min_dim_size_) // "Max. dim size should be 2 times the min.
// in a twisted torus" (FATAL)
// count axes equal to each extent (decompiled as vpcmpeqq lane sums)
num_max_dims_ = count(extent == max_dim_size_) // [obj+0x600] (this+192) = num2K
num_min_dims_ = count(extent == min_dim_size_) // [obj+0x608] (this+193) = numK
CHECK_EQ(num_min_dims_ + num_max_dims_, num_dims_) // == 3
// "Dimension sizes should either be
// maximum or minimum" (FATAL)
```text
两个 CHECK 字符串都已通过反编译逐字验证(`UpdateMinMaxDims` 中的 `MakeCheckOpString<long,long>(..., 2 * R9, "max_dim_size_ == 2 * min_dim_size_")` 和 `"num_min_dims_ + num_max_dims_ == num_dims_"`)。`2 * min_dim_size_` 操作数就是第一个 CHECK 用来比较的字面乘法。`(num2K, numK)` 对选择形状:
| `num2K` / `numK` | 形状 | `TwistedTorusShape` | 加倍轴 |
|---|---|---|---|
| 1 / 2 | `K, K, 2K` | `K_K_2K` | 一条 `2K` 轴 |
| 2 / 1 | `K, 2K, 2K` | `K_2K_2K` | 两条 `2K` 轴 |
| (1 or 2) | `K, 2K, nK` → 按 `n=2` 折叠 | `K_2K_NK` | 一条 `2K` 轴(collective);字面 `nK` 仅在路由中 |
`num2K + numK == 3` 总是成立(CHECK 2),所以对 3-D 切片只存在 `(1,2)` 和 `(2,1)` 这两种分割;`(0,3)` 是普通立方体(非 twisted),而 `(3,0)` 不可能(max ≠ min)。这就是为什么 collective 侧恰好有两个折叠(`num2K ∈ {1,2}`),并且切片构建器字符串恰好列出三种形状,其中第三种(`K_2K_NK`)是路由区别,而不是第四种折叠。
> **注意 —** `UpdateMinMaxDims` 按 `[obj+0xb8]=Y`、`[obj+0xc0]=X`、`[obj+0xc8]=Z` 的顺序读取三个对象维度字段;每个折叠使用的循环变量↔轴映射是 `Y↔j`、`X↔i`、`Z↔k`,这一点由两个阶段中 `GetReplicaPair3D` 调用点的压栈顺序按字节确认。分类器并**不**关心哪条物理轴是 `K` 轴;折叠(§3)通过 `t = K-axis loop var` 选择器与朝向无关。见 [Twist 谓词与朝向](twist-predicate-orientation.md)。
---
## 2. `K_2K_NK` 规约为 `num2K ∈ {1,2}` 情形
字面 `K_2K_NK` 形状,即一条长度为 `n·K` 且 `n > 2` 的长轴,从不会到达一个独立的 collective 折叠。两处独立的 CHECK 在 jellyfish 路径内部禁止它:
1. `UpdateMinMaxDims` 的 `CHECK_EQ(max_dim_size_, 2 * min_dim_size_)` 会对任何 `max = n·K` 且 `n ≠ 2` 的情形致命报错。
2. `GetReplicaPair3DOnTwistedTorus` 会在每个 `num2K ∉ {1,2}` 的落空路径上重新断言 `num_max_dims == 2`,即三个致命 `MakeCheckOpString<long,long>(a5, 2, "num_max_dims == 2")` 位置,每个 `arg` 分支一个(反编译验证地址 `0x1c89391c` / `0x1c893945` / `0x1c89396e`)。
因此在 jellyfish ND collective 内部,长轴**只有等于 `2K` 时**才会被接纳(即 `n = 2`)。collective 看到的所谓 `K_2K_NK` 切片因此会通过 §3 中同一套 `num2K ∈ {1,2}` 机制,折叠为 `K_K_2K`(一条加倍轴)或 `K_2K_2K`(两条)。字面 `nK` 几何,即长轴确实被加倍 `n` 倍,只对路由侧的 `TwistedTorusTopology::GetTiebreak` / `GetDistance`(`0x20b41320` / `0x20b408e0`)重要,它们会在一条 `n` 倍加倍轴上计算最小跳数路径。`k*k*2k` / `k*2k*2k` tiebreak 字符串和路由缓存都在那里,而不在副本组折叠中。
> **陷阱 —** 不要为 `K_2K_NK` 实现第三种坐标折叠。collective 一侧恰好有两个折叠(`num2K = 1` 和 `num2K = 2`);`nK` 区别完全在路由侧。把“三种形状”读成“三种折叠”的重新实现者会写出一个二进制从未到达、并且会被 `num_max_dims == 2` 致命报错拦住的折叠。路由侧的 `nK` 处理见 [Get Tiebreak](get-tiebreak.md) 和 [扭曲环面 — 概览 §2](overview.md#2-the-twistedtorus-class-family)。
---
## 3. 折叠几何 — 统一的 `(num2K, arg)` 闭式形式
`GetReplicaPair3DOnTwistedTorus`(`0x1c893400`)把 `(i, j_or_m, k)` 环/平面索引映射到物理 `(coord_Y, coord_X, coord_Z)`,然后从 `[Y][X][Z]` 物理→逻辑表中查出两个 megacore-core 逻辑设备 ID `{core0, core1}`。它的签名携带 `2K`(`a3`)、`K`(`a4`)、`num2K`(`a5`)和 `arg`(`a6`);分派是两层树:
```text
GetReplicaPair3DOnTwistedTorus(map, dims, 2K=a3, K=a4, num2K=a5, arg=a6, i=a7, j_or_m=a8, k=a9):
dispatch on arg (a6): == 1 → 2-phase folds (CHECK-gated unreachable in v0.0.40)
== 0 → single-phase folds (LIVE)
else → arg-other folds (unreachable)
each nests on num2K (a5): == 1 → K_K_2K fold (one-axis seam)
== 2 → K_2K_2K fold (two-axis diagonal seam)
else → CHECK(num_max_dims == 2) FATAL实时单阶段 collective 总是传入 arg = 0(shard bool,由 GetPerColorShardIdTable 0x137d2d80 门控为仅 1 阶段)。因此重新实现者必须复现的两个折叠是 (arg=0, num2K=1) 和 (arg=0, num2K=2)。二者都可规约为一个与朝向无关的闭式形式。
接缝
令 t 为短 K 轴的循环变量,即 {j, i, k} 中索引长度等于 K 的维度的那个变量(Y==K ⇒ t=j,X==K ⇒ t=i,Z==K ⇒ t=k)。接缝是日期线:
seam = ((t mod 2K) >= K) ? K : 0
```text
在反编译中,这是 `if (a7 >= a4)` 守卫结合 `a7 % a4`(`K` 轴坐标)和 `a7 + a4`(加倍轴上的 `+K` 偏移),以 `2K = a3` 和 `K = a4` 进行求值(已在 modulo/add 位置 `0x1c8935f5` / `0x1c89362d` / `0x1c8937fa` 以及 `% a4` 规约处验证)。`K` 环在加倍的 `2K` 成员跨度上两次穿过短轴;第二次(`t ≥ K`)会偏移 `+K`。
### 统一坐标折叠
```c
// the (arg=0) fold, both num2K==1 and num2K==2; t = the K-axis loop var
seam = ((t mod 2K) >= K) ? K : 0
coord(K-axis) = t mod K // % a4
for each 2K-axis x: coord(x) = (var_x + seam) mod 2K // (var + a4) % a3 on the seamed pass
return map[coord_Y][coord_X][coord_Z] // -> {core0, core1}两种形状的唯一区别是有多少条 2K 轴接收接缝:
| 形状 | num2K | 接缝应用到 | Phase0 R |
|---|---|---|---|
K_K_2K | 1 | 单条 2K 轴(单轴 +K 接缝) | K |
K_2K_2K | 2 | 两条 2K 轴同时(对角 (+K, +K) 接缝) | 2K |
R = (num2K ≥ 2) ? 2K : K 是 Phase0 外层循环界限,反编译已确认它是 GetPhase1ReplicaGroups 中的 if (this+192 >= 2) v19 = v18 cmov(v18 = 2K = obj+190,v19 = K = obj+191)。对 K_K_2K,单条加倍轴承载整个接缝;对 K_2K_2K,两次穿行会在两条加倍轴上对角偏移,因此每条 2K 轴都承载该环的一个长度 K 片段。
逐朝向折叠表(arg=0,全部三种朝向)
闭式形式展开为下表;var_Y = j,var_X = i,var_Z = k,并且 seam 使用 K 轴自己的循环变量作为 t:
| K-axis is | t | coord(Y) | coord(X) | coord(Z) |
|-----------|---|------------------|------------------|------------------|
| Y (dim0) | j | j mod K | (i+seam) mod 2K | (k+seam) mod 2K | K_2K_2K (Y short)
| X (dim1) | i | (j+seam) mod 2K | i mod K | (k+seam) mod 2K | K_2K_2K (X short)
| Z (dim2) | k | (j+seam) mod 2K | (i+seam) mod 2K | k mod K | K_2K_2K (Z short)
```text
对 `K_K_2K`(`num2K = 1`),只有单个 `2K` 轴对应的表格单元会得到 `+seam` 偏移;另一条轴是短 `K` 轴(`var mod K`),第三条是没有接缝的普通 `K` 长度轴。上表是 `num2K = 2`(`K_2K_2K`)形式,其中两条非 `K` 轴都已加倍。
### 示例跟踪 — `K_2K_2K`,`K = 2`(因此 `2K = 4`),`K` 轴 = Y
重新实现者可以用此跟踪自检折叠。切片为 `(Y, X, Z) = (2, 4, 4)`,`K` 轴为 `Y`(`t = j`),单个 Phase0 reduce-scatter 环固定 `(i, k)` 并遍历环成员 `j = 0..2K-1 = 0..3`:
```text
fix the plane cell (i, k) = (1, 2); walk j = 0..3:
j=0: seam=(0>=2?2:0)=0 ; cY=0%2=0 ; cX=(1+0)%4=1 ; cZ=(2+0)%4=2 -> chip (0,1,2)
j=1: seam=(1>=2?2:0)=0 ; cY=1%2=1 ; cX=(1+0)%4=1 ; cZ=(2+0)%4=2 -> chip (1,1,2)
j=2: seam=(2>=2?2:0)=2 ; cY=2%2=0 ; cX=(1+2)%4=3 ; cZ=(2+2)%4=0 -> chip (0,3,0)
j=3: seam=(3>=2?2:0)=2 ; cY=3%2=1 ; cX=(1+2)%4=3 ; cZ=(2+2)%4=0 -> chip (1,3,0)该环第一次穿行(j = 0,1)在 (X,Z) = (1,2) 处沿短 Y 轴行走;第二次穿行(j = 2,3)在 X 和 Z 两者上跳 +K = +2(对角接缝),并在 (X,Z) = (3,0) 处再次沿 Y 行走。四个成员是四个不同芯片,即一个正确的 2K = 4 芯片 reduce-scatter 环;接缝把该环分到每条加倍轴的两半上(X: 1↔3,Z: 2↔0)。对 K_K_2K,接缝只会接触 X/Z 中的一条;另一条加倍形式的轴会保持为短轴。
注意 — 对
K_2K_2K(num2K=2,arg=0)情形,折叠已通过仿真验证:在K ∈ {2,3,4}、所有(i,j,k)、全部三种朝向上,与指令级反汇编零不匹配;每个生成坐标都在界内(coord_Y < Y,coord_X < X,coord_Z < Z);并且每个 Phase0 组(i,k)包含2K个不同芯片,即正确的 reduce-scatter 环。K_K_2K(num2K=1)单轴接缝是 GetReplicaPair3DOnTwistedTorus 上记录的对照情形。怪癖 — 分派中的
(arg=1)和(arg-other)分支是结构上不同的折叠(0x1c893535/0x1c89359e处有不同的 cmov 链),但在 v0.0.40 中不可达:GetPerColorShardIdTable(0x137d2d80)会对任何 shard count≥ 2以"3D twisted torus weight update sharding algorithm currently supports only 1-phase sharding."致命报错,所以arg总是0。arg=1折叠只会在未来多 shard 的 twisted weight-update 下触发。置信度:低 — 其闭式形式尚未规约。见 GetReplicaPair3DOnTwistedTorus。
4. 每种折叠的 megacore 偶/奇拆分
每种形状的折叠都会产生一个 2K 成员 reduce-scatter 环(Phase0)和一个供 all-gather 使用的 K×R 平面(Phase1)。megacore 偶/奇拆分应用在 Phase1 中,并与产生该平面的任意折叠配对。它由逻辑设备数量决定,而不是直接由 megacore 模式决定。
GetPhase1ReplicaGroups(0x137d3de0)把组数设为 2K · LogicalDevicesPerChip(0):
function GetPhase1ReplicaGroups(target, dev_assign, arg, ...): // 0x137d3de0
UpdateMinMaxDims(target) // K=obj+191, 2K=obj+190, num2K=obj+192
GetPhysicalToLogicalMapping3D(...) // [Y][X][Z] -> {core0, core1}
R = (num2K >= 2) ? 2K : K // cmov: if (obj+192 >= 2) R = 2K
cores = Target::CoresPerChip(target, 0) // 0x1d615b40
n_groups = 2K * Target::LogicalDevicesPerChip(target, 0) // 0x20ad3020; imul
for m in 0 .. 2K-1: // m = the long-axis plane index
even = 2*m ; odd = 2*m + 1
for i in 0 .. R-1:
for k in 0 .. K-1:
pair = GetReplicaPair3DOnTwistedTorus(map, dims, 2K, K, num2K, arg, i, m, k)
// pair.first = core0 device, pair.second = core1 device
if Megacore() && (cores == 1 || secondary_cores <= 1):
... (megacore split path, rare)
elif !Megacore() && cores != 1: // NON-megacore 2-core
group[even].add(pair.first) // core0 -> even group 2m
group[odd ].add(pair.second) // core1 -> odd group 2m+1
else: // megacore OR single core
group[m].add(pair.first) // both cores -> group m
```text
`LogicalDevicesPerChip(0)`(`0x20ad3020`)是 `Megacore() ? 1 : CoreCount()`,即一个 megacore 芯片报告**一个**逻辑设备,而非 megacore 2 核芯片报告**两个**。因此组数为:
| 模式 | `LogicalDevicesPerChip` | Phase1 组 | 追加路由 |
|---|---|---|---|
| megacore | 1 | `2K` | group `m`(两个核心,一个逻辑设备) |
| 非 megacore,1 核 | 1 | `2K` | group `m` |
| 非 megacore,2 核 | 2 | `4K` | core0 → group `2m`(偶),core1 → group `2m+1`(奇) |
偶/奇拆分(`group[2m]` / `group[2m+1]`,反编译已确认为写入 proto repeated field 的 `v90 = 2*v26` / `v91 = 2*v26 + 1`)是**非 megacore 2 逻辑设备**情形。随后两个核心在互不相交的平面半部上 all-gather,因此每个核心的 AG 流量使用平面 ICI 链路的不同切片,从而在两个逻辑设备之间平衡加倍平面带宽。**megacore** 芯片把两个物理核心合并为一个逻辑参与者,并使用 group `m`(不拆分),因为 megacore 融合机制已经在一个逻辑设备内部把*工作负载*拆到了两个核心上(见 [Megacore Collective Fusion](../collectives/megacore-fusion.md))。
该拆分与形状**正交**:全部三种形状都会产生 Phase1 平面,同一个 `2K · LogicalDevicesPerChip` 组数适用于每一种。形状改变的是平面的长度,即 `K_K_2K` 的 `R = K` 和 `K_2K_2K` 的 `R = 2K`,它设置的是内部 `i` 循环界限,而不是组数。
> **注意 —** Phase1 偶/奇拆分是**非 megacore** 2 核情形(`LogicalDevicesPerChip = CoreCount = 2 → 4K` 组),*不是* megacore 模式行为;megacore 会折叠为 1 个逻辑设备并使用 group `m`(`2K` 组)。组数 `2K · LogicalDevicesPerChip` 是 `0x137d3eb1` 处的 `imul`,而 `LogicalDevicesPerChip` 通过 `0x20ad3020` 处的 `Megacore() ? 1 : CoreCount` getter 解析。Phase0(reduce-scatter)*总是*把同一芯片的两个核心放进同一组,不管模式如何(两个 proto append 都写入同一个 group 指针)。字节精确门控见 [Megacore Even/Odd Split](megacore-even-odd.md)。
>
> **注意 —** 反编译门控还有一个上表抽象掉的细节:当*secondary*-core-count 字段(`[topology+0x7c]`/`+0x124`)为 `> 1` 时,megacore 分支本身也能到达拆分路径。在常见 megacore 配置中,该字段为 `≤ 1`,所以 megacore 使用 group `m`。重新实现级规则是“当且仅当芯片呈现 2 个逻辑设备时拆分”;字节级跳转方向留到 [Megacore Even/Odd Split](megacore-even-odd.md)。
---
## 5. 为什么每种形状以这种方式折叠
折叠几何由这一要求强制决定:Phase0 reduce-scatter 环必须是一个 `2K` 芯片环,并且它的两半不能争用同一批 ICI 链路,这与 1-D 双向环的日期线论证相同。
**`K_K_2K`(一条加倍轴)。** 该切片有一条短轴和一条加倍轴(第三条轴也是短轴)。`2K` 环必须位于这条单独的加倍轴上,但平坦的 `0..2K-1` 行走会折回自身并死锁。折叠改为先沿短 `K` 轴行走(`K` 个芯片),再沿加倍轴跳 `+K`,然后再次沿 `K` 轴行走,把环的两个 `K` 片段放到这一条加倍维度的两半上。`R = K`,因为 all-gather 扫过的正交平面宽度为 `K`。
**`K_2K_2K`(两条加倍轴)。** 两条轴加倍,一条轴为短轴。若让单条加倍轴承载整个 `2K` 环,会让第二条加倍轴的 ICI 带宽闲置,并使第一条过载。因此折叠会同时对**两条**加倍轴应用接缝,即对角 `(+K, +K)` 偏移,使两条 `2K` 轴各自承载该环的一个长度 `K` 片段。这会在两条物理加倍轴之间平衡加倍轴 ICI 带宽。`R = 2K`,因为正交平面跨越完整的加倍轴。
**`K_2K_NK`。** 真正 `n` 倍加倍的长轴无法在 `num2K ∈ {1,2}` 折叠内部形成一个平衡的、感知 `2·(n·K)` 的环,因此 collective 从不会以 `n > 2` 的形式看到它;路由生成器(`TwistedTorusTopology`)处理字面 `nK` 距离几何,而 collective 只会折叠 `n = 2` 的规约。
megacore 拆分与平面配对,而不是与环配对:reduce-scatter 环是加倍轴上的物理 ICI 环,同一芯片的两个核心位于相同环位置并共享该芯片的 ICI 端口,所以拆分它们没有收益,Phase0 总是把它们放在同一组。相比之下,all-gather 平面对每个逻辑设备有不同链路集合,因此两个逻辑设备(非 megacore 2 核)会拆成不相交的偶/奇平面半部,以使用两组链路。
---
## 6. 函数映射
| 函数 | 地址 | 作用 |
|---|---|---|
| `TwistedTorusND::UpdateMinMaxDims` | `0x137d0260` | `K`/`2K` 规约 + 两个形状 CHECK + `(num2K, numK)` 计数 |
| `GetReplicaPair3DOnTwistedTorus` | `0x1c893400` | 逐形状坐标折叠(按 `num2K`、`arg` 分派);`num_max_dims == 2` 门控 |
| `TwistedTorusND::GetPhase1ReplicaGroups` | `0x137d3de0` | Phase1 平面 AG 组 + megacore 偶/奇拆分 |
| `TwistedTorusND::GetPerColorShardIdTable` | `0x137d2d80` | 仅 1 阶段门控(强制 `arg = 0`) |
| `TpuTopology::LogicalDevicesPerChip` | `0x20ad3020` | `Megacore() ? 1 : CoreCount()` — 决定拆分 |
| `Target::CoresPerChip` | `0x1d615b40` | `int32[topology+0x7c + coreType*12]` |
| `CreateTpuSliceTopology` | `0x1ff939c0` | 发出逐字三形状错误字符串 |
| `GetReplicaPair3D arg==1 fold` | `0x1c893535` | 不同的 `≥2-phase` 接缝 |
| `TwistedTorusTopology::GetTiebreak` | `0x20b41320` | 路由侧字面 `nK` 距离/tiebreak |
---
## 7. 尚未解决
- **`arg=1`(`≥2-phase`)折叠。** `GetReplicaPair3DOnTwistedTorus` 的 `arg==1` 入口(`0x1c893535`)是结构上不同的接缝(第二 shard 分区),但在 v0.0.40 中不可达(`GetPerColorShardIdTable` 1 阶段门控)。其闭式形式尚未规约。低。见 [GetReplicaPair3DOnTwistedTorus](get-replica-pair-3d.md)。
- **路由侧字面 `nK` 数学。** `TwistedTorusTopology::GetTiebreak` / `GetDistanceFromOrigin` 是 `n > 2` 长轴真正不同的唯一位置;依赖 `n` 的距离公式尚未解码。中。见 [Get Tiebreak](get-tiebreak.md)。
- **SparseCore 变体的逐形状拆分。** `TwistedTorusTopologyInfo`(`0x133e1980`,`sparse_core::collective`)只读取 `CoresPerChip(coreType=0)`;SC Phase 组是否按逻辑设备以不同方式拆分尚未追踪。中。见 [SC-Side Twist](sc-side-twist.md)。
- **精确的 megacore 拆分门控跳转。** 此处把反编译门控中的 secondary-core-count 条件(`[topology+0x124]`)抽象为“2 个逻辑设备 → 拆分”;字节级跳转方向见 [Megacore Even/Odd Split](megacore-even-odd.md)。