Skip to content

全局屏障 SFLAG 窗口和 REPLICA 路径

二进制: extracted/libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so(构建 ID 89edbbe81c5b328a958fe628a9f2207d,构建 libtpu_lts_20260413_b_RC00.text VMA == 文件偏移 0xe63c000.rodata VMA == 文件偏移)。 状态: 重新实现级 · 证据等级: 已确认(字节锚定) - GetGlobalBarrierSyncFlagNumber 公式、GetBarrierSyncFlag 调度、MaybeInsertGlobalBarrier 插入门和 REPLICA 树路径(BarrierWithinReplicaGroupStartImplVsyncAddRemote) 是字节精确的;每代保留整数的字面量是嵌入式内存文件依赖项(低,请参阅第 5 节)· 第 XIII 部分 — On-Pod Collectives & Barriers / SFLAG & Barriers · 返回索引

摘要

在这个二进制文件中,短语“全局屏障”在两个不同的定序器上命名三个不同的事物,每个事物都来自不相交的保留 SFLAG 区域。此页面拥有实际名称为 GetGlobalBarrierSyncFlagNumber 的页面 - base + count + 4 处的 TensorCore (TC) 保留的全局槽位 - 以及围绕它的两个结构:插入门 CustomKernelEmitter::MaybeInsertGlobalBarrier @0x1321ac20(它决定 是否 SparseCore 函数在不同的 SFLAG 窗口上获得全局屏障)完全),以及 TC GLOBAL 机器共享的 REPLICA(2) 屏障路径 — 通过相同的 net_util::GetBarrierSyncFlag 映射器和 BarrierCoresTree 执行器到达副本组内树屏障。

决定性的结构事实以及此页面存在的原因是 SparseCore Mosaic 发射器的 MaybeInsertGlobalBarrier 从不调用 GetGlobalBarrierSyncFlagNumber。这两者在历史上曾被混为一谈。完整的 .text E8/E9 rel32 外部参照扫描发现 20 个 GetGlobalBarrierSyncFlagNumber @0x1d60f420 的直接调用者,并且 没有一个 位于 SparseCore 自定义内核发射器中。全局SFLAG编号仅属于TC引擎; MaybeInsertGlobalBarrier 插入的 SC 功能级全局屏障在其自己的每核 Mosaic 窗口上运行。

SFLAG 数字公式位于 屏障到 SFLAG 的绑定 上; 按代号编译器保留 上每代的 {base, count} 整数; 推断屏障配置 上的 BarrierConfig 类型分类。此页面拥有全局屏障 SFLAG 窗口保留、MaybeInsertGlobalBarrier 插入门以及全局屏障共享的 REPLICA 路径

重新实现,合约为:

  • 全局 SFLAG 插槽是一个数字,保留在 TC 块的顶部。 GetGlobalBarrierSyncFlagNumber 返回 base + count + 4 — TC 保留范围 (§2) 的五个指定顶部插槽中最高的一个。它是计算出来的,从不存储在BarrierConfig中; GLOBAL 配置带有 id = -1
  • MaybeInsertGlobalBarrier 是一个门,而不是数字源。 它在 SparseCore Mosaic 端运行,读取 CustomCallConfig 标志 + BarrierConfig.type,并决定是否在 SC 每核窗口上插入函数级树屏障 - 它不计算 GetGlobalBarrierSyncFlagNumber (§3)。
  • 全局槽的使用者集是 TC 引擎。 net_util::GetBarrierSyncFlag(BarrierConfig → SFLAG 映射器)、net_util 树屏障系列(BarrierCoresTreeBarrierAllCores*)以及内存预留通道 — 所有 TensorCore LLO (§1)。
  • REPLICA(2) 是仅 TensorCore 的屏障类型。 它映射到 base + id(不是全局槽),并通过 BarrierCoresTree(REPLICATED/PARTITIONED)BarrierWithinReplicaGroupStartImplVsyncAddRemote 降低到当前核心的副本组对等体;成员资格是 InfoTable 文字。 SparseCore RetChecks 类型 2 (§4)。
