分层种类
此页面上的所有地址、符号和偏移量适用于
libtpu-0.0.40-cp314轮中的libtpu.so(build-id89edbbe81c5b328a958fe628a9f2207d,781,691,048 字节,未剥离,.textVMA == 文件偏移量0xe63c000,buildlibtpu_lts_20260413_b_RC00)。其他版本会有所不同;将每个 VA 视为版本固定。
摘要
HierarchicalKind 是决定 SparseCore 卸载集合是否构建为 平坦单环 还是 分层多相环列表 的单个参数。它看起来像分解的构建器签名中的三值枚举,但它不是密集的 0/1/2 枚举:它是 xla::jellyfish::AutoOr<bool>的 16 位位打包值,是区分 “flag is set” 和 “flag contains value X” 的包装器类型。卸载配置管道中的每个消费者都将其视为用 0x101 掩码的判别式 - 位 0x1 携带所包含的布尔值,位 0x100 是“参与”位。该页面恰好拥有:
AutoOr<bool>位编码 —0x1(值)和0x100(参与)如何由AutoOr<bool>::FromProtoOrDie打包,以及为什么判别式是 9 位掩码0x101而不是低整数。& 0x101/== 0x100解码 — 将HierarchicalKind分类为分层/显式扁平/未接合、字节锚定到ShouldEnableSparseCoreHierarchicalAllReduce和两个构建器主体的精确算术。- 种类→分解映射 - 四个判别值中的哪一个选择哪个集体分解,以及三个操作系列(AllGather / AllReduce / ReduceScatter)中的哪一个可以观察每个值。
消耗该种类的“构建器主体”以及该种类提供的 *OffloadConfig 结构位于 SC-卸载配置生成器 上。 0x101 路径产生的实际“多相发射”——D2D 芯片内环 + 每环面轴芯片间环,以及 IciStrategyRingConfig 叶场图——位于 分层 AllReduce / Pincer。本页是判别式的含义;这些页面就是它之间切换的内容。
二进制文件中观察到的 HierarchicalKind 合约:
- 该类型源自编译标志
xla_tpu_enable_sparse_core_hierarchical_all_reduce,通过AutoOr<bool>::FromProtoOrDie @0xf795300读取,当该标志存在时打包value | 0x100,当不存在时返回0x000。 - 该标志的编译默认值为 false (
AbslFlagDefaultGenFor… @0x1d726a00存储0);分层路径是选择性加入的。 - 构建者视为“平坦”的唯一
HierarchicalKind值正是0x100(已接合 + value-false)。任何与0x101判别式匹配的内容都是分层的;任何不参与的事情都会变得平淡。 - **AllGather和ReduceScatter硬连线
HierarchicalKind = 0x100**位于其ND包装中,因此它们在结构上固定为扁平的。 只有AllReduce计算实数类,才能达到层次分解。
概览
| 方面 | 值(字节锚定) |
|---|---|
| 底层类型 | xla::jellyfish::AutoOr<bool> 打包成 16 位字 |
| 源标志 | xla_tpu_enable_sparse_core_hierarchical_all_reduce(默认假) |
| 打包机 | AutoOr<bool>::FromProtoOrDie @0xf795300(return value | 0x100;return 0,如果未使用) |
位 0x001 | 包含的 bool 值 |
位 0x100 | 已接合位(AutoOr 保存一个值) |
| 判别掩模 | 0x101(每个消费者口罩都用这个) |
| 分层编码 | (kind & 0x101) == 0x101(已接合 + 真实) |
| 显式平面编码 | (kind & 0x101) == 0x100(已接合 + 假)— AG/RS 引脚 |
| 默认/未启用 | 0x000 → 平坦后备 |
| 启用谓词 | ShouldEnableSparseCoreHierarchicalAllReduce @0x1d6b6d80 ((~v & 0x101) == 0) |
| 扁平与分层调度 | AllReduce @0x133c2dc0 线 806 (kind & 0x101) != 0x100;全部聚集 @0x133c82c0 line 3102 == 256 |
| 可达分层 | 仅 AllReduce(AG/RS 固定 0x100) |
1.为什么它是一个AutoOr<bool>,而不是一个枚举
分解后的构建器签名为 (…, bool, bool, HierarchicalKind, optional<bool>, optional<bool>, optional<int>),这表明 HierarchicalKind 是一个具有少数命名成员的枚举类。它不是。 HierarchicalKind 是 xla::jellyfish::AutoOr<bool> ** 16 位打包表示的 typedef/别名 - jellyfish 的“自动或显式”标志包装器,与卸载配置管道中用于必须区分 unset 和 set-to-false 的标志的模式相同。
AutoOr<bool> 携带裸 bool 无法携带的两条信息:
- 该值是否已启用? — 该选项是否已设置(相对于保持自动/默认状态)?
- 值是多少? — 如果使用,则包含
bool。
消费者将两者打包成具有两个不相邻位的一个整数字,而不是 {tag, payload} 结构,因此判别式是 9 位掩码 0x101 并且不是一个小的 0..2 范围:
bit 15 ............ bit 8 ............ bit 0
0 0 0 0 0 0 0 E 0 0 0 0 0 0 0 V
^ ^
| +-- 0x001 = contained bool VALUE
+-------------------------- 0x100 = ENGAGED bit
```text
`E` (`0x100`) 为啮合位; `V` (`0x1`) 是值位。构建器看到的值中的内部位始终为零,因此“整个”语义内容由 `kind & 0x101` 恢复。
这就是为什么该子系统中的每个消费者在比较之前应用 `& 0x101` 的原因 - 以及为什么“平坦”标记是令人惊讶的常量 `0x100` 而不是 `0` 或 `1`。
---
## 2. 打包机 — `AutoOr<bool>::FromProtoOrDie`
该类是通过`AutoOr<bool>::FromProtoOrDie @0xf795300`读取编译标志产生的。反编译直接显示加壳:
```c
// xla::jellyfish::AutoOr<bool>::FromProtoOrDie — 0xf795300
__int64 FromProtoOrDie(xla::jellyfish::AutoProto *a1)
{
if ( !*((_DWORD *)a1 + 7) ) // AutoProto "engaged" word == 0 ?
return 0; // -> NOT ENGAGED : kind = 0x000
AutoOrTypeTraits<bool>::FromAutoProto(&v10, a1); // decode the contained bool -> v11
// ... (on decode failure, LOG(FATAL) "Failed to convert AutoProto into an AutoOr") ...
return v11 | 0x100u; // ENGAGED : kind = (value & 1) | 0x100
}
FromProtoOrDie @0xf795300:当原型的占用字(*((_DWORD*)a1 + 7))为零时,即标志从未设置→0x000,第16-17行返回0。否则(第 40 行),它返回v11 | 0x100u,将所占用的位0x100与包含的布尔值v11进行“或”运算。因此,打包程序只能发出三个值:0x000(未参与)、0x100(已参与 + false)、0x101(已参与 + true)。LOG(FATAL)的源位置是platforms/xla/service/jellyfish/flag_types.h:845,确认包装器是jellyfish的标志类型。
该标志本身默认为 false:
// AbslFlagDefaultGenForxla_tpu_enable_sparse_core_hierarchical_all_reduce::Gen — 0x1d726a00
*(_WORD *)this = 0; // default value = false
```text
> `AbslFlagDefaultGenFor… @0x1d726a00` 存储 `0` — 编译后的默认值为 `false`。该标志已注册到 `TpuCompilationEnvironment` (`GLOBAL__sub_I_tpu_compilation_environment.cc`) 中,因此它是一个预编译环境选项,可通过 AllReduce 包装器上的 `GetTpuCompEnv` 读取。默认 → 包含的 bool 为 false;达到 `0x101` 需要 `--xla_tpu_enable_sparse_core_hierarchical_all_reduce=true`。
---
## 3. 解码 — `& 0x101` 和 `== 0x100`
有两个不同的解码位点,两个形状略有不同,并且它们一致。
### 3.1 使能谓词 — `ShouldEnableSparseCoreHierarchicalAllReduce`
```c
// xla::jellyfish::ShouldEnableSparseCoreHierarchicalAllReduce — 0x1d6b6d80
bool ShouldEnableSparseCoreHierarchicalAllReduce(__int64 comp_env)
{
AutoProto *v1 = *(AutoProto **)(comp_env + 2632); // the flag's AutoProto
if ( !v1 ) v1 = &AutoProto_globals_;
AutoOr<bool>::FromProtoOrDie(v1); // -> v2 (the packed kind)
return (~v2 & 0x101) == 0; // true iff (v2 & 0x101) == 0x101
}
0x1d6b6d80第 13 行:return (~v2 & 0x101) == 0;。标识(~v & M) == 0 ⟺ (v & M) == M意味着当0x100和0x1都被设置时,返回true— 即类型为0x101(已接合 + true)。任何其他值(0x100、0x000或杂散0x001)都会返回false。这是规范的“是否启用了分层 AllReduce”测试。
3.2 建造者派遣 — (kind & 0x101) != 0x100
模板化构建器重新加载 16 位类型,并针对参与但错误的哨兵 0x100 对其进行测试。出现相同谓词的两种编码,每个操作族一种:
// AllReduce builder ConstructConfigForCollectiveUniDirNDGroups<AllReduceOffloadConfig,...> — 0x133c2dc0
// line 806:
v637 = (v63 & 0x101) != 256; // is_hierarchical = (kind & 0x101) != 0x100 (256 == 0x100)
// ^ mask discriminant ^ 0x100 == engaged+false -> FLAT (v637 = 0)
// -> else HIER (v637 = 1)
```text
```c
// AllGather builder ConstructConfigForCollectiveUniDirNDGroups<AllGatherOffloadConfig,...> — 0x133c82c0
// line 3032: LODWORD(v75) = v610 & 0x101; // mask the discriminant
// line 3102: if ( (_DWORD)v615 == 256 ) { ... flat ... } // direct == 0x100 compare
// lines 3204/3262: if ( (~(_WORD)v598 & 0x101) == 0 ) { ... hierarchical-only branch ... }AllReduce主体
@0x133c2dc0第806行将is_hierarchical字节计算为(kind & 0x101) != 0x100。 AllGather 正文@0x133c82c0第 3032 行屏蔽了& 0x101,然后在第 3102/3525 行将屏蔽值直接与256(=0x100) 进行比较;(~v & 0x101) == 0分层判别防护出现在第 3204/3262 行。两个操作系列以不同的方式编译“相同”谓词(AllReduce 从堆栈参数具体化setne字节;AllGather 内联比较堆栈槽),因为 AG 永远无法满足分层臂的要求 — 它的包装器将类型固定为0x100。
决定性的一点:建造者仅将**0x100**视为平坦。所有其他值都属于 != 0x100 的分层臂。与只能发出 0x000/0x100/0x101 的加壳器 (§2) 结合,可达行为为:
0x101(已接合+真实)→分层(!= 0x100)。0x100(接合+假)→平(== 0x100)。0x000(未接合/默认)→分层*!=测试的臂*,但该臂内的(~v & 0x101) == 0防护装置对于0x000来说是错误的,因此它折叠为平坦的单环后备。实际上,包装器永远不会将裸露的0x000转发给构建器(请参阅§5)。
4. 判别表
四个判别值以及每个判别值的选择。 分层 AllReduce / Pincer 详细介绍了分层分解本身(D2D 芯片内相位 + 每环面轴芯片间相位);这里只有选择。
kind & 0x101 | 已订婚 | 值 | 分解选定 | 达到 |
|---|---|---|---|---|
0x101 | 是 | 正确 | HIERARCHICAL — 多相环列表(D2D 芯片内 + 每个环面轴一个芯片间环,IMPLICIT 邻居) | 仅 AllReduce(标记已启用 + true) |
0x100 | 是 | 假 | 明确平坦 — 单芯片间环(EXPLICIT 邻居 + 预先计算的邻居表偏移量) | AG/RS(固定)+ AR(标记关闭) |
0x001 | no | — | 平坦回退(接合位清除 → ShouldEnable/(~v&0x101)==0 均为 false) | 未由包装器转发 |
0x000 | no | — | 默认 非分层(平坦后备) | 打包机未接合返回 |
平面分解和分层分解之间的语义划分,总结(钳页上的完整字节图):
| 方面 | 平 (0x100) | 分层 (0x101) |
|---|---|---|
phase_rings 每个颜色 | [D2D?] + 一个 片间环 | [D2D?] + 每个环面轴一个环 |
| 片间邻居 | ICI_RING_NEIGHBOR_EXPLICIT (1) | ICI_RING_NEIGHBOR_IMPLICIT (2) |
| 环长携带 | core_count 直接设置 | 隐式; core_count_adjustment(兆核三角洲) |
| 邻居表 | ring_neighbor_table_offset + has_reordering_map | 无(隐式排序) |
| D2D片内环 | 发射如果兆核(阶段 0) | 发射如果兆核(阶段 0) |
两臂片内D2D相位相同;判别式仅改变芯片间相位形状 - 将所有环面轴平坦折叠为单个 EXPLICIT 环,分层将它们分解为每个轴一个 IMPLICIT 环。这是密集 TensorCore 减少分散/全聚集相位分割的 SparseCore 模拟:每个环面维度一个相位。
5. 种类→操作族映射
HierarchicalKind 由三个公共 ND 包装器针对每个操作系列进行修复,不是由构建器修复。其中两个硬连线扁平:
| 包装 | VA | HierarchicalKind 通过 | 可以到达0x101吗? |
|---|---|---|---|
ConstructConfigForAllGatherUniDirND | 0x133c76c0 | 硬连线 0x100 | 否 — 始终平坦 |
ConstructConfigForReduceScatterUniDirND | 0x133ccbe0 | 硬连线 0x100 | 否 — 始终平坦 |
ConstructConfigForAllReduceUniDirND | 0x133c2c80 | 计算得出(见下文) | 是 |
AllGather和ReduceScatter包装器传递接合但错误的常量0x100,因此它们的构建器主体始终采用== 0x100平坦分支。只有 AllReduce 包装器计算真正的判别式。模板化构建器的主要 bool 参数是:
// ConstructConfigForAllReduceUniDirND — 0x133c2c80, line 41
arg0 = ((~a8 & 0x101) != 0) & (unsigned __int8)~ShouldEnableSparseCoreHierarchicalAllReduce;
// ^ a8 = caller's 16-bit HierarchicalKind ^ the §3.1 enable predicate
```text
> `0x133c2c80` 第35行在`GetTpuCompEnv(module, all_reduce)`的结果上调用`ShouldEnableSparseCoreHierarchicalAllReduce`;第 41 行将其与 `(~a8 & 0x101) != 0`(其中 `a8` 是调用者提供的 `unsigned __int16` 类型)一起折叠到转发给构建器的领先 `bool` 中。第 49/52/57 行的 RetCheck/error 字符串引用 `platforms/xla/sparse_core/offload_collective_config.cc`,固定翻译单元。
将第 41 行读取为布尔逻辑,`arg0` 为 true(意味着 **“使用平坦路径”**),除非**两者**都成立:
1. `ShouldEnableSparseCoreHierarchicalAllReduce` 为 true — 编译标志已启用 + true (`0x101`),**和**
2. `(~caller_kind & 0x101) != 0` — 即 `(caller_kind & 0x101) != 0x101`:调用者自己的可选 `HierarchicalKind` 覆盖本身**不会**强制分层编码关闭。
因此,仅当全局标志处于engage+true *并且*调用者的可选覆盖不会否决它时,才能到达分层臂。当该标志的默认值为 false (§2) 时,AllReduce(如 AllGather 和 ReduceScatter)将保持平稳运行,除非显式启用 `xla_tpu_enable_sparse_core_hierarchical_all_reduce`。
---
## 6. 重新实施清单
- 将 `HierarchicalKind` 表示为 16 位字,**不是**密集枚举。当使用源标志时,用 `value(0/1) | 0x100` 打包;如果不是,则发出 `0x000`。
- 通过 `xla_tpu_enable_sparse_core_hierarchical_all_reduce` 从 `AutoOr<bool>` 风格的包装器读取源代码;默认标志为 false。
- 使用掩码 `0x101` 进行分类:`== 0x101` → 分层,`== 0x100` → 明确平坦,其他任何 → 平坦后备。将“启用分层”表示为 `(~v & 0x101) == 0` (≡ `(v & 0x101) == 0x101`)。
- 在构建器中,**仅** `0x100` 视为平坦(`(kind & 0x101) == 0x100`);将每个其他值路由到多相臂,由 `(~kind & 0x101) == 0` 进行内部保护。
- 将 `HierarchicalKind = 0x100` 固定在 AllGather 和 ReduceScatter 包装器中。只有 AllReduce 包装器计算类型;它的主要“use-flat”布尔值是 `(!ShouldEnable) | ((caller_kind & 0x101) == 0x101)`-neated - 即平坦,除非 flag-engages-true 并且调用者覆盖不会强制平坦。
---
## 7. 验证说明
> 对照 `libtpu.so` v0.0.40 的 IDA 反编译进行交叉检查:
>
> - **包装** — `AutoOr<bool>::FromProtoOrDie @0xf795300`:当接合字为零时,`return v11 | 0x100u`(接合+值)/ `return 0`(第16-17行)。仅 `0x000`/`0x100`/`0x101` 是可发射的。 `LOG(FATAL)` 源 `flag_types.h:845` 确认了 `jellyfish` 标志包装器。
> - **默认** - `AbslFlagDefaultGenFor… @0x1d726a00` 存储 `0` (标志默认 false);注册到`TpuCompilationEnvironment`。
> - **启用谓词** — `ShouldEnableSparseCoreHierarchicalAllReduce @0x1d6b6d80` 第 13 行:`(~v2 & 0x101) == 0` == `(v2 & 0x101) == 0x101`。
> - **调度** — AllReduce 构建器 `@0x133c2dc0` 第 806 行:`(v63 & 0x101) != 256`; AllGather 构建器 `@0x133c82c0` 第 3032 行掩码 `& 0x101`,第 3102/3525 行 `== 256`,第 3204/3262 行 `(~v & 0x101) == 0`。
> - **包装器映射** — AllReduce 包装器 `@0x133c2c80` 第 35 行 (`ShouldEnable…`) + 第 41 行 (`((~a8 & 0x101) != 0) & ~ShouldEnable`); AG/RS 包装器 (`0x133c76c0` / `0x133ccbe0`) 引脚 `0x100`。 TU `offload_collective_config.cc`(包装线 49/52/57)。
> - **每轴ringDim** — 种类只选择分解;每轴环尺寸为`2 - (NDPlaneInfo[+0xa0] & 1)`(AllReduce体`@0x133c2dc0`线704 `2 - (v20[40] & 1)`),独立于`HierarchicalKind`。
>
> **[LOW]** 16 位字的内部位(`0x02..0x80`、`0x200..0x8000`)在构建器观察到的每个值中均假定为零 - 与仅发出 `0x000`/`0x100`/`0x101` 的加壳器一致,但`HierarchicalKind`携带任意内部位未被执行。 §4表的`0x001`(未参与,值位设置)行只能通过算术访问,不能通过打包器访问,并且永远不会被包装器转发;包含它是为了 `& 0x101` 解码的完整性。
---
## 交叉引用
### 这种分解之间切换
- [SC-卸载配置生成器](sc-offload-config-builder.md) — 消耗 `HierarchicalKind` 的模板化构建器主体,以及它提供的三个 `*OffloadConfig` 结构体
- [分层 AllReduce / Pincer](allreduce-hierarchical-pincer.md) — `0x101` 多相发射(D2D + 每轴环)和 `IciStrategyRingConfig` 叶场图
### 基材和选择上下文
- [On-Pod 集体 — 剖面图](overview.md) — SparseCore 卸载基底分割和策略选择器
- [SelectND策略](strategy-nd-picker.md) — 密集的 `StrategyND` 选择器,其相位分裂该镜子
- [ReduceScatter](reduce-scatter.md) — 扁平固定在卸载路径中(其包装硬线 `0x100`)
- [SC 核心选择(卸载)](sc-core-selection-offload.md) — 构建器上游的卸载操作类型分类
- [张量分裂ND平面](tensor-split-ndplane.md) — 选择每轴 `X_TORUS` 与 `X_MESH` 的 `NDPlaneInfo[+0xa0]` 奇偶校验字(与类型正交)
- [返回索引](../index.md)