Skip to content

CompressedToroidalRouteCache::Decompress — Proto 到 Map 的展开

本页所有地址适用于 libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64 wheel 中的 libtpu.so(build libtpu_lts_20260413_b_RC00,build-id 89edbbe81c5b328a958fe628a9f2207d)。该二进制带完整 C++ 符号(.text VMA == 文件偏移,base 0xe63c000);下文每个地址都是 VMA。已反混淆名称和字段偏移已与 IDA 反编译结果交叉核对。其他版本会不同。

摘要

Decompress预计算 route-cache 加载路径的第一阶段:它接收一个 proto::CompressedToroidalRouteCache,也就是 tsl::ReadBinaryProtoembed://…/<shape>.binarypb.compressed 烘焙资源读出的 Brotli 压缩包装器,并产生内部的 proto::ToroidalRouteCache 消息。它是一个很薄的 riegeli 解码流程:验证 format == 2,将 data 字段(一个 absl::Cord)包进 riegeli::BrotliReader,再把解压后的字节 ParseMessage 成内部 proto。解压出的 proto 还不是 内存中的查找结构;它是按每个 (src,dst) 列出的 RouteScheme 记录列表。

本页随后记录将该 proto 转成内存中 (src,dst) → path map 的两个阶段。ToroidalRouteCache 构造函数@0x20b5d8e0)会根据 第一个 RouteSchemeroute oneof case 设置对象的内存 布局判别量 [obj+0],也就是 distance vs static-path vs bit-encoded vs random-hop;该值决定四个 FlatHashMap 槽中的哪一个保存每个 pair 的值。CacheRead@0x20b5da20)是 逐条目展开循环:它从去重 orientation vector 构建 TopologyRotationHelper,然后对每个 RouteScheme(src_chip_id, dest_chip_id) 旋转进此 topology 的芯片 id 空间,按布局判别量解码路径主体,并把 (rotated_src, rotated_dst) → value pair 插入匹配的 map。

CacheRead 消费的去重 orientation vector 由 route-cache-dedup.md 产生;type-2(bit_encoded_path)variant 的 bit-stream 主体由 DecodePathFromBits 解包,记录在 route-cache-codec.md;容器对象、它在 topology 中的嵌入,以及运行时读侧分派位于 toroidal-route-cache.md。本文负责 Decompress 函数体ToroidalRouteCacheType proto enum文件 选择器,区别于布局判别量),以及 CacheRead 展开循环

重新实现时,契约为:

  • Decompressformat == 2 gate、absl::Cordriegeli::BrotliReader 设置,以及 ParseMessageproto::ToroidalRouteCache
  • 两个判别量proto::ToroidalRouteCacheType(密集 [0,4] 文件/代号 enum,选择要加载哪个烘焙 blob)与内存中的 [obj+0] 布局 int {0,1,2,3}(scheme 携带哪个 oneof,进而决定哪个 map)。
  • 展开循环 — 对每个 RouteScheme:对两个芯片 id 做 RotateId,按 layout type 解码路径(RotateCoordinates / 每跳 RotateOrientation / DecodePathFromBits),find_or_prepare_insert 进对应类型的 map,并拒绝重复 (src,dst) key。
Decompressslice_builder::Decompress(const proto::CompressedToroidalRouteCache&) @ 0x20b63320
构造函数(设置 [obj+0]ToroidalRouteCache::ToroidalRouteCache(const proto::ToroidalRouteCache&, const vector<proto::Orientation>&) @ 0x20b5d8e0
展开循环ToroidalRouteCache::CacheRead(const proto::ToroidalRouteCache&, const vector<proto::Orientation>&) @ 0x20b5da20
文件选择 enumproto::ToroidalRouteCacheType,密集区间 [0,4],descriptor @0x20c06b00
Brotli reader vtableoff_22015FE0riegeli::BrotliReader)位于 off_22015E78riegeli::CordReader)之上
Parse 入口riegeli::parse_message_internal::ParseMessageImpl @ 0x20be5d60
路径编解码器(type 2)DecodePathFromBits @ 0x20b5c5a0route-cache-codec.md
源文件platforms/accel_ssw/deepsea/slice_builder/internal/compressed_toroidal_route_cache.cc…/toroidal_route_cache.cc

