屏障和错误聚合器如何使用集群元数据
两个跨主机子系统会消费集群元数据,并且二者都只读取 扁平 DCN 层:主机总数和 (slice_id, host_id) 主机身份。二者都不会触及芯片坐标、切片形状或 DCN 规约树。
跨主机屏障
Megascale 跨主机屏障是一个以主机身份为键的集中式计数器:
- 默认参与者数量 =
MultiSliceTopologyAndLocation::NumHosts()— 所有切片中的主机总数。未参数化的屏障(collective-rendezvous 风格)只有在集群中的每台主机都到达后才会完成。 - 到达键 =
(slice_id, host_id)元组。协调器 (BarrierCoordinator::ProcessRequest @0x1cf54e60) 将到达记录存储在BarrierCoordinator+0xD8处的flat_hash_set<tuple<int,int>>中;重复到达(例如重试)会被拒绝,因此不能重复计数。另外,调用方侧 (Communicator::Barrier @0x1cca8ee0) 会维护一个已使用屏障 ID 的flat_hash_set<string>,并用 "Barrier ID: $0 has already been used." 拒绝重复使用的 ID。 - 没有其他内容。 屏障从不读取切片形状、芯片坐标或
DCNTopology。它只需要两个事实:要等待多少台主机(NumHosts),以及如何识别每一台((slice_id, host_id))。
NumHosts() 由 MultiSliceTopologyAndLocation 类根据已组装的集群视图计算:它对每个切片的 TpuTopologyArgsProto 的 product(host_bounds) 求和。因此,屏障的参与者数量最终来自启动时收集的逐切片形状。
错误聚合器
错误聚合器 将逐主机错误报告汇聚成一个摘要,同样以主机身份为键:
提前触发条件 =
MegascaleErrorAggregator::size() ==expected-worker-count,在ErrorReporter::ReportError @0x1ccb6ea0中检查。预期数量通过ErrorReporter上的一个虚拟访问器读取(该对象以TopologyCoordinator const*构造),并等于集群级主机总数 (TopologyCoordinator::GetNumHosts() @0x1cf51de0/MultiSliceTopologyAndLocation::NumHosts() @0x20802c20)。达到该数量时,reporter 会立即调用ErrorReporter::ProcessErrorDigest;否则会回退到同一位置设置的 300 ms 超时(Duration += 300)。二进制中不存在TopologyCoordinator::NumWorkers()方法。逐错误 worker 键 =
Substitute("slice$0-task$1", slice, task)(在ReportError中构造,来自内存中MegaScaleRuntimeError的 slice 和 task 索引)。去重linked_hash_map<string, ...>键 (AddError @0x1ccba940) 会追加一个/分隔符和尾随整数,因此完整键为"slice<slice>-task<task>/<n>"。罪魁命名。 摘要中被归咎的主机由
RapidEyeErrorDigestProto.WorkerAndCoreInfo消息命名(通过ToWorkerAndCoreInfoProto @0x1ccc4f80从内存中的MegascaleErrorAggregator::WorkerAndCoreInfo结构发出):protobufmessage WorkerAndCoreInfo { // RapidEyeErrorDigestProto.WorkerAndCoreInfo string worker_id = 1; // "slice<slice>-task<task>" string host_name = 2; CoreInfo core_info = 3; message CoreInfo { int32 chip_id = 1; int32 core_idx = 2; string physical_location = 3; } } ```text
这个 CoreInfo {chip_id, core_idx, physical_location} 三元组是跨主机层中唯一以物理方式命名芯片的位置,并且它是诊断输出,而不是启动库存的一部分。
故障链路 是主机粒度的:
protobufmessage FaultyNetworkLink { // RapidEyeErrorDigestProto.FaultyNetworkLink WorkerInfo src_worker = 1; // RapidEyeErrorDigestProto.WorkerInfo WorkerInfo dst_worker = 2; }每个端点都是一台主机(
WorkerInfo={worker_id, host_name, cloud_instance_id}),直接映射回一个NetworkAddressMapping条目。跨主机故障模型中没有 ICI 级链路。
共享依赖
两个消费者依赖同样两个派生事实:
| 事实 | 来源 | 使用方 |
|---|---|---|
NumHosts() | 对所有切片的 product(host_bounds) 求和 | 屏障参与者数量、聚合器提前触发 |
(slice_id, host_id) | NetworkAddressMapping | 屏障到达键 (flat_hash_set<tuple<int,int>>)、聚合器 worker 键 ("slice<slice>-task<task>") |
更丰富的所有内容 — 切片形状、芯片坐标、DCNTopology — 都是 collectives 和编译器层的职责。屏障和错误聚合器将集群视为一个由 NumHosts 台主机构成的扁平集合,每台主机都由 (slice_id, host_id) 命名。
这对取证为何重要
因为跨主机层是主机粒度的,所以将挂起分类为 BAD_TPU_CHIP 或 BAD_SC_CHIP 的摘要只能指向主机(通过 WorkerAndCoreInfo)。要获取这些主机的芯片级状态,operator 需要继续调用 tpunetd 的 GetCoreDump(CORE_DUMP_CHIP_DUMP),也就是回到 ICI 层。集群元数据的两层拆分正是需要这种交接的原因:跨主机摘要知道哪台主机,而 tpunetd 知道哪颗芯片。参见 ICI 与 DCN 以及 tpunetd 关系。