2026-04-15 Daily
🧠 今天记录
- 看到flagcxWaitSignal 报错raise RuntimeError(f”FLAGCX error: {error_str}”)
- 确定了 error 码是 1,就是Unhandled device error ⬇️
- 先增加了 comm 初始化 并发的隔离,未解决,但是代码保留 ⬇️
- 然后怀疑是 context 用了其他的 cudaDevice 导致的,加了setCurrentDeive之后导致会出现 hang,不会直接报错。问题不在这,因为打印发现 worker 线程都是这样用的,并且和 mooncake 使用的方式是对齐的,问题不在这。❌
- sanitizer 排查内存问题,
- sanitizer 跨机给出的 error 分别有:
cudaErrorNoKernelImageForDevice (error 209) on cudaGetLastError, CUDA_ERROR_NOT_PERMITTED (error 800) on cuMemCreate,CUDA_ERROR_NOT_SUPPORTED (error 801) on cuMemGetHandleForAddressRange. 三类错误分别是没指定sm90,VMM 不知道为什么分配被拒,不支持ncclCommWindowRegister。signal 难道分配的有问题?
- 发现flagcxOneSideBuildFullMesh内存在下面问题,需要结合 flagcx.cc内flagcxOneSideBuildFullMesh的 for 循环来看:
时间轴 ──────────────────────────────────────────────────────►
rank0: [i=0: self↔self] ──完成──► [i=1: while循环开始]
└─ connect(rank1.listen) TCP 进入 rank1 的 accept queue
accept(rank0.listen) 等待 rank1 来连
rank1: [i=0: while循环]
connect(rank1.self) TCP 进入 rank1 自己的 accept queue
accept(rank1.listen) ← rank1的accept queue里现在有2个连接:
[A] rank1 自己(self-connect, i=0预期)
[B] rank0 发来的 (i=1来的, 不该这轮消费)
OS 的 accept queue 是 FIFO,但 [A] 和 [B] 谁先到是竞态。如果 rank0 的 TCP connect 先到:
rank1 的 accept() 拿到了 [B] (rank0 的 i=1 连接)
→ recvComm 设置为来自 rank0 的连接 ✓ (recvComm != NULL)
→ while 条件: sendComm==NULL || recvComm==NULL
→ recvComm 非 NULL,accept() 不再被调用
rank1 的 connect(self) 还卡在 StateSend/StateConnecting
→ 需要有人 accept() 自己发过去的 QP info
→ 但 while 循环里 recvComm 已非 NULL,不会再调 accept()
→ sendComm 永远是 NULL
→ while(sendComm==NULL || recvComm==NULL) 永远成立
→ rank1 无限循环,sendComm 卡死 ← HANG
问题是,这里在和 mc 讨论中发现 mpich 启动的测试从来不会出现问题,我用 openmpi 会出现问题。就算这里加上 barrier,在 pd 分离的时候依旧会出现 decode 出一样的报错。
🚀 今日TODO
🧩 遇到的问题 / 卡点
📌 明天该干啥
💡 随手记录