Decompress 函数体、[obj+0] 判别量算术、四个 CacheRead map 分支及其 find_or_prepare_insert policy 类型,以及 ToroidalRouteCacheType enum 名称,置信度为 已确认(字节锚定),均已与 IDA 反编译和 .rodata 字符串交叉核对。唯一 LOW 置信度项已在文内标注(random_first_hop 的 proto wire-tag)。


Decompress 在加载路径中的位置

DecompressToroidalRouteCache::Create@0x20b5d6e0)的一步,该调用会物化一个预计算缓存。调用链如下:

text
ToroidalRouteCache::Create (0x20b5d6e0)
  ├─ GetRouteCacheData (0x20b5c420)
  │    ├─ GetRouteCacheDataPath (0x20bf2080)      ── "embed://<lower(Type)>_data/<shape>.binarypb.compressed"
  │    ├─ tsl::ReadBinaryProto (0x20d02060)        ── read CompressedToroidalRouteCache off the baked resource
  │    └─ Decompress (0x20b63320)                  ── *** THIS PAGE: Brotli → proto::ToroidalRouteCache ***
  ├─ ToroidalRouteCache::ctor (0x20b5d8e0)         ── set [obj+0] = layout type from 1st RouteScheme oneof
  │    └─ CacheRead (0x20b5da20)                   ── *** THIS PAGE: proto → 4 FlatHashMaps, rotated ***
  └─ move the 4 maps into the StatusOr<ToroidalRouteCache> result
```text

`GetRouteCacheDataPath` 是两个 type 判别量中的 **第一个** 被消费的位置:它将 `ToroidalRouteCacheType` enum 名称转小写,并用 `StrFormat` 写入资源路径。`Decompress`/`CacheRead` 则展开内部 proto。容器及其 `Create` 编排详见 [`toroidal-route-cache.md`](toroidal-route-cache.md);本文从 `Decompress` 边界开始。

---

## Decompress @0x20b63320 — Brotli,不是 zstd

`Decompress` 消费一个 `proto::CompressedToroidalRouteCache`,其 schema 只有两个字段:

| field | tag | type | 内存偏移 | 作用 |
|-------|-----|------|------------------|------|
| `format` | 1 | `int32` | `[proto+0x28]` | 压缩判别量;**必须是 `2`** |
| `data` | 15 | `bytes`(`absl::Cord`) | `[proto+0x18]` | Brotli 压缩的 `ToroidalRouteCache` 字节 |

解码是固定的 riegeli pipeline。位于 `[proto+0x28]` 的 `format` 字段会按 dword 读取并与 `2` 比较;任何其他值都会短路为错误。

```c
// 0x20b63320 — Decompress(this <- StatusOr storage, const CompressedToroidalRouteCache* cc)
StatusOr<proto::ToroidalRouteCache> Decompress(const CompressedToroidalRouteCache* cc) {
    if (*((int32_t*)cc + 10) != 2)                          // [cc+0x28] == format; line 0x20b63335
        return MakeError(InvalidArgument,                   // status code 13
                         StrFormat("Unsupported format: %d", cc->format));

    // cc->data is an absl::Cord at [cc+0x18]; ref-bump it into a local Cord (v26/v27),
    // then construct a BrotliReader<CordReader<Cord>> on the heap (operator new(0x158)).
    void*  reader = operator new(0x158);
    *(void**)reader          = &off_22015FE0;               // riegeli::BrotliReader vtable
    *(void**)(reader + 112)  = &off_22015E78;               // riegeli::CordReader  vtable
    // copy the borrowed Cord into the reader's owned slot [reader+0x148]
    riegeli::CordReaderBase::Initialize(reader + 112, /*Cord*/ reader + 328);   // 0x1db11ec0
    riegeli::BrotliReaderBase::Initialize(reader, /*src=*/ reader + 112);       // 0x20b64ee0

    proto::ToroidalRouteCache out;                          // ctor(&out, 0)
    // default_recursion_limit_ packed into the high word; v16 = vtable[+0x60](reader, 1)
    int64_t st = riegeli::parse_message_internal::ParseMessageImpl(reader, &out, ...);  // 0x20be5d60
    if (st == 1) reader->vtable[+0x58]();                   // VerifyEndAndClose on success
    if (!riegeli::Object::Close(reader)) { ... fold reader status into st ... }
    reader->vtable[+0x8]();                                 // ~reader / dtor

    if (st != 1)                                            // parse failed
        return CreateStatusAndConditionallyLog(             // tagged compressed_toroidal_route_cache.cc:52
                   StatusBuilder::InitRepImpl(st));
    return out;                                             // move/CopyFrom into the StatusOr payload
}

