代号速查表
本页所有地址均适用于
libtpu-0.0.40-cp314wheel 中的libtpu.so(build-id89edbbe81c5b328a958fe628a9f2207d— 明确锚点;运行时报告的0.103无法在二进制中静态验证)。该二进制未剥离符号 — 每个符号都是反混淆后的 C++ 名称;.text、.rodata和.lrodata满足 VMA == file offset。其他构建会不同。
摘要
同一代 TPU 在 libtpu.so 内至少披着七种不同名称,而且它们分布在三条独立的整数轴上,彼此不共享编号。读者追查一个事实时 — “gfc 是哪颗芯片?”,“DeviceType 12 表示什么?”,“TpuVersion 4 是 Trillium 还是 v7x?” — 总会撞到不同于手头概念的另一条轴,而这些轴之间的差一偏移正是先前分析出错的地方。本页就是要反复回看的那张卡片:它把每一代的每个名称都钉到定义它的二进制位置上,并排展示,这样 wiki 的其余部分可以直接指向这里,而不必重新推导映射。
三条轴分别是内部 tpu::TpuVersion enum(紧凑的 0..5,编译器对“哪种硅”的概念,由 TpuVersionToString @ 0x20b3a480 定义);profiler 的 xprof::DeviceType enum(稀疏的 1..13,trace 管线对“哪种设备”的概念,由 DeviceTypeFromDeviceIdentifiers @ 0xf6993a0 和 DeviceTypeString @ 0xf69c7c0 定义);以及 protobuf TpuVersionProto(1..6 的 wire enum,internal = proto − 1,TpuVersionFromProto @ 0x20b3a8c0)。与这三条轴都正交的是 codec/ISA 代号(jxc、pxc/plc、vfc/vlc、glc、gfc)、鱼类营销代号(Jellyfish … Trillium)、PCI device-id,以及公开的 Cloud-API 字符串(v2…tpu7x)。下面每个由二进制锚定的单元格都带有证据地址;如果某个名称不在二进制中(Trillium、Ironwood、“Ghostfish”),本页会明确说明,而不是编造。
导航约定如下:
- 主表在同一行中绑定每一代的每条轴,每个单元格都带有自己的置信度 — 这是 wiki 其余部分链接到的规范查表。
- 双轴警告解释
TpuVersion和DeviceType的数值为什么不一致,避免重新实现者用一张表的 ordinal 去索引另一张表。 - 陷阱汇总容易踩坑之处:两个差一的 SparseCore sequencer enum、嵌套 codec namespace(
pxc::plc、vxc::vlc、gxc::gfc),以及 v7x6acc60406/gfc随附 SparseCore SCS+TEC 但不随附 TAC。
| 内部 enum | tpu::TpuVersion 0..5 — TpuVersionToString @ 0x20b3a480,表 off_22011BF0(6 ptrs) |
| Profiler enum | xprof::DeviceType 1..13(稀疏)— DeviceTypeFromDeviceIdentifiers @ 0xf6993a0,名称 off_21772F00 |
| Proto enum | TpuVersionProto 1..6 — TpuVersionFromProto @ 0x20b3a8c0(internal = proto − 1) |
| Codec factory | tpu::TpuCodec::Create(TpuVersion) @ 0x1e835fa0(6-case switch,顺序 = TpuVersion) |
| Trace codec | xprof::tpu::GetTraceCodec @ 0xf5a2900(按 PCI identity 取键,而不是按任一 ordinal) |
| PCI vendor | 每个 TPU 设备均为 0x1ae0(Google) |
主速查表
每代一行,按 TpuVersion 顺序排列。从左到右读取,即可把任意一个名称翻译成所有其他名称。Confidence 列适用于整行中由二进制锚定的单元格;营销列单独标注,因为它是唯一并非源自二进制的列。
| Codec 代号 | 鱼类代号 | TpuVersion(内部) | DeviceType(profiler) | 营销显示名 | PCI chip DID | HAL family |
|---|---|---|---|---|---|---|
jxc (jellyfish) | Jellyfish | 0 | 3 | TPU v2 | 0x004e | TpuHalJxc |
jxc (dragonfish) | Dragonfish | 1 | 5 | TPU v3 | 0x004f | TpuHalJxc |
pxc / pfc | Pufferfish | 2 | 7 | TPU v4 (v4 lite) | 0x0050/51/52 | TpuHalPxc |
pxc / plc | Puffylite | — (没有自己的 TpuVersion) | 8 | (v4-class lite) | (chip-parts 变体) | TpuHalPxc |
vxc / vfc | Viperfish | 3 | 10 | TPU v5 (v5 lite) | 0x00ac/0x00ad | TpuHalVxc |
vxc / vlc | Viperlite | — (折叠进 v3) | 11 | (v5-class lite) | 0x00ae/0x00af | TpuHalVxc |
gxc / glc | Ghostlite | 4 | 13 | TPU v6 lite | 0x00d1 | TpuHalVxc |
gxc / gfc | (无 — 6acc60406) | 5 | 12 | TPU7x | 0x00f2 | TpuHalVxc |
NOTE —
TpuVersion→代号绑定是二进制中锚定最牢的事实。TpuVersionToString(0x20b3a480)索引off_22011BF0处的 6 指针.data.rel.ro表,其R_X86_64_RELATIVErelocation 指向字面量jellyfish(0x863f064)、dragonfish(0x863f392)、pufferfish(0x863f1c4)、viperfish(0x863f172)、ghostlite(0x86864e0)、6acc60406(0x863f0cf)。这个编译出的数组是其他每条轴挂靠的根。
营销 / Cloud-API 列(单独置信度)
鱼类和 codec 代号是烘进符号和 .rodata 的内部名称。面向客户的 Cloud-TPU 名称是一组并行字符串,通过 TpuVersionToExternalName(0x20b3a500)和 AcceleratorType… parser(0x204cf620 / 0x20b3a740)到达。公开的产品代号在外部叠加,并且并非全部在二进制中:
TpuVersion | Fish | TpuVersionToExternalName string | Cloud-API string(s) | 公开营销名 | 营销置信度 |
|---|---|---|---|---|---|
| 0 | Jellyfish | TPU v2 | v2 | TPU v2 | HIGH(字符串在二进制中) |
| 1 | Dragonfish | TPU v3 | v3 | TPU v3 | HIGH(字符串在二进制中) |
| 2 | Pufferfish | TPU v4 / TPU v4 lite | v4, v4lite | TPU v4 | HIGH(字符串在二进制中) |
| 3 | Viperfish | TPU v5 / TPU v5 lite | v5, v5e, v5p | TPU v5p / v5e | HIGH(字符串在二进制中) |
| 4 | Ghostlite | TPU v6 lite | v6e | Trillium | LOW — “Trillium” 不在二进制中 |
| 5 | 6acc60406 | TPU7x | tpu7x, tpu7 | Ironwood | LOW — “Ironwood” 不在二进制中(外部名称) |
GOTCHA — 字符串
Trillium在libtpu.so中出现次数为零;Ironwood也是;Ghostfish也是。Trillium = Cloudv6e=Ghostlite/glc/TpuVersion4,Ironwood = Cloudtpu7x=6acc60406/gfc/TpuVersion5,二者都是外部事实(Cloud-TPU 文档),正确但无法从二进制取证。最新一代唯一的内部名称是混淆标签6acc60406;其gxc::gfc目录缩写看起来可能代表某种 “Ghostfish” 风格的鱼类名称,但该名称不存在 — 不要断言它。引用6acc60406(或显示字符串TPU7x)作为TpuVersion5 的规范内部名称,并把 Ironwood 当作仅存在于外部的营销标签。
两条轴,两套编号 — 为什么 TpuVersion ≠ DeviceType
最常见的错误是用另一张表的 ordinal 来索引这张表。TpuVersion 4 是 Ghostlite;DeviceType 4 不是本表中的任何一代。它们是由不同子系统维护的不同 enum,从未打算对齐。
TpuVersion — 紧凑的编译器轴(0..5)
tpu::TpuVersion 是编译器 / codec / HAL 轴。它是连续的 0..5,编译器为每个硅家族发射代码,对应一个值。TpuVersionToString 将其限制在 < 6;TpuCodec::Create(0x1e835fa0)是干净的 6-case switch(case 0→Jellyfish … case 5→ 通过 sub_1E838380 到达匿名 gfc codec);TpuVersionFromProto 将 proto 1..6 映射为 internal = proto − 1。Lite 变体(Puffylite、Viperlite)没有自己的 TpuVersion — 它们通过嵌入的 TpuChipParts proto 在父家族的 HAL 内复用,因此这条轴正好有六个值。
DeviceType — 稀疏的 profiler 轴(1..13)
xprof::DeviceType 是 profiler / trace 轴。DeviceTypeFromDeviceIdentifiers(0xf6993a0)读取捕获设备的 12 字节 PCI DeviceIdentifiers 元组,并直接分配一个 DeviceType ordinal — 而这个 ordinal 集合是稀疏的:八个真实 TPU 硅代落在 ordinal {3, 5, 7, 8, 10, 11, 12, 13} 上,跳过 1, 2, 4, 6, 9。被跳过的值不是空洞:在 13 项名称表 off_21772F00 中,ordinal 1 是 "GPU",ordinal 2, 4, 6, 9 都读出通用的 "Cloud TPU" 占位字符串,因此 TPU 硅槽位与一个 GPU 槽位和若干未分配/回退槽位交错。DeviceTypeString(0xf69c7c0)计算 index = ordinal − 1 并索引该表,边界为 ordinal − 1 > 0xC(即 ordinal 1..13);超范围返回 "Cloud TPU"。ordinal 存储是 DeviceTypeFromDeviceIdentifiers 每个分支中的字面量 mov:
// xprof::tpu::DeviceTypeFromDeviceIdentifiers(DeviceIdentifiers) // 0xf6993a0
// each branch matches the PCI tuple against a kXxxChipIdentifiers constant,
// then stores the DeviceType ordinal at result+8 (decompiler: result[2]):
if matches kJellyfishIdentifiers: DeviceType = 3
else if matches kDragonfishIdentifiers: DeviceType = 5
else if matches kPuffyliteChipIdentifiers: DeviceType = 8 // pxc::plc — its own ordinal
else if matches kPufferfishChipB0{Mfg,Water,Air}Identifiers:
DeviceType = 7 // pxc::pfc
else if matches kViperliteChip{A0,A1}{PF,VF}Identifiers:
DeviceType = 11 // vxc::vlc
else if matches kViperfishChip{PF,VF}Identifiers:
DeviceType = 10 // vxc::vfc
else if IsGlc(ids): DeviceType = 13 // gxc::glc, Ghostlite / v6e
else if IsGfc(ids): DeviceType = 12 // gxc::gfc, 6acc60406 / v7x
else: error("Unsupported device identifiers") // device_identifiers_utils.cc:152
```text
> **QUIRK —** 在 `DeviceType` 轴上,最新两代相对于时间顺序是**数值倒置**的:Ghostlite(较旧,v6e)是 `13`,而 `6acc60406`(较新,v7x)是 `12`。名称表本身直接确认了这一点 — `off_21772F00` slot 11(ordinal 12)是 `"TPU v7x"`,slot 12(ordinal 13)是 `"TPU v6 Lite"`。这是会绊倒每位分析者的单一事实 — `DeviceType` 12 < 13 **不**意味着 v7x 比 v6e 更旧。profiler 的 perf-counter 层精确地以 `DeviceType == 12` 做 gate,因为 v7x 是此构建中唯一暴露具名片上计数器的一代(见 [v7x Perf-Counters](../profiling/v7x-perf-counters.md));如果重新实现者按 `== 13` gate 并期待“最新芯片”,就会让整个 v7x counter 管线静默失效。
>
> **GOTCHA —** `Puffylite`(`pxc::plc`)和 `Viperlite`(`vxc::vlc`)作为**一等 `DeviceType` ordinal** 存在(8 和 11),但它们**没有自己的 `TpuVersion`** — 它们分别折叠进 Pufferfish(`TpuVersion` 2)和 Viperfish(`TpuVersion` 3)。所以 `DeviceType → TpuVersion` 是多对一。把捕获到的 `DeviceType` 翻译成编译器 `TpuVersion` 时,必须折叠 `8→2` 和 `11→3`;反向翻译会丢失 lite/non-lite 区分(该区分从 `TpuChipParts` 变体恢复,而不是从 `TpuVersion` 恢复)。
### proto 轴(`1..6`)和公开 `TpuType`
第三个 enum `TpuVersionProto` 是 protobuf wire 形式:`TPU_V2=1` … `TPU_V6_LITE=5`,`TPU_V7X=6`。`TpuVersionFromProto`(`0x20b3a8c0`)是字面量 `internal = proto − 1` 翻译;这解释了为什么嵌入的 `6acc60406_chip_parts.binarypb` blob 对内部 `TpuVersion` 为 `5` 的芯片携带 `version = 6`(proto)。第四个更粗粒度的公开 enum — `superpod::routing::TpuType`(`GetTpuType` @ `0x1ff94340`)— 又把 lite/standard 区分展开回来(`type=2`…`type=10`)。四个 enum 都可以通过上方主表完全调和;见 [Dual-Enum: Proto vs Internal](../targets/dual-enum-proto-vs-internal.md)。
---
## 陷阱与 Namespace 嵌套
### Codec namespace 嵌套 — family vs sub-core
codec/ISA namespace 是**两层深**:先是 family tag,再是 sub-core — 对于拆分家族(`pxc`、`vxc`、`gxc`),该 sub-core 是 fetch/load 对;`jxc` 是融合的,改为嵌套 engine block。只搜索 family tag(`pxc`、`vxc`、`gxc`)有一半时候会落到错误的 sub-namespace。位于 `asic_sw::driver::deepsea::` 下的嵌套如下:
| Family | Sub-cores(嵌套 namespace) | 服务对象 |
|---|---|---|
| `jxc` | `jxc::jfc`(Jellyfish core)、`jxc::dfc`(dataflow)、`jxc::registers`、`jxc::snap` | Jellyfish、Dragonfish(融合,无 fetch/load 拆分) |
| `pxc` | `pxc::pfc`(fetch)、`pxc::plc`(load) | Pufferfish、Puffylite |
| `vxc` | `vxc::vfc`(fetch)、`vxc::vlc`(load) | Viperfish、Viperlite |
| `gxc` | `gxc::glc`(load)、`gxc::gfc`(fetch) | Ghostlite(`glc`)、`6acc60406`(`gfc`) |
> **GOTCHA —** `jxc::jellyfish`、`jxc::dragonfish`、`jxc::bcs` 和 `jxc::brn` **不是** namespace。`jxc` 下唯一真实的嵌套 namespace 是 engine block(`jfc`、`dfc`、`registers`、`snap`);`bcs`/`brn` token 是 `*_trace_entry` 类型名中的前缀(`bcs_internal_trace_entry`、`brn_perf1_trace_entry`),而 `jellyfish`/`dragonfish` 只作为 `*_performance_counters` 标识符出现。JXC 的编译器侧 ISA 位于 `platforms_deepsea::jellyfish::isa`,不在任何 `jxc::isa` 中。见 [Sub-Core Taxonomy](../targets/sub-core-taxonomy.md)。
>
> **QUIRK —** `gxc` family 将其 HAL 注册进**共享的 `TpuHalVxcHardwareFactory`**(vtable `0x21cabf70`),也就是 Viperfish 使用的同一个 factory class — 不存在 `TpuHalGxc` factory。三个内部代号(Viperfish、Ghostlite、`6acc60406`)共享一个 factory class 和一个 vtable,只通过 `+8` 处存储的 `TpuVersion` 区分。每代 HAL 注册由 `google_init_module_tpu_hal_{vxc,glc,gfc}_hardware_impl` 注入;*codec* namespace 中的 family tag(`gxc`)和 HAL *factory* class(`Vxc`)是刻意不同的 — 不要期待它们匹配。
>
> **NOTE —** 只有 `TpuVersion` 4(`glc`)随附一个**具名** codec class:`tpu::TpuCodecGhostlite`(`_ZTV` @ `0x21d35c00`)。`TpuVersion` 5(`gfc`)随附一个**匿名** codec(vtable `0x21d35898`,由 `sub_1E838380` 构造,作为 `TpuCodec::Create` 的 `case 5` 到达);不存在 `TpuCodec6acc60406` 符号。codec 的 `Encode` guard 独立地再次证明 proto 轴:`glc` codec 在 `+0x58` 检查 `proto_tag == 5`,`gfc` codec 检查 `proto_tag == 6`。
### 两个差一的 SparseCore sequencer enum
`TpuSequencerType`(bundle 目标 sub-core)有**两套相差一的编号**,混用会静默地为错误 engine 编码。codec template 在内部值 `{3, 4, 5}` 上实例化 SCS/TAC/TEC;proto/runtime 形式高一位,为 `{4, 5, 6}`:
| Sequencer | Codec-template(内部) | Proto / runtime |
|---|---|---|
| TensorCore (TC) | 0 | 1 |
| BarnaCore (BCS) | 1 | 2 |
| *(reserved)* | 2 | 3 |
| SparseCore Scalar (SCS) | **3** | **4** |
| SparseCore Tile-Access (TAC) | **4** | **5** |
| SparseCore Tile-Execute (TEC) | **5** | **6** |
`TpuSequencerTypeFromProto`(`0x20b36300`)是连接二者的字面量 `internal = proto − 1` switch;SCS codec 在 `(TpuSequencerType)3` 实例化,TAC codec 在 `(TpuSequencerType)4` 实例化。每代完整 op roster 见 [Sequencer Ops Per Gen](../isa/sequencer-ops-per-gen.md)。
> **GOTCHA — 6acc60406(v7x)只随附 SCS + TEC,没有 TAC。** 符号表中存在 `gxc::gfc::isa::SparseCoreScs{Bundle,CodecBase,Program}` 和 `gfc::isa::SparseCoreTec{Bundle,Program}`;`gfc::isa::SparseCoreTac{Bundle,CodecBase,Program}` **缺失**。Viperfish(`vfc`)和 Ghostlite(`glc`)携带全部三个 SparseCore sequencer;`6acc60406`/`gfc`(v7x)去掉了 tile-access engine。若重新实现假设 SparseCore 三件套在带 SparseCore 的各代(Viperfish 往后)中一致,就会为 v7x 发射一个硬件没有对应 sequencer 的 TAC codec。
### Trace-codec 选择按 PCI identity 取键,而不是按任一 ordinal
`GetTraceCodec`(`0xf5a2900`)**不**接受 `TpuVersion` 或 `DeviceType`。它用 `Is{Jfc,Dfc,Pfc,Plc,Vfc,Vlc,Glc,Gfc}` predicate 重新分类原始 `DeviceIdentifiers` 元组,并选择六个 `std::variant` codec alternative 之一。variant index 是**第四个独立的**小 enum(反编译的 `__assign<N>` 调用中 jxc=6、glc=1、gfc=2、vlc=3、vfc=4、pxc=5),与其他三条轴都不匹配。接线 profiler 时,应从 PCI 元组经由这些 predicate 驱动 codec 选择 — 不要使用你在别处计算出的 `DeviceType` 或 `TpuVersion`。所选 codec 后续如何封装 record,见 [Riegeli Trace Container](../profiling/riegeli-trace-container.md)。
---
## 交叉引用
- [TpuVersion 代号矩阵](../targets/tpu-version-codename-matrix.md) — 拥有 `TpuVersion`→代号推导及其十八个交叉验证位置的深入页面
- [PCI Device IDs](../targets/pci-device-ids.md) — 完整 `DeviceIdentifiers` 表、header DID、rev-mask,以及 `IsGlc`/`IsGfc` chip-DID 比较
- [Dual-Enum: Proto vs Internal](../targets/dual-enum-proto-vs-internal.md) — `TpuVersionProto` `1..6` vs 内部 `TpuVersion` `0..5`,`proto − 1` 调和
- [Marketing / Cloud Naming](../targets/marketing-cloud-naming.md) — 外部 `TPU vN`、Cloud-API 字符串,以及 Trillium/Ironwood “not in binary” 说明
- [代号废弃标签](../targets/codename-superseded-labels.md) — 需要避免的 `Ghostlite=v5p` / `Trillium=6acc60406` / “Ghostfish” 误标,以及推翻每项误标的二进制位置
- [GXC Family](../targets/gxc-family.md) · [VXC Family](../targets/vxc-family.md) · [PXC Family](../targets/pxc-family.md) · [JXC Family](../targets/jxc-family.md) — 每个 family 的 codec、ISA 和 HAL 细节
- [Sub-Core Taxonomy](../targets/sub-core-taxonomy.md) — `fetch`/`load` sub-core 拆分以及 `xc`/`fc`/`lc` 命名模式
- [HAL Families](../targets/hal-families.md) — 三个 `TpuHal{Jxc,Pxc,Vxc}HardwareFactory` class 以及各自注册哪些 `TpuVersion`
- [Per-DeviceType Profiler Struct](../profiling/per-devicetype-struct.md) — 按稀疏 `DeviceType` ordinal 索引的 `kDeviceTypeInfo` 数组
- [v7x Perf-Counters](../profiling/v7x-perf-counters.md) — `DeviceType == 12` gate,以及为什么 v7x 是唯一的 counter-naming generation
- [Sequencer Ops Per Gen](../isa/sequencer-ops-per-gen.md) — `(TpuVersion, TpuSequencerType)` op roster 以及 v7x `6acc60406` TAC 移除
- [Riegeli Trace Container](../profiling/riegeli-trace-container.md) — 按 PCI identity 选择的 trace codec 如何封装 record
- [Per-Gen Function Dispatcher](../forensics/per-gen-function-dispatcher.md) — 二进制中跨代码库的按 `TpuVersion` 分派模式