全球 SFLAG 编号GetGlobalBarrierSyncFlagNumber @0x1d60f420 = base + count + 4 (this[560]/this[561] = Target+0x8c0/+0x8c4)
预留窗口TC块[base, base+count)的前5个插槽; GLOBAL 位于 +count+4,MEGACORE 位于 +count
消费套装20 个直接调用者,所有 TC LLO(net_util::GetBarrierSyncFlagBarrierCoresTreeBarrierAllCores*、内存预留通行证); SparseCore 发射器调用者
BarrierConfig → SFLAG 映射器net_util::GetBarrierSyncFlag @0x1c69ad00(全局→base+count+4,其他→base+id)
插入门(SC 马赛克)CustomKernelEmitter::MaybeInsertGlobalBarrier @0x1321ac20(3 个 RetCheck 门;调用全局访问器)
复制品生产者DetermineBarrierConfigForKey @0x109c6fa0(为单个非分区副本组写入 type=2, id=key id)
复制执行器BarrierWithinReplicaGroupStartImpl @0x1c698080VsyncAddRemote @0x1d522f40 到 InfoTable 对等点
来源 TU 锚点net_util.ccbarrier_assignment.cccustom_kernel_emitter.ccoffload_a2a_util.cc

1.全局SFLAG槽:数量、窗口、消费者

“全局屏障同步标志”是在 TensorCore 保留块顶部保留的单个 SFLAG 编号。它是按需计算,从未在配置字段中携带 - GLOBAL BarrierConfig 存储哨兵 id = -1,并且降低会替换计算的插槽。

1.1 GetGlobalBarrierSyncFlagNumber @0x1d60f420

访问器是两个添加。反编译得到的字节精确:

c
// xla::jellyfish::Target::GetGlobalBarrierSyncFlagNumber(Target *this)   // 0x1d60f420
__int64 GetGlobalBarrierSyncFlagNumber(Target *this) {
    return (unsigned int)(*((_DWORD *)this + 561)    // Target+0x8c4 = count
                        + *((_DWORD *)this + 560)    // Target+0x8c0 = base
                        + 4);
}
```text

`this[560]` 是 TC reserved-block **base**(`Target+0x8c0`);`this[561]` 是 **count**(`Target+0x8c4`,其中 `count = |compiler_reserved(TensorCore)|5`)。结果是 `base + count + 4`,即保留在 per-id 窗口 `[base, base+count)` 之上的五个命名顶部槽位中的**第五个也是最高**。slot 推导、`−5` carve,以及 sibling accessor(`GetMegacoreBarrierSyncFlagNumber` = `base+count`、两个 `GetAllReduceSyncFlagNumber` 槽)在 [Barrier-to-SFLAG Binding](barrier-to-sflag-binding.md) 中推导;per-codename `{base, count}` 整数见 [Per-Codename Compiler-Reserved](per-codename-compiler-reserved.md)。本页不重新推导它们,而是记录该窗口的*消费者*和 GLOBAL/REPLICA *路径*

> **注意 —** 全局槽**不在**每个 ID 窗口中。 REPLICA(2)/CUSTOM(3) id 满足 `0 <= id < count` 并映射到 `base + id`(§4,§1.2); GLOBAL 是 `base + count + 4`,位于顶部可用 id 上方的四个插槽。两人从不别名。

### 1.2 `net_util::GetBarrierSyncFlag` @`0x1c69ad00` — `BarrierConfig → SFLAG` 映射器

全局槽的主要消费者是 TC 密集集合 `BarrierConfig → SFLAG` 映射器。它在 `BarrierConfig.barrier_type` 的 `[bc+0x20]` 上发货。字节精确:

```c
// net_util::GetBarrierSyncFlag(BarrierConfig const& bc, LloRegionBuilder b)   // 0x1c69ad00
int GetBarrierSyncFlag(BarrierConfig const& bc, LloRegionBuilder b) {
    int type = *(int*)(&bc + 0x20);
    if (type == 1) {                                   // GLOBAL
        int n = b.target()->GetGlobalBarrierSyncFlagNumber();   // base + count + 4
        return b.SflagImmPtr(n, "global barrier sync flag");
    }
    if (type == 0)                                     // BARRIER_INVALID
        CHECK_FAIL("barrier.barrier_type() != BarrierType::BARRIER_INVALID");  // net_util.cc:2065 (0x811)
    // type 2 (REPLICA) / 3 (CUSTOM) / 4 (MEGACORE):
    long id = *(long*)(&bc + 0x18);
    CHECK(id < *(int*)(b.target() + 0x8c4));           // "barrier.id() < b.target().GetBarrierSyncFlagCount()", :2070 (0x816)
    int n = id + *(int*)(b.target() + 0x8c0);          // base + id
    return b.SflagImmPtr(n, "barrier sync flag number");
}

