跳到主要内容

ISSUE-044: G5 建模与测试 Code Audit — Findings 汇总

发现日期:2026-06-10 状态部分已修复 (2026-06-10 plan 执行完成:护栏 3 项 + P0-1/2/3/4 + 存量 4 bug — tcredit 零字节帧 credit 泄漏 / p2p Send retire 错芯片 / switch 丢包 credit 对账 / psn_gaps 净计数;剩余 P0-5/6 + P1/P2/P3 见 plan 阶段外清单) 类型实现 bug + 建模误差 + 测试缺口 混合 影响范围:G5 仿真引擎 (perfmodel/evaluation/g5/)。collective 展开层 DBT / hierarchical / 2-port 三条路径在仿真语义下产出错误结果;测试体系对这些路径覆盖为零,golden/MR 仅跑 pairwise alltoall。基建层 (守恒插桩 / 事件核 / CBFC 对账) 质量高,不受影响。


审查方法

对 G5 全量代码 (7 个 Python 胶水文件 + 93 个 Rust 文件,~25k 行) 与 ~448 个 Rust 测试 + Python 测试做 5 维独立 audit (Correctness / Structure / Rules / Efficiency / Test-effectiveness)。3 个 P0 经主对话抽查复核 (读源码确认行号与逻辑)。


问题现象 (按严重度汇总)

P0 正确性 (会产出错误结果,必修)

IDFile:LineIssue后果
P0-1collective/tree_allreduce.rs:24 vs :118DBT broadcast 方向倒置:edges 存 (child, parent), broadcast 循环按 &(parent, child) 解构,emit 出来仍是 child→parentroot 永不下发,依赖结构全错;测试只数 Transfer 总数 (=12) 抓不到
P0-2collective/tree_allreduce.rs:55-102last_msg_id 消费后不清除,同 chip 第二条 MsgWait 等已被消费的 msg_id (msg_central 是消费语义)DBT 进仿真即 stall;守恒护栏无"CDMA cmd 未 retire"检查 → latency 静默截断偏小
P0-3collective/hierarchical.rs:149-160维度间依赖只挂 cmds[0] 且 dep 是 thread 级,跨维 thread 不一致 → 永不满足或错误并行分层 collective (BlueConnect 路径) 整条不可信
P0-4collective/expand.rs:137-141 + top/multi_chip/setup.rs:226-2312-port × 多 channel 映射 unit 0..2C-1 越界,加载层 if unit_idx < units.len() 静默丢命令半数 channel 凭空消失,字节守恒破坏 + 静默截断。这是 ISSUE-025 搁置的 2-port 标度问题的根因之一
P0-5comm_result_builder.py:83busbw 分子用 msg_size_bytes 漏乘 spec.repeat,而 latency 覆盖 repeat 次传输repeat>1 时 busbw 低估 repeat 倍;busbw 是 sweep 排序 score (engine_adapter.py)
P0-6lib.rs:48-103cancel_check 仅仿真启动前调一次,cancel_flag 是函数内局部 Arc,启动后无人能置位,主循环每 1000 事件的轮询是死代码分钟级多芯片仿真无法中途 kill,与 CLAUDE.md "取消靠 AtomicBool 轮询" 描述不符

P1 结构 / 正确性风险

IDFile:LineIssue
P1-1rc_link_tx.rs:415 + event_handlers/paxi.rs:329NAK 处理先 on_ack, process_ack 无条件 retry_counter.remove,即使释放 0 slot;持续丢同一 PSN 时 counter 反复清零 → max_retry=15 永不命中,Go-Back-N livelock, liveness 探测也不报警 (每次重传刷新 last_progress)。与 ISSUE-041 不同:041 修 timer 太紧致 spurious 重传,本条修 counter 清零致 max_retry 失效
P1-2event_handlers/shared.rs:47-56ACK/CNP 反向路由失败时静默 fallback 零延迟立即送达 → 时序系统性偏快,守恒抓不到 (数据照常流动)
P1-3switch.rs:247-298iSLIP grant 用 HashMap RandomState 迭代 → 仿真不可复现;priority=3 (tcredit) 不保证优先于 priority=2 数据
P1-4collective/helpers.rs:189 + expand.rs:56,821-port ring msg_id 段隔离仅 step<32 成立,C>4 且 N≥17 跨 channel 计数污染;2-port 断言 <32 是对的,1-port 漏了
P1-5collective/p2p.rs:9模块级 static THREAD_COUNTER: AtomicU32 分配 thread,不复位;PyO3 常驻进程下同 program 连续两跑结果漂移;%8 硬编码无视 threads_per_cdma
P1-6collective/tree_allreduce.rs:45,105DBT 两棵树串行 (共享 last_cmd_id + 全 thread 0) + parent 只 MsgWait 最后一个 child → DBT 并行收益未建模,延迟 ≈2× 理论值
P1-7top/multi_chip.rs:72-79空 chips 守卫在 .expect("...paxi...") 之后,永不可达;空输入先 panic 跨 FFI
P1-8cdma/callbacks.rs:22-30完成回调硬编码 tx_threads, Rx group 指令 pending_count 永不递减;hierarchical 用例触发 Rx thread pending 泄漏 → 永久 FenceWait
P1-9sim_engine.py:55 / comm_primitive_pipeline.py / pipeline.py:23sim_engine 路由空路径静默编造直连;pipeline.py 收 network_graph/routing_strategy 参数但从不使用,多芯片退化单芯片无报错