所有关键事实都由字节锚定:

  • format == 2 是唯一可接受值。 比较位于 0x20b63335;失败路径运行 FormatPack("Unsupported format: %d", 22)MakeErrorImpl<13>InvalidArgument),标记为 compressed_toroidal_route_cache.cc:40。不存在 case 1/zstd 分支;磁盘上的 .compressed 资源始终是 Brotli 流。
  • reader 是叠在 riegeli::CordReader 上的 riegeli::BrotliReader 两个 vtable 分别写入对象偏移 +0off_22015FE0)和 +112off_22015E78);CordReaderBase::Initialize@0x1db11ec0)和 BrotliReaderBase::Initialize@0x20b64ee0)连接该链。data Cord 通过 _InterlockedAdd(refcount, 2) 增加引用后借用,并复制进 reader 自有的 Cord 槽 [reader+0x148]
  • 内部消息由 riegeli 的 ParseMessageImpl 解析@0x20be5d60),并使用标准的 proto2::io::CodedInputStream::default_recursion_limit_。成功时(st == 1),解析出的 proto::ToroidalRouteCacheCopyFrom/InternalSwapStatusOr payload(尾部选择 Copy 还是 Swap 取决于两个 arena 是否匹配,0x20c040a0/…e0)。
  • 失败是结构化的,而非 fatal。 parse 或 reader 错误会返回非 OK Status(标记为 compressed_toroidal_route_cache.cc:52);调用方(GetRouteCacheData)会传播它。(对比下方 构造函数,它会在 malformed proto 上 CHECK 失败;这两个阶段的失败纪律不同。)

注意 — riegeli format 字节 vs 磁盘 magic。 format == 2CompressedToroidalRouteCache.format proto 字段,不是 Brotli/riegeli 流 magic byte。它是生产端契约:烘焙 .binarypb.compressed 资源的一方写入 format = 2 和 Brotli data blob。未来的格式 1/3 在添加解码分支前都会落入 Unsupported format 错误。


两个 type 判别量(不要混淆)

该子系统中有两个不同整数都会被读作 “type”。它们位于不同位置,并驱动不同决策。

1. proto::ToroidalRouteCacheType — 文件/代号选择器

一个密集 protobuf enum,区间 [0,4],descriptor @0x20c06b00(表 @0x224ab9c0)。五个取值名称原样存在于 .rodata

valueenum name作用
0CACHE_UNKNOWN_TYPE哨兵 / 未设置
1CACHE_TWISTED_TORUS非 resilient slice-builder twisted torus
2CACHE_ICI_RESILIENCY_PUFFERFISHresilient — pufferfish silicon generation
3CACHE_ICI_RESILIENCY_VIPERFISHresilient — viperfish silicon generation
4CACHE_ICI_RESILIENCY_6acc60406resilient — 6acc60406 silicon generation

该 enum 是 GetRouteCacheDataPath@0x20bf2080)的输入,不是 CacheRead 的输入。反编译显示,密集 enum lookup NameOfDenseEnum<&ToroidalRouteCacheType_descriptor, 0, 4>type <= 4 限制,随后 AsciiStrToLower,再 FormatPack 到资源模板:

text
"embed://%s_data/%s.binarypb.compressed"          (the path template; AsciiStrToLower @0x20bf2080)
   │            │
   │            └─ StrCat( JoinAlgorithm(dims, "x"), is_twisted ? "_twisted" : "",
   │                       orientation ? "_" + NameOfDenseEnum<Orientation,0,6>(orient) : "" )
   └─ lower(NameOfDenseEnum<ToroidalRouteCacheType,0,4>(type))   e.g. "cache_twisted_torus"

  ⇒ "embed://cache_twisted_torus_data/12x12x24_twisted.binarypb.compressed"