算术:GLOBAL → base + count + 4(保留的全局槽位); 每个 ID (2/3/4) → base + id0 <= id < countBARRIER_INVALID(0) 是硬 CHECK-fail;槽值返回时包装为 SflagImmPtr(发射器发出信号/等待的直接 LloValue)。这是 SparseCore GetSyncFlagForBarrierId (id + SC_base) 的 TensorCore 模拟 — 相同​​的结构,不同的 Target 字段和不同的定序器/操作系列 (屏障到 SFLAG 的绑定)。

GetBarrierSyncFlag有18个直接调用者,全部为xla::jellyfish密集集体发射器(AllGather/RingSum/Binomial/RotatedPincer/CollectivePermute/AllToAll);每个读取由 TensorCoreBarrierAssignment 选择的 HLO BackendConfig.BarrierConfig 并通过 net_util 树屏障助手发出集合点。

1.3 消费者集(20 个调用者;全部 TensorCore)

E8/E9 rel32 解析为 0x1d60f420 的整体 .text 扫描发现 20 直接调用站点;每个都解析(通过排序的符号表)为 xla::jellyfish TensorCore LLO / 运行时函数。 SparseCore Mosaic 自定义内核发射器中没有** - 确认 MaybeInsertGlobalBarrier (§3)、EmitScsBarrierEmitAllToAllBarrierStart 从未接触过 Target+0x8c0/+0x8c4。来电者分为四组:

集团功能(代表)角色
A。配置映射器net_util::GetBarrierSyncFlag @0x1c69ad00BarrierConfig → SFLAG 映射器 (§1.2) — 主要指定消费者
B。树障家族BarrierCoresTree @0x1c6a75c0; BarrierAllCoresStartNoReturn @0x1c697b60; BarrierAllCoresJoin @0x1c697e60BarrierAllCoresWithIdVerification @0x12715900BarrierCoresWithIdVerificationInternal @0x12715c00; MaybeDistributeStackBaseAddresses @0x1c69ae00运行时ICI/跨核心树屏障(GLOBAL执行器)
C。内存保留/分析DoMemoryAllocation @0x10a31ee0(×4个站点); LinkAndFinishProgram @0x10a25a20; AllocateHloOutputsInMemorySpace @0x1c439980ComputeAvailableSyncFlags @0x1c6e42a0RaceAnalyzerStepper::PreProcessEvent @0x10bb2a60; Processor::Instrument $_1 @0x10c94920; GetReferencedSyncFlags $_1 @0x10c94c60TpuCompactionIsaEmitterCodegen::Generate @0x1090ece0为 SFLAG 池中的全局槽预留/账户
D。密集集体参考AllToAllEmitter::EmitOutputAddressExchange @0x10f00dc0; SC LoweringEmitter::Emit @0x131ce4e0(+1 作为 SFLAG 范围上限,不是屏障消费者)直接引用槽位

同级 GetMegacoreBarrierSyncFlagNumber @0x1d60f4e0(= base + countMegacore() 门控)只有 3 个调用者 — SynchronizeProgramDescriptorStatesMegacoreLloRegionBuilder::BarrierMegacoreRaceAnalyzerStepper::PreProcessEvent — 即仅百万核倍运行时屏障;没有 BarrierConfig 制作人编写过 MEGACORE(4)(请参阅 推断屏障配置概述 §2 QUIRK)。

