Skip to content

Target Capability Bitfield(Target+0x628)

本页中的所有地址、偏移和 bit 位置都适用于 libtpu-0.0.40-cp314 wheel(BuildID md5 89edbbe81c5b328a958fe628a9f2207d)中的 libtpu.so。其他版本会有所不同。

摘要

xla::jellyfish::TargetTarget+0x628 处携带一个 64-bit “has-bits” qword。尽管它以完整 uint64_t 读写,对整个 .text 的操作数扫描证明,此构建只设置和测试其中两个 bit:bit-0(mask 0x1)和 bit-2(mask 0x4)。所有其他 bit,包括 bit-1、bit-3 和全部更高 bit,都没有设置点也没有测试点;这个 qword 是一个留有扩展空间的 feature word,但此构建只使用了两个槽位。

该 qword 紧跟在一个两项 inline array 之后,数组元素是continuation-queue scoped-memory-region 描述符(Target+0x580Target+0x5F0)。每个 bit 都是一个描述符的存在标志:bit-0 记录 TensorCore region 已追加,bit-2 记录 SparseCore region 已追加。两个 append 都在同一个 megachip / SparseCore-offload feature-detect 谓词下运行,因此 bit-2 最终成为 Target::IsMegachip() 的有效项,也就是 SparseCore lowering 和 Deepsea compiler driver 中 102 个内联 testb $0x4,0x628 站点读取的 gate。

怪癖 — entry-B 是 GetContinuationQueues(2),而 2 在运行时 TpuCoreType enum 中是 kSparseCore{kTensorCore=0, kBarnaCore=1, kSparseCore=2},也是 tpu::TpuCoreProgram variant 的替代顺序;IsMegacorecore==2 → "Megacore SparseCore is not supported" 上的 fatal-log 也佐证了这一点)。不要把它与 chip_parts.binarypb 内部使用的 protobuf nProto 顺序 {TENSOR_CORE=1, BARNA_CORE=2, SPARSE_CORE=3} 混淆;在那里,2 是 BarnaCore。has-bits 字段由运行时 enum 构建,因此 bit-2 是 SparseCore region。

本页记录:

  • bit 布局:每个 live bit gate 的能力、它在 Target::Init 中的设置位置,以及逐 bit 的 consumer surface。
  • IsMegachip 恒等式:为什么 bit-2 是 megachip/SC-offload has-bit,以及为什么 bit-0 既不属于 megachip 也不属于 megacore。
  • 后备数据:这些 bit 所标记的两项 continuation-queue scoped-memory-region array,以及设置它们的谓词。