```text

因此 `ToroidalRouteCacheType` 选择 **加载哪个烘焙 blob**,即每个代号 family 一个。代号选择(以及选择哪个 dedup singleton 和哪个 enum 值)在上游 `InitRouteSolution` 中完成;见 [`route-cache-dedup.md`](route-cache-dedup.md)。用于可选路径后缀的 `Orientation` enum 自身也是密集 `[0,6]` enum(`{UNKNOWN=0, X=1, Y=2, Z=3, A=4, B=5, C=6}`)。

### 2. `[obj+0]` — 内存布局判别量

位于 `ToroidalRouteCache` 对象头部的普通 `int`,取值 `{0,1,2,3}`,由构造函数从 *第一个* `RouteScheme` 的 `route` oneof case 设置。它选择 **四个 `FlatHashMap` 槽中的哪一个** 保存每个 pair 的值。它独立于 `ToroidalRouteCacheType`:一个 `CACHE_TWISTED_TORUS` blob 和一个 `CACHE_ICI_RESILIENCY_VIPERFISH` blob 都可以携带 `bit_encoded_path` scheme,并且二者都得到 `[obj+0]==2`。

> **注意。** 还存在 *第三个* 无关的 “type” int,即 topology 对象上的 twist-shape 判别量 `[topo+0xe8]` `{1,2,3}`(`k·k·2k` / `k·2k·2k` / `k·2k·nk`)。它随 twisted-torus 几何记录,不在本文被消费。

---

## 构造函数 @0x20b5d8e0 — 设置 `[obj+0]`

构造函数将四个 map 槽(`[obj+0x8]`、`[obj+0x28]`、`[obj+0x48]`、`[obj+0x68]`)清零初始化,计算 `[obj+0]`,然后调用 `CacheRead`。布局 int **只由第一个 scheme 的 oneof tag 派生**,但若 *任何* scheme 带有 random-first-hops,则会将 `static_path` 缓存升级为 random-hop 布局。

```c
// 0x20b5d8e0 — ToroidalRouteCache(this, const proto::ToroidalRouteCache* cache_pb, const vector<Orientation>* orients)
void ToroidalRouteCache::ToroidalRouteCache(int* obj, const proto::ToroidalRouteCache* cache_pb, ...) {
    obj[0x8>>2] = obj[0x28>>2] = obj[0x48>>2] = obj[0x68>>2] = 0;   // 4 empty FlatHashMaps

    CHECK(cache_pb->routing_schemes_size() != 0);    // hard CHECK; toroidal_route_cache.cc:128
                                                     // ("cache_pb.routing_schemes_size() != 0")

    auto& scheme0 = cache_pb->routing_schemes(0);    // [cache_pb+0x18] repeated field, element 0
    int oneof = scheme0._oneof_case;                 // [scheme0+0x38]

    int type;
    if      (oneof == 3) type = 0;                   // distance        → distance map  [obj+0x8]
    else if (oneof == 5) type = 2;                   // bit_encoded_path→ vec<Dir> map  [obj+0x28]
    else {                                           // static_path (4) and everything else
        type = 1;                                    //                 → vec<Dir> map  [obj+0x28]
        for (auto& s : cache_pb->routing_schemes)    // any scheme with random-first-hops?
            if (s.random_first_hop_size() > 0) {     // [s+0x20] > 0
                type = 3;                            //                 → random-hop maps [obj+0x48]/[+0x68]
                break;
            }
    }
    obj[0] = type;                                   // *** the layout discriminant ***  0x20b5d97b

    CHECK_OK( this->CacheRead(cache_pb, orients) );  // toroidal_route_cache.cc:152
}
oneof[scheme0+0x38]附加条件[obj+0]布局
3(distance)0distance vector
5(bit_encoded_path)2bit-packed Direction path
4(static_path)没有 scheme 含 random_first_hop1单个 Direction path
4(static_path)某个 scheme 有 random_first_hop > 03random-hop path set