BarrierCoresTree @0x1c6a75c0 在其主体中调用 GetGlobalBarrierSyncFlagNumber 并将其包装为 SflagImmPtr("global barrier sync flag") — TC 树屏障的 GLOBAL 槽。直接在反编译中验证。


2.三个“全局屏障”,三个保留区域,两个测序仪

因为“全局”这个词被重载,所以重新实现者必须将三个不同的源分开。只有**(c)**是GetGlobalBarrierSyncFlagNumber;该页面拥有 (c) 和产生 (a) 的门。

#什么选择/插入SFLAG 编号来源定序器/运算系列
(a)SC 马赛克 功能级 树屏障CustomKernelEmitter::MaybeInsertGlobalBarrier @0x1321ac20 (§3)SC Mosaic 每核窗口(mlir::sparse_core::MemorySpaceAttr::get(ctx, 14) — SC MLIR 枚举,不是 jellyfish MemorySpaceAllocateAtOffsetOp); 不是 GetGlobalBarrierSyncFlagNumberTC 音序器(马赛克)tpu.sem_signal/tpu.sem_wait in scf.for
(b)SC 每个集体全局屏障EmitScsBarrier(type1) / EmitAllToAllBarrierStart(type1)EmitGlobalBarrier @0x13352820GetSyncFlagForBarrierId(reserved id) = id + SC_base(SC 屏障块)SC 定序器 sc_tpu.sync_add SC 内核树
(c)TC LLO 保留全局插槽net_util::GetBarrierSyncFlag(type1) @0x1c69ad00; BarrierCoresTree 等 (§1)GetGlobalBarrierSyncFlagNumber() = base + count + 4(TC屏障块)TC 定序器 Vsync* / net_util 树屏障

这三者存在于三个数字空间中:(a) SparseCore Mosaic 每核窗口(mlir::sparse_core::MemorySpace 值 14 — SC MLIR 枚举,与水母 MemorySpace 枚举不同,其中 14 = sparse_core_sequencer_smem); (b) SC 屏障块; (c) TC 屏障块 [base, base+count],GLOBAL 插槽位于 +count+4。 (a)和(b)是SparseCore; (c) 是 TensorCore。 GetGlobalBarrierSyncFlagNumber 仅属于 TC 引擎 — 这正是 SparseCore MaybeInsertGlobalBarrier 从不调用它的原因。源 (c) 不是 SC 树屏障 (a):它们是不同的 Target/SparseCoreTarget 字段和不同的定序器。


3. MaybeInsertGlobalBarrier @0x1321ac20 — 插入门

CustomKernelEmitter::MaybeInsertGlobalBarrier 是 SparseCore Mosaic 入口点,决定是否自定义调用函数被赋予函数级全局屏障,并且 - 如果是 - 将其插入到 SC 每核窗口中。它是一个,而不是 SFLAG 编号源:它读取 CustomCallConfig 标志和 BarrierConfig.type,运行三个合法性 RetCheck,然后遍历 func 的操作以在适当的核心类型上实现屏障。它不计算 GetGlobalBarrierSyncFlagNumber

3.1 签名和输入

c
// xla::tpu::sparse_core::CustomKernelEmitter::MaybeInsertGlobalBarrier(
//     mlir::ModuleOp module, CustomCallConfig const* cfg, BarrierConfig const* bc)   // 0x1321ac20
```text

反编译显示`a1` =模块句柄,`a2` =模块上的遍历迭代器,`a3` = `CustomCallConfig*`,`a4` = `BarrierConfig*`(可能为空)。门从 `CustomCallConfig` (`a3`) 中读取三项内容,从 `BarrierConfig` (`a4`) 中读取一项内容:

| 反编译读取 | 含义(归因于使用 + RetCheck 字符串) |
|---|---|
| `v4 = cfg[+0x10]` 标志双字;位 `0x200` | *has-communication* 字节的存在防护 |
| `v5 = cfg[+0x90]`(如果位 `0x200` 则只读) | **has-communication**标志(自定义调用通信) |
| `v4` 位 `0x2000` | *skip-device-barrier* 字节的存在防护 |
| `v6 = cfg[+0x94]`(如果位 `0x2000` 则只读) | **skip_device_barrier** 标志 |
| `v4` 位 `0x40` | **自定义屏障请求**标志(附有 `BarrierConfig`) |
| `v7 = (bc->type [a4+0x20] == 3)` | 附加屏障为 `CUSTOM(3)` |

### 3.2 三个合法性门(字节精确)

主体解析四个谓词,然后保护三个错误路径,每个路径都有一个锚定到 `custom_kernel_emitter.cc` 的 `absl::Status` `MakeErrorImpl<3>` (`kInvalidArgument`):

```c
result = 1;  // OK / kOk by default
// GATE 1 — a barrier was requested for a non-communicating custom call.
if ((flags & 0x40) && !has_communication)
    return Error("Custom barrier requested for non-communicating custom call.");   // :3560