Bitfield 成员Target+0x628uint64_t has-bits qword
Live bitsbit-0 (0x1)、bit-2 (0x4) — 此构建中其他全部保留/未使用
设置点(两者)xla::jellyfish::Target::Init @ 0x1D60FC20
bit-2 accessorxla::jellyfish::Target::IsMegachip @ 0x10914F60(内联于 102 个 testb $0x4 站点)
bit-0 consumerDeepseaCompilerBase::CompileInternal @ 0x10928B40(gate LloRegionBuilder::ShaltInternal
后备数组continuation-queue scoped-mem descriptors @ Target+0x580 / Target+0x5F0
Simulator fallbackTarget+0x540 byte (platform_type == iss)

Bit 布局 {#bit-layout}

该 qword 是 _has_bits_ 风格的 flags 成员。Bit 编号按 LSB-first:bit-n 的 mask 是 1 << n,因此 bit-0 = 0x1,bit-2 = 0x4,这也是本页每个 or/testb immediate 使用的约定。设置点是 Target::Init 中两段 load-or-store 序列(0x1D611D52or $0x1,%rcx 后接 mov %rcx,0x628(%r12)0x1D612121or $0x4,%rcx 后接 mov %rcx,0x628(%r12));测试点是 testb $imm,0x628(reg)。对 .text 中 offset 0x628 的穷尽操作数扫描只发现这些针对 Target 指针基址寄存器的 immediate:or $0x1 一次,or $0x4 一次,testb $0x1 两次,testb $0x4 102 次。任何地方都没有出现 $0x2$0x8 或更高 mask。

易错点 —testb $0x1,0x628 的原始操作数 grep 会返回三个命中,但其中一个(0xFE3B600,位于 PostorderDFSVisitor::PostOrderDFSVisit 内)是 testb $0x1,0x628(%rsp),也就是刚好位于 frame offset 0x628 的 stack local,而不是 Target 字段。只有两个基于 %r12/%r14 的读取(0x109280830x1090EB6E)是真正的 bit-0 测试。102 个 testb $0x4 站点全部基于指针寄存器,这组中没有 %rsp/%rbp false positive。

bitmask语义 / 名称设置点(Target::Initconsumers(测试点)
00x1TensorCore continuation-queue scoped-memory region 存在(entry-A)0x1D611D52or $0x1),在 entry-A append 之后2 个真实 testb $0x1,0x628 读取;有效 reader DeepseaCompilerBase::CompileInternal @ 0x10928083 → gate LloRegionBuilder::ShaltInternal
10x2reserved / unused in v0.0.40(从未设置)(从未测试)
20x4megachip / SparseCore-offload capability has-bit,即 Target::IsMegachip() 的有效项0x1D612121or $0x4),在 entry-B append 之后testb $0x4,0x628 ×102 = 内联 IsMegachip();SC lowering、CompileSparseCoreProgramsEmitSparseCoreAsyncStart/DoneIsValidReduceScatterForSparseCoreOffload、Deepsea Lower/RunBackend/MakeAot
3+0x8+reserved / unused in v0.0.40(从未设置)(从未测试)

注意 — qword 通过 REX.W (mov) 加载和存储,也就是 64-bit,因此物理上还有 62 个 flag 的空间。bits 1 和 3+ 是源代码中已死,还是为后续 silicon generation 前向保留,仅凭这个二进制无法区分;可以确定的是 v0.0.40 恰好驱动其中两个。


Bit-2 == IsMegachip()

102 个 testb $0x4,0x628 站点都是 Target::IsMegachip 的内联副本。该 accessor 按 byte 精确读取为三项合取:

c
char Target::IsMegachip(Target *this):                 // sub_10914F60
    cfg = *(TpuChipConfig**)(*(void**)(this+0x3B8) + 0x18);  // Target+0x3B8 -> deref -> +0x18 chip config
    if (!cfg->Megachip()                               //  TpuChipConfig+0x9  (byte)
        || *(int32*)(cfg+0x94) <= 0)                   //  TpuChipConfig+0x94 = CoresPerChip(kSparseCore)
        return 0
    if ((this[0x628] & 4) == 0)                         //  bit-2 of the has-bits qword
        return this[0x540]                              //  platform_type == iss fallback byte
    return 1                                            //  bit-2 set: megachip
```text

因此 bit-2 *就是* megachip capability:当某个 part 的 chip config 声明 `Megachip()`、至少有一个 SparseCore,并且 `Target::Init` 谓词设置了 bit-2 或者平台是 `iss` simulator(`Target+0x540`)时,该 part 就是 megachip。即使硬件谓词没有设置该 bit,simulator 路径也会强制采用该能力。`Megachip()` 本身是一次 one-byte 读取:

```c
bool TpuChipConfig::Megachip(TpuChipConfig *this):     // sub_20AFCC00
    return *((uint8_t*)this + 9)                        //  TpuChipConfig+0x9

为什么 bit-2 不是 IsMegacore

Target::IsMegacore 是另一个 accessor,完全不触碰 Target+0x628

c
bool Target::IsMegacore(Target *this, TpuCoreType core):   // sub_13699EE0
    if (core == kSparseCore=2)
        LOG(FATAL) << "Megacore SparseCore is not supported."  // target.h:1210
    cfg = *(TpuChipConfig**)(*(void**)(this+0x3B8) + 0x18);  // Target+0x3B8 -> deref -> +0x18 (same chain as IsMegachip)
    if (!cfg->Megacore())                                    // TpuChipConfig+0x8 (byte)
        return 0
    if (core >= 3) BUG()
    return *(int32*)(cfg + 0x7C + core*12) >= 2              // per-core count: TpuChipConfig+0x7C + core*12
```text

它读取 `TpuChipConfig+0x8` 处的 *Megacore* flag 和 `+0x7C+core*12` 处的逐核心计数,不引用 has-bits qword。Bit-2 只属于 megachip;bit-0 两者都不属于,它是下文描述的 TensorCore continuation-queue presence flag。

| accessor | VA | 读取 `Target+0x628`? | 公式 |
|---|---|:--:|---|
| `Target::IsMegachip` | `0x10914F60` | yes(bit-2| `Megachip ∧ CoresPerChip(SC)>0 ∧ ((+0x628 & 4) ∨ +0x540)` |
| `Target::IsMegacore` | `0x13699EE0` | no | `Megacore ∧ CoresPerChip(core) ≥ 2` |

---

## 后备数据:Continuation-Queue Scoped-Memory Regions

这两个 bit 是两项 inline array 中 continuation-queue scoped-memory-region 描述符的存在标志。`Target::Init` 在 `Target+0x580`..`Target+0x627` 构建这些描述符,has-bits qword 紧接在 entry B 的 vector 之后。每个描述符宽 `0x70` bytes:

| entry | presence bit | `name` (`std::string`) | `MemorySpace` (int32) | `std::vector<MemoryPart>` `{begin,end,cap}` | source |
|---|---|---|---|---|---|
| A | bit-0 (`0x1`) | `Target+0x580` | `Target+0x59C` | `+0x5A0` / `+0x5A8` / `+0x5B0` | `GetContinuationQueues(kTensorCore=0)` |
| B | bit-2 (`0x4`) | `Target+0x5F0` | `Target+0x60C` | `+0x610` / `+0x618` / `+0x620` | `GetContinuationQueues(kSparseCore=2)` |

每个 entry 都通过复制逐核心 continuation-queue list 构建;该 list 是 `TpuChipConfig::GetContinuationQueues` 返回的 `0x30`-byte-stride source array,随后被复制到 `0x1C`-byte-stride `MemoryPart` vector,并通过 `TpuSharedMemoryTypeToMemorySpace`(`0x1D6224E0`)映射每个元素的 shared-memory type。每次 append 后,对应 bit 都被 OR 到 `Target+0x628`。`GetContinuationQueues` 是一个小型 presence-gated lookup:

```c
auto TpuChipConfig::GetContinuationQueues(TpuChipConfig *this, TpuCoreType core):  // sub_20AFCCC0
    if (!_bittest64(this[0xC8], core))           //  presence bitmask at TpuChipConfig+0xC8
        return {nullptr, 0}
    if (core >= 3) BUG()
    return this[0x80 + core*0x18]                //  EnumMap base +0x80, stride 0x18

append 谓词(两个 entry 共用)是 megachip / SparseCore-offload feature-detect,形状与 IsMegachip 相同:Megachip() ∧ CoresPerChip(kSparseCore)>0 ∧ ((Target+0x628 & 4) ∨ Target+0x540) ∧ continuation_queue[0]==2

怪癖 — 描述符数组只存在于 C++ 运行时。Target::ToArgumentsProto0x1D60F560)不会序列化 Target+0x540..Target+0x628 区域,因此它没有 protobuf FieldDescriptor。逐 entry 布局({std::string, MemorySpace int32, std::vector<MemoryPart>}0x70-byte stride)和 GetContinuationQueues(core) source 是 byte-exact 的,但 C++ 成员名称是从 source getter 归因而来,不是从 descriptor 恢复的。重新实现应把该 qword 视为运行时状态,而不是 wire state。