两个 CHECK 使该构造函数在 malformed proto 上不可恢复:空 routing_schemestoroidal_route_cache.cc:128)和非 OK CacheRead 结果(:152)。由于 proto 来自 烘焙、可信 资源,此处失败就是构建/打包 bug,因此是 abort 类 LogMessageFatal,而不是传播 Status。反编译还用 LogIndexOutOfBoundsAndAbort(标准 generated-proto bounds check)保护 routing_schemes(0) 访问。

注意 — first-scheme homogeneity。 判别量只从 scheme 0 读取(另加全局 random-hop 扫描)。因此缓存生产者必须在一个 blob 中发出 同质route oneof;混合 distance/static_path 的文件会被错误定型。CacheRead 的逐 scheme RetCheck(见下)正是防御这种情况,将异质 blob 转成非 OK status,而不是静默误插入。


CacheRead @0x20b5da20 — 逐条目展开循环

CacheRead 是主力:它将解析后的 proto 转为四个内存 map。它很大,因为四个 layout 分支都完全内联,每个都有自己的 raw_hash_set find_or_prepare_insert 和 value 构造代码,但结构是统一的。

Prologue — 构建旋转 helper

c
// 0x20b5da20 — CacheRead(this, const proto::ToroidalRouteCache* cache_pb, const vector<Orientation>* orients)
topo = slice_builder::Topology( cache_pb->topology() );        // field 1 → Topology ctor @0x20bf3820
rot  = TopologyRotationHelper::Create(topo, *orients);         // @0x20bf2380   (orients = dedup payoff)
if (!rot.ok()) return rot.status();                            // toroidal_route_cache.cc:161
int type = this->obj[0];                                       // the layout discriminant
```text

`orients` 是 dedup `Find` 返回的 `vector<proto::Orientation>`(见 [`route-cache-dedup.md`](route-cache-dedup.md))。缓存 blob 以单一 **规范** orientation 写入;helper `rot` 是从该规范芯片 id/坐标空间到 ** topology 轴的重映射。后续每个 key 和每个坐标都会通过 `rot`,这正是让一个烘焙 blob 服务一个形状所有 X/Y/Z 旋转的机制。`RotateId`/`RotateCoordinates`/`RotateOrientation` 自身的逐轴置换数学属于 [`route-cache-codec.md`](route-cache-codec.md);此处只标注它 *在哪里* 被应用。

### 逐 scheme 循环

对每个 `RouteScheme`,执行同一个骨架:

```c
for (auto& scheme : cache_pb->routing_schemes) {               // field 3, repeated
    int skey = rot.RotateId(scheme.src_chip_id);               // [scheme+0x28]  @0x20bf3020
    int dkey = rot.RotateId(scheme.dest_chip_id);              // [scheme+0x2c]  @0x20bf3020
    pair<int,int> key{skey, dkey};
    // ... decode value per `type`, then find_or_prepare_insert(key, value) ...
}

RotateIdtopo.GetCoordinate(id) → RotateCoordinates → topo.GetId(coord)GetCoordinate/GetId 是虚函数,vtable+0x88/+0x90)。两个芯片 id 都在组成 map key 之前 被重映射,因此内存 map 以 此 topology 的 芯片 id pair 为 key,而不是规范 blob 的。

四个 value 解码分支

分派形式为 if (type == 3) … else if (type == 2) … else if (type != 0 /*type 1*/) … else /*type 0*/。每个分支最终都会对不同的 FlatHashMapPolicy 做一次 find_or_prepare_insert,并且每个分支都有 RetCheck 守卫,确认 scheme 确实携带预期的 oneof:

type每个 scheme 的 proto oneofvalue 解码目标 mapfind_or_prepare policy value 类型
0distance (3) — 由 RetCheck(has_distance()) :166 守卫RotateCoordinates(scheme.distance) @0x20b5da20:3039[obj+0x8]superpod::routing::Coordinates
1static_path (4) — 由 RetCheck(has_static_path()) :189 守卫通过 RotateOrientation 旋转每个 static_path.hops[i][obj+0x28]vector<proto::Direction>
2bit_encoded_path (5) — 由 RetCheck(has_bit_encoded_path()) :216 守卫DecodePathFromBits(scheme.bit_encoded_path) @0x20b5c5a0[obj+0x28]vector<proto::Direction>
3random_first_hop(repeated)每个 random_first_hop[i].hop 一个 vector<Direction>probabilityint8 weights[obj+0x48](paths)+ [obj+0x68](weights)vector<vector<proto::Direction>> + vector<int8_t>