// GATE 2 — communication needs a global barrier, but the compiler couldn't allocate a
//          dedicated SFLAG *and* Mosaic isn't allowed to fall back to a device barrier.
//   reached only when (flags & 0x40) is set, has_communication is true,
//   the attached barrier is NOT CUSTOM(3) (v7 == false), and skip_device_barrier (v6) is set:
if ((flags & 0x40)) {
    if (bc->type == 3 /*CUSTOM*/) return result;          // dedicated barrier already allocated → no insert
    if (skip_device_barrier)
        return Error("The compiler failed to allocate a barrier semaphore and Mosaic "
                     "wasn't allowed to perform a global barrier due to skip_device_barrier.");   // :3572
} else if (skip_device_barrier) {
    return result;                                        // no barrier requested + skip → nothing to do
}

// INSERT — walk the module's ops; pick the core-type variant, materialise the barrier.
v12 = 2 - HasAnyCoreType(walk, &kSparseCoreType, 1);      // core-type selector (TC vs SC variant)
ok  = mlir::detail::walk<ForwardIterator>(walk, MaybeInsertGlobalBarrier::$_0(FuncOp), &state, /*WalkOrder=*/1);
// GATE 3 — the walk found no func it could attach a barrier to.
if (!ok) return Error("Requested barrier for unsupported core type");   // :3681
return result;  // OK

重新实现者的语义:

  • 当自定义调用进行通信(has_communication)并且明确请求屏障(标志 0x40)而没有可用的专用 CUSTOM(3) 配置时,或者到达失败插入路径时,才会插入全局屏障。 CUSTOM(3) 配置意味着编译器已经分配了每个键的 SFLAG(通过着色生成器),因此 MaybeInsertGlobalBarrier 返回 OK,而不插入函数级全局 SFLAG。
  • skip_device_barrier逃生舱口:如果 Mosaic 被告知不要发出设备范围的屏障,并且没有分配专用信号量,则门 编译失败(GATE 2),而不是默默地丢弃集合点 - 避免死锁的硬错误。
  • 实际的屏障物化是 walk 回调 MaybeInsertGlobalBarrier::$_0(FuncOp 访问者):它在 SC 每核窗口(§2 中的源 (a))上构建 AllocateAtOffsetOp(MemorySpace::sflag) + scf.for(tpu.sem_signal/tpu.sem_wait) 树,由v12 = 2 − HasAnyCoreType(...)。这不是** GetGlobalBarrierSyncFlagNumber — SFLAG 偏移量来自 Mosaic 每核内存预留,而不是 TC Target+0x8c0 块。树协议本身位于 树屏障/vSync 上。

GOTCHA — 三个 CustomCallConfig 字段偏移(+0x10 标志、+0x90 has-communication、+0x94skip_device_barrier)和位掩码(0x200/0x2000/0x40)是来自反编译读取的字节确认;字段 names(has_communicationskip_device_barriercustom_barrier_requested)源自 RetCheck 字符串("non-communicating custom call""due to skip_device_barrier"),而不是来自原始描述符。所有三个门的行为均已确认。

注意 — 行号。 三个错误站点是 custom_kernel_emitter.cc:3560:3572:3681BarrierConfig.type == 3 读取确认唯一短路全局插入的屏障类型是 CUSTOM(3);附加到通信自定义调用的 GLOBAL(1)/REPLICA(2) 仍采用插入路径。这些与 概述 §3.3 中总结的降低门相匹配。


