Marketing / Cloud 命名
地址适用于
libtpu-0.0.40-cp314wheel 中的 libtpu.so(build-id89edbbe81c5b328a958fe628a9f2207d,781,691,048 B)。其他版本会有所不同。
摘要
libtpu 为同一批硅片携带了三套并行命名空间,另有第四套只存在于外部 Cloud-TPU 文档中。内部 codename(jellyfish…6acc60406)是 binary 的主 key;外部显示名称("TPU v2"…"TPU7x")是 TpuVersionToExternalName 发出的内容;Cloud-TPU accelerator-type 字符串(v2, v3, v5e, v5p, v6e, tpu7x)是面向用户的 accelerator_type API 使用的 key,也是 AcceleratorTypeToTpuVersionEnum parser 消费的内容。第四套空间 — 诸如 Trillium 和 Ironwood 的公开 marketing 名称 — 没有嵌入在 binary 的任何位置。
本页是 codename ↔ marketing/Cloud 的对照表,也是 marketing / cloud-accelerator-type 命名轴的权威来源:如果同级 Part IV 页面存在分歧,以下基于 binary 的表格优先。正向方向(codename / TpuVersion → 外部显示名称)是 TpuVersionToExternalName 中逐字的 switch,因此为 CERTAIN。Cloud-API 字符串集合是从 AcceleratorTypeToTpuVersionEnum 比较链中完整按字节追踪得到的 — 每个被接受的 literal 及其产生的整数都从反编译中恢复,而非推断。marketing-codename 绑定(Trillium = v6e/Ghostlite,Ironwood = 6acc60406)是叠加在 binary 之上的外部事实,并非来自 binary;每类这样的行都会标注。重新实现的收益是具体的:libtpu front door 的 clone 必须恰好接受这套 accelerator_type 词汇,恰好写入 parser 写入的 public-TpuType 整数,并恰好发出该 switch 返回的显示字符串 — 三个轴中任何一个出错,plugin 都可能拒绝一个有效 Cloud type,或错误地 gate 某个代际。
必须严格区分三个整数/字符串轴,因为 parser 发出的整数并不是显示 switch 消费的同一个整数:
- 内部
TpuVersion— 0-based,是TpuVersionToExternalName/TpuVersionToStringswitch 的索引:jellyfish=0,dragonfish=1,pufferfish=2,viperfish=3,ghostlite=4,6acc60406=5。 - 外部显示名称 — switch 返回的
const char*("TPU v2"…"TPU7x")。 - Public TpuType —
AcceleratorTypeToTpuVersionEnum从 Cloud accelerator-type 字符串写入的 1-based 整数(v2→1,v3→2,v4→3,v4lite→4,v5e/v5lite→5,v5p→6,v6e/v6ea→7,tpu7x/tpu7→8)。这是IsAtLeastTPU7x测试的轴,不是TpuVersion。
对重新实现而言,契约是:
TpuVersion→ external-display-nameswitch及其litevariant 逻辑。- Cloud-TPU accelerator-type 字符串词汇,以及它在何处被解析。
- 哪些名称是 binary 内部名称(可验证),哪些只是外部名称(推断)。
正向映射 (TpuVersion→display) | tpu::TpuVersionToExternalName @ 0x20b3a500 |
Cloud-API parser (string→TpuType) | libtpu::(anon)::AcceleratorTypeToTpuVersionEnum @ 0x204cf620 |
| 代际 gate | libtpu::IsAtLeastTPU7x @ 0x204cfda0(解析 type,测试 TpuType >= 8) |
| 人类可读形式 | tpu::TpuVersionAndVariantToHumanReadableName @ 0x20b3b040(与正向映射相同的分支) |
| Codename 事实来源 | TpuVersionToString @ 0x20b3a480, rel.ro table @ 0x22011bf0(索引 0..5) |
| Binary 中的 marketing 名称 | 无 — Trillium=0,Ironwood=0,Ghostfish=0 occurrences |
命名对照表
完整对照表,每个代际一行。四个轴保持分离:0-based TpuVersion 是 display-switch 索引;外部显示列是该 switch 返回的 const char*;Public TpuType 列是 Cloud-string parser 发出的整数(一个不同的轴);Cloud-API 列列出 parser 接受的精确 literal。TpuVersion、display、TpuType 和 Cloud-API 列都从两个 switch/compare body 中按字节追踪得到;只有 marketing 列在标注处为 external-only。
| TpuVersion | Codename (internal) | External display | Public TpuType | Cloud-TPU API (parser literals) | Marketing |
|---|---|---|---|---|---|
| 0 | jellyfish | "TPU v2" | 1 | v2 | TPU v2 |
| 1 | dragonfish | "TPU v3" | 2 | v3 | TPU v3 |
| 2 | pufferfish | "TPU v4" / "TPU v4 lite" | 3 / 4 | v4 / v4lite | TPU v4 |
| 3 | viperfish | "TPU v5" / "TPU v5 lite" | 6 / 5 | v5p (→6) · v5e,v5lite (→5) | TPU v5p / v5e |
| 4 | ghostlite | "TPU v6 lite" | 7 | v6e, v6ea | Trillium |
| 5 | 6acc60406 | "TPU7x" | 8 | tpu7x, tpu7 | Ironwood (external) |
易错点 — Cloud 名称
v5p属于 Viperfish (TpuVersion3),v5e也是如此:parser 将 bothv5p→TpuType 6 和v5e/v5lite→TpuType 5,并且它们共享 Viperfish 的显示名称"TPU v5"/"TPU v5 lite"(字符串"TPU v5p"@0x85c9e34)。下一代 Ghostlite (TpuVersion4) 是v6e/v6ea→TpuType 7。把v5p上滑到 Ghostlite,或把v6e下滑到 Viperfish,是最常见的命名错误;参见 Superseded-Label Correction List。规范说法是:Viperfish = v5p AND v5e;Ghostlite = v6e(= marketing "Trillium");6acc60406 = tpu7x。 没有任何 binary 字符串将6acc60406关联到v6e或 "Trillium"。
binary 毫无歧义地确定了 Viperfish/Ghostlite Cloud-name 轴。0x22011bf0 槽位表固定 viperfish = TpuVersion 3 且 ghostlite = 4;TpuVersionToExternalName (0x20b3a500) 给出 3→"TPU v5" 和 4→"TPU v6 lite";parser (0x204cf620) 接受 v5p/v5e/v5lite 进入 v5(TpuType 5/6)区间,并接受 v6e/v6ea 进入 v6 区间(TpuType 7)。因此 v5p 是 Viperfish Cloud 名称,而 v6e 是 Ghostlite Cloud 名称;二者都不属于对方。marketing 名称 "Trillium" 绑定到 Ghostlite/v6e,而不是 6acc60406 — 参见 Marketing Names Are External-Only。
正向映射 — TpuVersionToExternalName
目的
TpuVersionToExternalName 是权威的 TpuVersion → 面向用户显示字符串函数。它接受 enum 值和一个可选 variant string view,并返回一个静态 C 字符串。这是用户会在工具和错误消息中看到其输出的函数。
算法
const char* TpuVersionToExternalName(int v, view variant): // 0x20b3a500
switch (v):
case 0: return "TPU v2"
case 1: return "TPU v3"
case 2: return (variant.len==4 && variant=="lite") ? "TPU v4 lite" : "TPU v4"
case 3: return (variant.len==4 && variant=="lite") ? "TPU v5 lite" : "TPU v5"
case 4: return "TPU v6 lite" // Ghostlite — no plain "TPU v6"
case 5: return "TPU7x" // 6acc60406
default: return "Unknown TPU version"
```text
`lite` 测试将 variant view 的前四个字节与 `0x6574696C`(ASCII 字符串 `"lite"` 的 little-endian dword)比较,并要求长度为 4。只有 Pufferfish(v4)和 Viperfish(v5)以这种方式携带可选 `lite` 后缀;Ghostlite 已经无条件将自己命名为 `"TPU v6 lite"`,而 6acc60406 始终是 `"TPU7x"`。
> **怪癖 —** 没有任何代际对应 plain `"TPU v6"` 字符串。Ghostlite 是 v6-class 部件,在 case 4 中直接命名为 `"TPU v6 lite"` — `lite` 限定词被烘焙进名称,而不是由 variant 分支追加。若重新实现时预期存在 `"TPU v6"` 基础名和单独的 `lite` 后缀(v4/v5 模式),就会生成 binary 从不发出的名称。
### 证据
显示字符串,直接从 binary 读取:
```text
0x868655d "TPU v6 lite" (case 4 — Ghostlite)
0x84c7976 "TPU7x" (case 5 — 6acc60406)
0x85c9e34 "TPU v5p" (Viperfish Cloud standard name)
0x998f2b3 "TPU v5" (case 3 base)
0x9c163f0 "TPU v2" (case 0)
external display-name cluster @0x8686541:
...|TPU v6 lite|TPU v5 lite|TPU v4 lite|...
v7 cluster @0x84c7968:
TPU v7x|tpu7x|TPU7x|pwr6x|...codename ↔ TpuVersion 绑定不是推断:TpuVersionToString (0x20b3a480) 索引 .data.rel.ro 指针表 0x22011bf0(在 a1 >= 6 fatal-bounds check 之后,证明正好有六个条目),并且每个槽位都由链接时的 R_X86_64_RELATIVE 重定位物化,其 addend 指向 codename 字符串:
0x22011bf0 + 8*v -> codename string (RELA addend)
[0] 0x863f064 "jellyfish"
[1] 0x863f392 "dragonfish"
[2] 0x863f1c4 "pufferfish"
[3] 0x863f172 "viperfish" <- TPU v5 family (v5p / v5e / v5lite)
[4] 0x86864e0 "ghostlite" <- TPU v6 lite (v6e / v6ea)
[5] 0x863f0cf "6acc60406" <- TPU7x (tpu7x / tpu7)
```text
---
## Cloud-TPU Accelerator-Type Parser
### 目的
`AcceleratorTypeToTpuVersionEnum` 是反向方向:它接受用户提供的 accelerator-type 字符串(Cloud-TPU `accelerator_type`,例如 `v6e`、`v5p`、`tpu7x`),并将其解析为 **public TpuType** 整数(1-based,1..8 — *不是*内部 `TpuVersion`)。`IsAtLeastTPU7x` 包装它,以 gate TPU7x 及后续代码路径。
> **怪癖 —** parser 写入的是 **public TpuType** 轴(`v2`→1 … `tpu7x`→8),这*不是*显示 switch 消费的内部 `TpuVersion`(`jellyfish`=0 … `6acc60406`=5)。两个轴在基数(1-based vs 0-based)和粒度上都不同:单个 `TpuVersion`(例如 Viperfish=3)会展开为*两个* TpuType(`v5p`→6 和 `v5e`/`v5lite`→5)。不要把 TpuType 输入 `TpuVersionToExternalName`,也不要假设 parser 的整数会索引 `0x22011bf0` 处的 codename 表。
### 算法
```c
void AcceleratorTypeToTpuVersionEnum(out, string accel_type): // 0x204cf620
if accel_type.empty():
out = Error("Accelerator type is empty.") // libtpu_init_utils.cc:33
return
parts = split(accel_type, '-') // split on 0x2d '-'
if parts.size() != 2: // must be '<ver>-<core_count>'
out = Error("Accelerator type is not in the format ...") // :37
return
tok = AsciiStrToLower(parts[0]) // leading token, lowercased
// Fast path: a length-keyed dword/word compare on the inlined buffer.
if tok.len == 6 && tok == "v4lite": return ok(4) // 0x696C3476 + 0x6574
if tok.len == 2: // 2-byte word compares
if tok == "v2": return ok(1) // *(WORD) == 0x3276
if tok == "v3": return ok(2) // 0x3376
if tok == "v4": return ok(3) // 0x3476
// Fallthrough (any length, incl. unmatched len-2/len-6): string compares.
if tok.starts_with("v5lite") || tok == "v5e": return ok(5)
if tok == "v5p": return ok(6)
if tok == "v6e" || tok == "v6ea": return ok(7)
if tok == "tpu7x" || tok == "tpu7": return ok(8)
out = Error("Unsupported accelerator type: " + accel_type) // :67
// ok(n): out.tpu_type = n; out.ok = 1; return
bool IsAtLeastTPU7x(string accel_type): // 0x204cfda0
v = AcceleratorTypeToTpuVersionEnum(accel_type)
return v.ok() && v.tpu_type >= 8 // public TpuType axis; only tpu7x/tpu7 qualifyaccelerator-type 字符串按 - 拆分,并用前导 token 匹配接受词汇。IsAtLeastTPU7x 在 public TpuType 轴 上测试解析值 >= 8,并且在该轴上只有 tpu7x/tpu7 解析为 8(Ghostlite 的 v6e/v6ea 解析为 7)。因此该 gate 仅对 6acc60406 为 true — 它正如其名称所示,gate TPU7x-and-later 代码路径,并且对 v6e/Ghostlite 返回 false。
易错点 — 名称
IsAtLeastTPU7x是字面含义,不是 "v6-class-or-newer"。因为 parser 将v6e→7 而tpu7x→8,tpu_type >= 8测试会通过tpu7x/tpu7(6acc60406),并对v6e/v6ea(Ghostlite)失败。若重新实现者把该 wrapper 理解为 "v6e and up",就会把 Ghostlite 错误 gate 到 TPU7x 路径;阈值比函数的7x后缀乍看暗示的代际还要高一代。
函数映射
| Function | Address | Role |
|---|---|---|
TpuVersionToExternalName | 0x20b3a500 | TpuVersion → display string(显式 switch) |
AcceleratorTypeToTpuVersionEnum | 0x204cf620 | Cloud accelerator-type string → public TpuType(每个 literal 均按字节追踪) |
IsAtLeastTPU7x | 0x204cfda0 | 解析字符串,测试 public TpuType >= 8(仅 tpu7x/tpu7) |
TpuVersionAndVariantToHumanReadableName | 0x20b3b040 | TpuVersion → 人类可读名称(相同 switch 分支) |
注意 — parser 是完整按字节追踪的,不是推断。lowercase 和
-split 之后,它按长度分派前导 token:2 字节 token 与 dwords/wordsv2/v3/v4比较(*(_WORD*) == 0x3276/0x3376/0x3476→ TpuType 1/2/3),6 字节 token 与v4lite比较(0x696C3476+0x6574→ 4),其余 literal 通过starts_with/operator==链处理:starts_with("v5lite") || == "v5e"→ 5,== "v5p"→ 6,== "v6e" || == "v6ea"→ 7,== "tpu7x" || == "tpu7"→ 8。其他任何值都会在libtpu_init_utils.cc:67返回Error("Unsupported accelerator type: …")。上面的每个 literal 及其产生的 TpuType 都从0x204cf620body 中恢复 — Public TpuType 列是 CERTAIN,不是推断。
Marketing 名称仅在外部 {#marketing-names-are-external-only}
公开的 marketing codename 不在 binary 中。对整个 745 MiB image(781,691,048 B)进行大小写不敏感扫描,每个词都返回零匹配:
| Marketing token | Occurrences in libtpu.so | Status |
|---|---|---|
Trillium | 0 | 仅 marketing 名称;外部文档记载为 Ghostlite / v6e。非 binary 知识 — 不是引用事实 |
Ironwood | 0 | 仅 marketing 名称;外部文档记载为 6acc60406 / TPU7x 代际。非 binary 知识 — 不是引用事实 |
Ghostfish | 0 | 通过 ghostlite→glc 类推为 gfc 发明的 gloss;不是 binary 事实,也不是真实产品名 |
注意 —
TpuVersion5(gfcsub-core / external"TPU7x"代际)的唯一规范内部名称是混淆标签6acc60406。gloss "Ghostfish" — 由类推(ghostlite→glc,所以ghostfish→gfc)提出 — 在 binary 中无处出现(ghostfish/Ghostfish= 0 occurrences),不得作为已确认 codename 呈现。6acc60406背后的 marketing 名称(外部为 "Ironwood")没有嵌入,不能从 libtpu.so 取证。怪癖 — "Trillium" 是
v6e代际的已记录外部名称,但只读 binary 的重新实现者永远看不到它。应将 Ghostlite 绑定到"TPU v6 lite"/v6e(二者都在 image 中),并把Trillium视为注释,而不是 lookup key。对6acc60406的任何公开名称(外部为 "Ironwood")也是如此:binary 只知道它是6acc60406/"TPU7x"/tpu7x。这两个 marketing 名称都是从外部 Cloud-TPU 文档叠加到 binary 上的,绝不是从中读出的。
交叉引用
- Codename 矩阵 —
TpuVersionenum ↔ codename 事实来源表 - PCI Device IDs — 锚定每个代际的 chip-DID → codename 映射
- Superseded-Label Correction List —
v5p-vs-v6e和 Ghostfish 修正在细节上的说明 - HAL Families — 按 codename 划分的 JXC/PXC/VXC factory routing