Bit-0:TensorCore Continuation-Queue Presence

当 entry A,也就是从 GetContinuationQueues(kTensorCore=0) 构建的 region,被追加时,bit-0 在 Target::Init0x1D611D52)中被设置。它正好在两个真实 testb $0x1,0x628 站点被读取(第三个语法匹配 0xFE3B600%rsp stack local,不是这个字段;见 Bit 布局 中的易错点)。有效 reader 是 DeepseaCompilerBase::CompileInternal0x10928083):该测试后面是跨过 call LloRegionBuilder::ShaltInternal0x1D520D20)的 jne,因此 bit-0 已设置会跳过 shalt-region emission,而 bit-0 清除会调用 ShaltInternal。因此 bit-0 gate 的是是否为 TensorCore continuation-queue capability 发出 stall/halt region。第二个读取点是 TpuCompactionIsaEmitterCodegen::Create0x1090EB6E),它同样 guard 相同的 emission,并且紧跟在内联 TpuChipConfig::Megachip 检查之后。


SparseCore-Offload 覆盖旋钮

TpuCompilationEnvironment(TCE)中的两个编译期旋钮会覆盖 bit-2/megachip gate 建立的硬件默认值。两者都是 xla::jellyfish 命名空间中的 getter,接收一个 ObjectView<TpuCompilationEnvironment> 和一个 TpuTopology&,读取单个 TCE proto 字段,并在该字段保留为 AUTO 时回退到 generation default。因为 ObjectView byte-offset 等于 TCE _impl_ struct offset,也等于 _InternalSerialize field-write offset,所以每个 struct offset 都与恢复出的 proto field number 一一对应。

c
char ShouldEnableConcurrentSparseCoreOffloading(ObjectView<TCE> env,            // sub_1D6B6F80
                                                TpuTopology &topo, bool force_off):
    hw  = (topo.chip_parts->version == 5) & ~force_off    //  chip_parts+0 == TpuVersionProto 5 (ghostlite/v6e)
    p   = env[0x458] ?: &AutoProto_globals_               //  TCE +0x458 = field 923
    v   = AutoOr<bool>::FromProtoOrDie(p)                 //  ret = AUTO?0 : (value | 0x100)
    if ((v & 0x100) == 0) v = hw                          //  no explicit value -> hw default
    return v & 1