4. REPLICA(2)路径全球屏障份额

REPLICA(2)TensorCore-only 屏障类型。它不是全局插槽 - 它像 CUSTOM(3) 一样映射到 base + id - 但它与 GLOBAL 屏障一样使用相同的 net_util::GetBarrierSyncFlag 映射器(第 1.2 节)和相同的 BarrierCoresTree 执行器,区别仅在于它选择了哪个 TreeBarrierType(以及哪个对等集)。这就是为什么全局屏障窗口和 REPLICA 路径被记录在一起:它们共享映射器和树屏障引擎;它们仅在对等集(所有核心与副本组对等体)和 SFLAG 插槽(+count+4base+id)处出现分歧。 生成 REPLICA 配置的分类位于 推断屏障配置 上; 复制品屏障 上的完整 REPLICA 降低。本节记录共享路径。

4.1 制作人 — DetermineBarrierConfigForKey @0x109c6fa0

TensorCoreBarrierAssignment::DetermineBarrierConfigForKey(key, config, has_conflict) 构建 BarrierConfig。字节精确决策树:

c
// 0x109c6fa0
BarrierConfig DetermineBarrierConfigForKey(TensorCoreBarrierKey key, HloModuleConfig config, bool has_conflict) {
    BarrierConfig bc{};                                      // ctor(0)
    bool beneficial = IsGlobalBarrierBeneficial(key, config);   // 0x109c6ee0
    if (has_conflict || beneficial) {                        // → GLOBAL(1)
        bc.type = 1;  bc.id = -1;                            // movl $1,+0x20 ; movq -1,+0x18
    } else if (key[+0x10] /*group begin*/ == key[+0x20] - 1 /*group end−1*/) {   // single replica group
        if (config[+0x50] /*partition flag*/ != 1) {         // → REPLICA(2)
            bc.type = 2;  bc.id = key[+0x10];                // shared key id
        } else {                                             // → GLOBAL(1) (partition-scoped singleton)
            bc.type = 1;  bc.id = -1;
        }
    } else {                                                 // → CUSTOM(3)
        bc.type = 3;  bc.id = <fresh via __try_key_extraction_impl @0x109cbd60>;
    }
    bc.hasbits |= 3;                                         // type + id present (orb $3, +0x10)
    return bc;
}
```text

`IsGlobalBarrierBeneficial` @`0x109c6ee0` 对于**单一维度**返回 true:由 `key[+0x51]` 门控(ICI 路由已知标志 - 当清除时,它会在 `VLOG`“由于未知 ICI 路由限制而跳过全局屏障优势的评估。”)和`key[+0x50] == 0`(分区标志,此处请重点阅读),然后检查 `+0x170` (replica_count) / `+0x178` (num_partitions) 处的配置派生轴对,并仅当其中一个轴为 `1` **** `key[+0x10] == 1` (最好由全核全局屏障)。生产者通行证仅写入 `{1, 2, 3}` — **从不写入 `MEGACORE(4)`**

因此,`REPLICA(2)` 是**每个副本组共享**障碍:*单个*副本组,**分区范围(`config[+0x50] != 1`),**计划冲突,并且**全局受益。它的`id`是共享密钥id(组中的多个集体重用它),满足§1.2中`base + id`映射的`0 <= id < count`。

### 4.2 降低 (TensorCore) — `BarrierCoresTree` 范围仅限于副本组

具有 `BarrierConfig.type == 2` 的 TC 密集集体通过其发射器的 `BarrierStart` 降低(例如 `AllGatherEmitter::BarrierStart` @`0x13809520`)。类型调度 (`r15d == 2`) 使用 `net_util::TreeBarrierType` = `(target_predicate ^ 1)` 调用 `$_3` 闭包 — 即 `REPLICATED(1)` 或 `PARTITIONED(2)`。 SFLAG 本身来自 `GetBarrierSyncFlag(bc)` → `base + id` (§1.2),以及 `$_3` → `net_util::GetRegistryTreeBarrierInfoProvider` @`0x1c6a7480` + `net_util::BarrierCoresTree` @`0x1c6a75c0`:

```text
BarrierConfig{type=2, id} ──GetBarrierSyncFlag──▶ sflag = base + id
                          ──$_3(TreeBarrierType)──▶ BarrierCoresTree

   GetOrCreateTreeBarrierInfoTable @0x1c6b60e0:      ▼
     TreeBarrierType 0 ALL_CORES   → variant 0x23  (kAllCoresTreeBarrierInfoTable        @0xb433290)
     TreeBarrierType 1 REPLICATED  → variant 0x2a  (kReplicatedCoresTreeBarrierInfoTable @0xb4332c0)
     TreeBarrierType 2 PARTITIONED → variant 0x2b  (kPartitionedCoresTreeBarrierInfoTable@0xb4332f0)

   BarrierWithinReplicaGroupStartImpl @0x1c698080:   ▼
     GetReplicaGroupCoreInfo  → this core's group peers (from the InfoTable)
     Pneg + Predicated        → gate participation
     for each peer: VsyncAddRemote(sflag, peer)  → signal the peer's barrier sflag
   BarrierWithinReplicaGroupDone @0x1c6984e0 → wait