按分支列出的字节锚定说明:

  • Type 0(distance)。 superpod::routing::Coordinates value 由 scheme 的 distance ChipCoordinate 构造(Coordinates::Coordinates @…:3038),经 RotateCoordinates@…:3039)处理,然后插入 FlatHashMapPolicy<pair<int,int>, superpod::routing::Coordinates>find_or_prepare_insert_large @…:3047)。distance value 是一个 superpod::routing::Coordinates,即有符号逐轴 distance vector,而 不是 slice_builder::Coordinates。这是运行时 GetRouteDistance 读取的 map。
  • Type 1(static_path)。 scheme.static_path.hops 中的每个 Direction(一个 RepeatedPtrFieldStaticPath 默认实例是 …_StaticPath_globals_)都会被复制并用 RotateOrientation 重映射,累积成插入 [obj+0x28]vec<Direction> map 的 vector<proto::Direction>RetCheck(has_static_path()) 位于 toroidal_route_cache.cc:189
  • Type 2(bit_encoded)。 单个 scheme.bit_encoded_path bytes 字段被传给 DecodePathFromBits@0x20b5c5a0),返回的 vector<proto::Direction> 插入与 type 1 相同[obj+0x28] map:type 1 和 2 是同一个内存 value 的两种编码。bit-stream 布局(BitDecoder::GetVarInt 头、每个 Direction 的 orientation(2b)/polarity(1b))由 route-cache-codec.md 负责。RetCheck(has_bit_encoded_path()) 位于 :216
  • Type 3(random-hop)。 体积最大的分支:对每个 random_first_hop[i],一个 Directionhop,经 RotateOrientation 重映射)变成一个单元素 vector<Direction>,这些集合再变成插入 [obj+0x48]vector<vector<Direction>>FlatHashMapPolicy<pair<int,int>, vector<vector<Direction>>>)。每跳 probability(proto 中是 int32)被窄化为 int8,并累积到一个平行的 vector<int8_t>,插入 [obj+0x68]。两个 map 都以同一个旋转后的 (src,dst) pair 为 key,因此 path set 和 weight vector 保持对齐。

拒绝重复 key

每个分支都会检查 find_or_prepare_insert 结果,并 拒绝第二个具有同一旋转后 (src,dst) key 的 scheme

c
// e.g. type 3, around 0x20b5da20:+offset (the "$_0" lambda inline)
if (!inserted_fresh) {
    return MakeError(/*code 3 = InvalidArgument*/,
        StrCat("Duplicate insertion associated with source: ", skey,
               " and destination: ", dkey));                  // toroidal_route_cache.cc:322
}
```text

`StrCat` 会拼接字面量 `"Duplicate insertion associated with source: "`、source 芯片 id、`" and destination: "` 和 destination 芯片 id(经 `FastIntToBuffer`)。因此重复项是一个 *硬性、显式* 错误:缓存契约是在 *旋转后* 每个 `(src,dst)` pair 正好一个 `RouteScheme`;碰撞(生产者 bug,或两个旋转前 key 在旋转后 alias)会以精确诊断中止加载,而不是静默覆盖。

### 结果

OK 路径上,`CacheRead` 返回 `Status::OK`(`v15 == 1`),对象上的四个 `FlatHashMap` 槽被填充;随后 `Create` 将它们 move-construct 到 `StatusOr<ToroidalRouteCache>` payload(每个 map 的 C2 mover `@0x1fbe41e0`/`4220`/`4260`/`42a0`)。任何 `RetCheck` 不匹配或重复项都会产生非 OK `Status`,构造函数的 `CHECK_OK`(`:152`)随后会将其转为 fatal。

---

## 端到端(一张图)

```text
GetRouteCacheData(dims, twisted, orient, ToroidalRouteCacheType)            # 0x20b5c420
  path = "embed://" + lower(NameOf(type)) + "_data/" + <shape> + ".binarypb.compressed"
  ReadBinaryProto(path) → CompressedToroidalRouteCache{ format, data:Cord }  # 0x20d02060
  └─ Decompress: format==2 ? BrotliReader(data) → ParseMessage              # 0x20b63320  [THIS PAGE]
                 → proto::ToroidalRouteCache{ topology, routing_schemes[] }