char EnableSparseCoreOffloadQueuingInLhs(ObjectView<TCE> env, TpuTopology &topo):  // sub_1D6B81E0
    hw  = (topo.chip_parts->version == 5)                 //  chip_parts+0 == TpuVersionProto 5 (ghostlite/v6e)
    p   = env[0x730] ?: &AutoProto_globals_               //  TCE +0x730 = field 1021
    v   = AutoOr<bool>::FromProtoOrDie(p)
    if ((v & 0x100) == 0) v = hw
    return v & 1
```text

覆盖机制是 `AutoOr<bool>::FromProtoOrDie`(`0xF795300`):它读取 `AutoProto+0x1C` 处的 `AutoProto` state word;state `0`(AUTO/unset)返回 `0`,因此 `& 0x100` 测试失败并采用硬件默认值;任何其他 state 返回 `value | 0x100`,因此 bit-8 标记“存在显式值”,bit-0 携带 bool,可在两个方向覆盖 chip-gen default。

```c
int64 AutoOr<bool>::FromProtoOrDie(AutoProto *a1):     // sub_F795300
    if (a1[0x1C/4] == 0) return 0                       //  AUTO: no presence -> 0
    val = AutoOrTypeTraits<bool>::FromAutoProto(a1)     //  (LOG(FATAL) on conversion error)
    return val | 0x100                                  //  bit-8 = present, bit-0 = value
getter (xla::jellyfish::)VATCE offsetfield #TCE field namehardware default
ShouldEnableConcurrentSparseCoreOffloading0x1D6B6F80+0x458923xla_tpu_enable_concurrent_sparse_core_offloading(proto_version==5: ghostlite/v6e) && !force_off
EnableSparseCoreOffloadQueuingInLhs0x1D6B81E0+0x7301021xla_tpu_enable_sparse_core_offload_queuing_in_lhsproto_version==5 (ghostlite/v6e)

注意 — field numbers(923、1021)来自 TpuCompilationEnvironment::_InternalSerialize0x1DB41DC0)中每个 InternalWriteMessage 调用前的 mov $field#,%edi immediate:0x1DB50028 加载 0x458 然后写 field 0x39B(923),0x1DB50DBE 加载 0x730 然后写 field 0x3FD(1021),因此 struct-offset ↔ field-number 绑定是直接的,不是推断的。version == 5 比较反汇编为针对 TpuTopology+8 -> chip_parts+0cmpl $0x5,(%rax)0x1D6B6F8C)。该字段携带 TpuVersionProto(1-based,即 proto field-1 的值,也是 chip_parts.binarypb blob 开头的值),不是 0-based 内部 TpuVersion;因此 5 解析为 ghostlite (TPU v6e)6 将是 6acc60406。0-based↔1-based 对照见 Codename 矩阵。四个 sibling SC-offload knobs 共享相同的 AutoOr<bool> 模式,每个都由同一 serializer 中的 0xNNN(%r14) load + mov $field#,%edi pair 确认:field 930(disable_sparse_core_collective_offload_remover+0x4900x3A2)、853(enable_hbm_test_buffer_for_sc_collective_offload+0x2E00x355)、857(enable_outfeed_sanity+0x2E80x359)、959(xla_shardy_options+0x5680x3BF)。


相关组件

名称关系
Target::Init (0x1D60FC20)在追加两个 continuation-queue regions 后设置 bit-0 / bit-2
Target::IsMegachip (0x10914F60)读取 bit-2;102 个内联 testb $0x4 站点就是它的函数体
TpuChipConfig::GetContinuationQueues (0x20AFCCC0)被复制到 regions 中的逐核心 queue list 的来源
AutoOr<bool>::FromProtoOrDie (0xF795300)两个 SC-offload knobs 的 override decode
TpuCompilationEnvironment::_InternalSerialize (0x1DB41DC0)将 TCE struct offsets 映射到 proto field numbers

交叉引用

  • TpuChipConfig — gate 读取其 Megachip/CoresPerChip/GetContinuationQueues 字段的 chip-config 对象
  • Codename 矩阵TpuVersion ↔ codename 映射;消除 version == 5 SC-offload default 的歧义
  • TPU Compilation Environment — TCE proto,其中 fields 923 / 1021 覆盖 bit-2 硬件默认值
  • chip_parts.binarypb Decode — proto nProto core 顺序(TENSOR_CORE=1, BARNA_CORE=2, SPARSE_CORE=3),不能与运行时 TpuCoreType enum(kSparseCore=2)混淆;也包含 version==5 → ghostlite/v6e 映射