GLOBAL 屏障在所有核心上采用与 TreeBarrierType = ALL_CORES(0) 相同的 BarrierCoresTree 路径; REPLICA 将对等点集缩小到当前核心的副本组。执行器操作是 VsyncAddRemote @0x1d522f40 — 向每个对等点发送 SFLAG 信号,然后等待 — SparseCore sc_tpu.sync_add (树屏障/vSync) 的 TC 模拟。

BarrierWithinReplicaGroupStartImpl @0x1c698080:反编译显示GetReplicaGroupCoreInfo(解析组对等体),Pneg @0x1d5208e0 + Predicated @0x1d520f00(参与门)和 VsyncAddRemote(对等信号)。对等集是当前核心的副本组,而不是所有核心。

4.3 成员编码 — 副本组 InfoTable

副本组成员资格是预先计算的 int 成员资格表,而不是位掩码或每环常量文字切片。 net_util::CreateReplicaInfoTable(absl::Span<xla::ReplicaGroup const>, replica_count, partition_count, …) @0x1c69b660CreateStaticReplicaInfoTable @0x1c69b780 将 HLO 集合体的 replica_groups 属性展平为由 xla::Literal R1 int 数组支持的 xla::InfoTable (LiteralUtil::CreateR1<int> @0x10aa05e0)。 GetReplicaGroupCoreInfo 以当前核心的序号读取此表以恢复其组对等 ID。 RegisterTreeBarrierInfoTables @0x1c6a8620 每个程序将 ALL/REPLICATED/PARTITIONED 表预注册到 ProgramSharedRegistry 中一次; GetRegistryTreeBarrierInfoProvider 在发出时获取它们(通过 GetReplicaGroupCoreInfoCache 缓存)。

4.4 为什么 REPLICA(2) 在 SparseCore 上永远不会降低 - 以及名称陷阱

两个 SparseCore 自定义内核屏障入口点 RetCheck 类型 2:

  • EmitScsBarrier @0x13352500:仅限==1 GLOBAL / ==3 CUSTOM;否则重新检查。
  • EmitAllToAllBarrierStart @0x133500e0:仅限==1 GLOBAL / ==3 CUSTOM; else RetCheckFailSlowPath(offload_a2a_util.cc:124) "backend_config.barrier_config().barrier_type() == jellyfish::BarrierType::GLOBAL",消息**“SparseCore 上的所有集合仅支持自定义和全局屏障”**。

GOTCHA — EmitReplicaGroupCustomBarrierStart 名称陷阱。 SparseCore 函数字面名为 EmitReplicaGroupCustomBarrierStart @0x13353620 是 SC A2A CUSTOM(3) 屏障(和显式 id 路径)的降低,对于 BarrierType::REPLICA 不是。它向组中的每个成员发出一个谓词 sc_tpu.sync_add,该组的成员资格位于传递的 BufferOffset 处的 SMEM 缓冲区中,这与 TC REPLICA(2) 不同,TC REPLICA(2) 的成员资格是 InfoTable 文字(第 4.3 节)。在 SparseCore 上,根本没有** BarrierType-REPLICA(2) 降低;嵌入集合仅使用 GLOBAL(1)CUSTOM(3)REPLICA(2) 是 TensorCore 密集集合势垒类型独有