ctor(proto, dedup_orientations)                                            # 0x20b5d8e0  [THIS PAGE]
  [obj+0] = {distance→0, static_path→1, bit_encoded→2, +random_hop→3}
  CacheRead(proto, dedup_orientations):                                    # 0x20b5da20  [THIS PAGE]
     rot = TopologyRotationHelper(topology, dedup_orientations)            # canonical→actual remap
     for scheme in routing_schemes:
        key = ( rot.RotateId(src_chip_id), rot.RotateId(dest_chip_id) )
        switch [obj+0]:
          0: map@+0x8 [key] = rot.RotateCoordinates(distance)              # superpod::routing::Coordinates
          1: map@+0x28[key] = [rot.RotateOrientation(h) for h in static_path.hops]   # vector<Direction>
          2: map@+0x28[key] = DecodePathFromBits(bit_encoded_path)         # vector<Direction>  → codec page
          3: map@+0x48[key] = [[hop] for hop in random_first_hop];         # vector<vector<Direction>>
             map@+0x68[key] = [int8(p.probability) for p in random_first_hop]
        on collision: error "Duplicate insertion associated with source: …"
Create: move the 4 maps into StatusOr<ToroidalRouteCache>                  # 0x20b5d6e0

重新实现检查清单

  • [ ] Decompress:用 InvalidArgument("Unsupported format: %d") 拒绝 format != 2;将 data Cord 包进 riegeli::BrotliReader<CordReader<Cord>>ParseMessageproto::ToroidalRouteCache;传播 parse 失败(不要 abort)。
  • [ ] 构造函数CHECK 非空 routing_schemes;从 routing_schemes(0)._oneof_case 设置 [obj+0]3→0, 5→2, 4→1),如果 任何 scheme 有 random_first_hop_size() > 0,则将 1→3
  • [ ] CacheRead:从去重 orientation vector 构建 TopologyRotationHelper;对每个 scheme,将两个芯片 id 都 RotateId 到 key;按 layout type 解码,并对匹配的 has_*()RetCheck;插入 per-type map;用精确的 "Duplicate insertion associated with source: …" 消息拒绝重复 key。
  • [ ] 保持四种 value type 字节级精确:distance → superpod::routing::Coordinates;static/bit-encoded → vector<proto::Direction>(同一 map);random-hop → vector<vector<proto::Direction>> 加平行的 vector<int8_t> weight map。

注意(字段号置信度 LOW)。 按上游 descriptor decode,random_first_hop 字段 tag 是 wire tag 7;本文只锚定构造函数升级和逐元素 hop/probability 访问所用的内存 [scheme+0x20] count 读取。精确 proto 字段 编号(7)来自 descriptor,而不是由本文中的 EnumDescriptorProto 字节确认;因此图中的 (7) 标注应按此处理。


交叉引用

  • route-cache-dedup.mdRouteCacheDeduplicatorRouteCacheIdentifier key,以及 CacheRead 消费的 vector<proto::Orientation> rotation vector;也包括选择 ToroidalRouteCacheType 的无参 vs 代号 keyed GetCacheDeduplicator overload。
  • route-cache-codec.mdDecodePathFromBits(type-2 bit-stream 解包)以及贯穿 CacheRead 应用的 TopologyRotationHelper RotateId/RotateCoordinates/RotateOrientation 置换数学。
  • toroidal-route-cache.mdToroidalRouteCache 容器对象、它的四个 FlatHashMap 布局及其在 topology 中的嵌入、Create 编排,以及基于 [obj+0] 的运行时读侧分派(CacheHit/GetRouteDistance/GetRoutePath)。
  • overview.md — ICI routing 章节地图:预计算 ToroidalRouteCache 相对于实时 *ToroidalWildFirstPaths 生成器和 InitRouteSolution cache-vs-generate 决策的位置。
  • get-static-path.md — packed (hop_count<<6 | polarity<<3 | orientation) DirectionHops 编码,由缓存的 vector<proto::Direction> 条目和实时路径生成器共享。