P2 规范合规 (项目铁律)

IDFile:LineIssue
P2-1input/parse_topology.rs:44-125死代码全链路 (旧 interconnect 格式),携带"缺字段 eprintln WARN + 空 map"违例 (config-loading 铁律) + 旧格式残留 (no-backward-compat);无生产调用方,应整体删除
P2-2comm_primitive_pipeline.py:59 / comm_result_builder.py:78dma_engines.get("cdma")→端口数兜底 1;未知 primitive 兜底 1.0 — 违反禁默认值铁律
P2-3rc_link_dcqcn.rs:22timer_interval_ns: 3_000.0 vs 注释 "55us",差 18× (DCQCN 标准 55μs)
P2-4input/parse_chip.rs:109 / parse_topology.rs:64get_item 任何错误当"引擎不存在"; .and_then(extract().ok()) 类型错静默吞 None — fail-loud 缺失
P2-5common/trace.rs:53 + lib.rs:81未知 trace category 字符串 filter_map 静默丢弃 → typo 得空 trace 无报错
P2-6comm_result_builder.py:43 vs comm_primitive_pipeline.py:71同一 total_sim_time_ns 缺失,一处 raise 一处兜底 agg.total_time*1e6,行为不一致
P2-7tests/evaluation/g5/test_adapter.py:31chip fixture 读真实 SG2262.yaml,应复用 conftest 的内存 chip_spec (单测不读真实 YAML 约定)

P3 风格 / 效率 / 死代码

IDFile:LineIssue
P3-1cdma/tests.rs:1699AI 自言自语死注释 "(我的 mask 设错了,让我重新算...wait)",且算式本身写错
P3-2rc_link_tx.rs:383process_ack 每次扫全 512 slots + retain(contains) O(slots×pending), ACK 最热路径
P3-3sim_kernel.rs:152cancel_timer 对已 fire timer 的 tid 永留 cancelled HashSet,长仿真无界增长
P3-4expand.rs:22 / 各 emit 点source_op_id: String 每条 cmd 克隆 (ring N=64 C=8 上万次),可改 Arc<str>
P3-5c2c_link.rs vs c2c_network.rs PhyLink两套几乎相同物理链路实现,易漂移
P3-6forwarding/ecmp_hash.rs:47ECMP 用恒等 flow_id % K 无 hash,易系统倾斜;flow_cache 无淘汰长仿真内存涨
P3-7build_g5rs.py:85非 Windows 只找 .so, macOS .dylib 必失败;产物复制到根目录 shadow maturin 装的版本
P3-8adapter.py:80-104DMA engine 的 duration 不进任何 bucket, total_memory_time 永远 0, memory-bound 算子瓶颈分析失真

测试有效性 (核心问题)

IDFile:LineIssue关联
T-1golden 16 cell (driver.rs:210)全部是 alltoall + pairwise; routing 维度纯标签 (全跑静态路由);n_ports 不改 unit 数。4 个 P0 全部在零覆盖路径上,这是它们能存活的原因
T-2top/multi_chip/tests.rs 全文件21 个集成测试 19 个未调用 assert_conservation,断言多为 sim_time>0 + 5× 宽界。这是 MEMORY "G5 存活性验收缺陷" pending 项的主体,helper 已存在纯接线MEMORY g5_test_hardening
T-3tests/ 全目录无 G5×Math 差分校验,两路径从未互比;golden 只防"变"不防"错"ISSUE-016
T-4mr_tests.rs:100MR3 比较两次完全相同的仿真 (n_ports 不改 unit 数),恒等通过却未声明 LIMITATION
T-5golden/update_golden确定性仿真配 1% 容差 + update 即重基线 → 容差棘轮,系统性慢漂移不可见 (与 ISSUE-041 lesson 一致)ISSUE-041
T-6collective *.rs 89 测试全停在命令生成计数层 (cmd 数/msg_id/依赖),无时序对照解析公式;删调度串行化约束命令结构不变,测试全绿