EmitAllToAllBarrierStart @0x133500e0:RetCheck 字符串和消息逐字存在于 barrier_type 调度的 else 臂的反编译中 — REPLICA(2) 在 SparseCore 上被拒绝。


5. 验证说明

libtpu.so v0.0.40 中的字节精确:

  • GetGlobalBarrierSyncFlagNumber @0x1d60f420this[561] + this[560] + 4 = base + count + 4 — 准确。
  • net_util::GetBarrierSyncFlag @0x1c69ad00type==1target()->GetGlobalBarrierSyncFlagNumber()SflagImmPtr("global barrier sync flag")type==0 → 检查失败(net_util.cc:2065);否则 → 检查 id < target[0x8c4] (:2070) → id + target[0x8c0]SflagImmPtr("barrier sync flag number") — 准确,偏移量 0x8c0/0x8c4 (=2240/2244) 已确认。
  • MaybeInsertGlobalBarrier @0x1321ac20:从 cfg[+0x10] 读取的标志(位 0x200/0x2000/0x40), cfg[+0x90]/cfg[+0x94]bc->type [+0x20] == 3;三个错误位点custom_kernel_emitter.cc:3560/:3572/:3681身体任何地方都不能调用GetGlobalBarrierSyncFlagNumber;通过 mlir::detail::walk(MaybeInsertGlobalBarrier::$_0)v12 = 2 − HasAnyCoreType(...) 插入 — 准确。
  • DetermineBarrierConfigForKey @0x109c6fa0: if (has_conflict || IsGlobalBarrierBeneficial)type=1, id=-1;否则 if (key[+0x10] == key[+0x20]−1) 然后 config[+0x50]!=1type=2, id=key[+0x10] 否则 type=1,id=-1;否则 → type=3, id=freshhasbits |= 3 — 精确(分区标志读取反汇编为 cmpb $0x1,0x50(%r14),其中 %r14=HloModuleConfig,第二个参数 — config,而不是密钥); 没有 movl $4
  • BarrierCoresTree @0x1c6a75c0:调用 GetGlobalBarrierSyncFlagNumberSflagImmPtr("global barrier sync flag") — 在正文中确认。
  • BarrierWithinReplicaGroupStartImpl @0x1c698080GetReplicaGroupCoreInfo + Pneg/Predicated + VsyncAddRemote — 已确认。
  • EmitAllToAllBarrierStart @0x133500e0:REPLICA(2) RetCheck(offload_a2a_util.cc:124,“SparseCore 上的所有集合仅支持自定义和全局屏障”)- 已确认。

[HIGH] CustomCallConfig 字段名称(has_communication @+0x90skip_device_barrier @+0x94custom_barrier_requested0x40)和TensorCoreBarrierKey 字段标识(+0x10/+0x20 组范围;+0x50 分区标志和 +0x51 ICI 路由已知防护,由 IsGlobalBarrierBeneficial 读取)— 字节确认的偏移量,来自 RetCheck 字符串和配置读取的名称,而不是来自结构体描述符。注意:DetermineBarrierConfigForKey 内的 REPLICA-vs-GLOBAL 分区测试从 HloModuleConfig (%r14) 读取不同 +0x50 字节,而不是从密钥读取。

[LOW] 每个 (codename, deployment) {base, count} 整数的文字 (Target+0x8c0/+0x8c4) 是从嵌入式芯片配置内存文件 blob 运行时解析的,并且不是静态提取的;窗口几何(count = |CR_TC| − 5,GLOBAL @ +count+4)已确认。请参阅 按代号编译器保留。 net_util InfoTable 在线索引(GetReplicaGroupCoreInfo 如何映射核心序数→其在扁平 R1 int 文字中的对等集)未完全反汇编 - 被证明是 replica_count × partition_count 键控的 int 表;每个条目的含义为“低”。


交叉引用

屏障算法(本节)

同级子系统