交叉引用 (与现有 issue 关系)

现有 issue关系
ISSUE-025 (测试覆盖缺口)ISSUE-025 记载的两个 2-port ignored 测试现已激活 (tests.rs:299/317) 但 fixture total_cdma_units=1 不经过 replicate_channels,探测不到 P0-4。P0-4 验收需新增 C≥2 × 2-port 测试 (见 plan Task 7)
ISSUE-041 (retry_timer 太紧)P1-1 是不同 bug: 041 修 timer 时长致 spurious 重传;P1-1 修 retry_counter 无条件清零致 max_retry 永不命中 livelock。两者都在 RC Link 重传路径
ISSUE-016 (AG/RS G5-Math 差分)T-3 (无 G5×Math 差分校验) 是 016 的系统化延伸
MEMORY: G5 测试加固T-2 (守恒断言接线) + T-3 (差分) 即该 pending 项的两个落地方向

修复优先级 (建议顺序)

阶段 1 — 先堵静默截断 (改护栏,不改算法;让坏路径从"错数据"变"显式红")

  1. collect_results 增加"所有 CDMA sendq/rcvq 排空"守恒线,纳入 CONSERVATION_KEYS (堵 P0-2/3/4 的静默截断)
  2. setup.rs:226 unit 越界 if unit_idx < units.len()panic! (带 chip/thread/units.len)
  3. event_handlers/shared.rs:47 ACK 路由失败计数到独立 stat 纳入守恒,不静默零延迟
  4. top/multi_chip/tests.rs 19 个集成测试结尾统一接 assert_conservation (helper 已存在)

阶段 2 — 修 6 个 P0 (此时有失败基线兜底)

  1. P0-1 + P0-2: tree_allreduce 方向修正 + msg_id 消费后清除 (并补 direction 断言测试)
  2. P0-3: hierarchical 维度间用 chip 级同步原语
  3. P0-4: expand_one 容量除以 units_per_port_mode (新增 total_cdma_units≥2 × 2-port 仿真测试验收;tests.rs:299/317 为 C=1 路径不覆盖本修复)
  4. P0-5: busbw 分子乘 repeat (+ repeat>1 回归测试)
  5. P0-6: cancel 机制改为暴露 AtomicBool 句柄给 Python 侧持有,或 detach 闭包内周期 try_attach 回调

阶段 3 — P2 规范 + 正确性对照测试

  1. P2-1 删 parse_topology 死代码全链路;P2-2 去默认值兜底;P2-3 对齐 DCQCN timer
  2. collective × 解析公式时序对照测试 (ring AR=2(N-1) 步精确值); golden 矩阵扩到 allreduce/HD/DBT,容差降 0
  3. G5×Math 差分测试 (承接 ISSUE-016)

阶段 4 — 结构 / 性能 (非阻塞)

  1. P1-1/2/3/5 复现确认后修;P3 系列 (ACK 索引化 / c2c 单实现 / Arc / ECMP hash)

验证

  • 阶段 1 完成判据:跑现有 DBT/hierarchical/2-port 用例应变红 (守恒线触发),证明护栏有效
  • 阶段 2 每个 P0 修复后,对应路径守恒线回绿 + 新增 direction/timing 断言通过
  • 新增 C≥2 × 2-port 仿真测试通过 (2-port 快于 1-port + 守恒全绿);tests.rs:299/317 保持现状,不作为 P0-4 验收
  • 全量 cargo test --release + pytest tests/evaluation/g5/ 0 失败

遗留问题

  • P1-1 livelock / P1-8 Rx pending 泄漏为静态推导结论,未跑端到端复现 (当前 collective 路径全 Tx group, P1-8 未触发)
  • F9 (2-port ceil(N/2) 步数模型 vs 标准双向 ring 偏差 33%) 是建模选型问题,需对 G5-CDMA spec 裁定后再定修复方向
  • 完整 5 维 audit 原始报告 (含每条 Why-it-matters 详述) 在本会话产出,未独立成文