已合并
engram修复aiv数小于rank数切换channel导致sq溢出 #14556
wuchenhao123创建于 3 天前
engram修复aiv数小于rank数切换channel导致sq溢出 #14556
已合并
Pull Request已成功合入, 合并人@CANN-robot
(感谢 wuchenhao123 的贡献)3 天前 创建了 pull request,commit 5e8d4a83
atomgit-bot
3 天前 评论:
3 天前 评论:
变更摘要
本 PR 针对 mc2/engram_fetch/op_kernel/arch35/engram_fetch_arch35.h 中切换 channel 导致 SQ 溢出的问题,将原先基于单一全局计数与当前 channel 句柄的待发送读请求管理方式,改为按 rank 维度统计待发送读数量。EngramFetchArch35 新增每 rank 的读计数缓冲区,在判断是否需要 Drain 时使用对应 rank 的计数,从而更准确地控制同一 channel 上未完成读请求的堆积。
主要改动
- 按 rank 维护待读计数: 新增 UB 成员
rankReadCntBuf_,在Init中按numRanks_ * sizeof(uint32_t)对齐分配,并用Duplicate<uint32_t>初始化为 0,同时通过SyncFunc<AscendC::HardEvent::V_S>()保证初始化可见。 - 移除全局 SQ 计数与活动 channel 记录: 删除
sqReadCount_和activeChannelHandle_成员,PrepareRead不再递增全局计数,仅保留preparedReadCount_的批次统计。 - Drain 判定改为按 rank 计数:
RemoteFetchRank中以rankReadCnt(ownerRank)决定needDrain,提交读请求后递增该 rank 计数,Drain完成后仅将该 rank 的计数清零,避免跨 channel 切换时计数被误重置。 - UB 预算同步更新:
usedUb计算加入rankReadCntBufSize,使后续maxBatchSize等可用 UB 推导包含新增缓冲区的开销。
🧩 本次 Review 已使用自定义 Skill:


不准确?
3 天前 添加了label:cann-cla/yes
CANN-robot
3 天前 评论:
3 天前 评论:
Thanks for your pull-request.
The full list of commands accepted by me can be found at here.
You can get sig-info at here.
You can self-configure the PR merge rules for this repository. For more details, please refer to Here.
For more, you also can visit HICANN.
PR Approval Progress
✅ Congratulations! All modules have met the lgtm and approve requirements.
Module Approval Details
| module | lgtm status | approve status |
|---|---|---|
| mc2 | ✅ wang-minbo, chenjunjian11 (2/2) | ✅ wang-minbo (1/1) |
💡 Tip:
- Committer can comment
/approveor/lgtm- Commenting
/approveimplies both code review (lgtm) and intent to merge (approve)
CLA Signature Pass
wuchenhao123, thanks for your pull request. All authors of the commits have signed the CLA. 👍


CANN-robot
3 天前 评论:
3 天前 评论:
3 天前 将captainmiaow,monologue815,jiang-lirui,Allan_Yu,wang-minbo,tgwsakiko_,liudan12,chenjunjian11,yangzeheng,liuboxi,luobaiqing,zhong-zixin,libohao6,mabing1118,macech,huangshuai59设为评审人
3 天前 将captainmiaow,monologue815,jiang-lirui,Allan_Yu,wang-minbo,tgwsakiko_,liudan12,chenjunjian11,yangzeheng,liuboxi,luobaiqing,zhong-zixin,libohao6,mabing1118,macech,huangshuai59设为评审人
此处折叠了6条事件消息 查看更多
3 天前 修改了pull request 的描述
wuchenhao123
3 天前 评论:
3 天前 评论:
/compile


3 天前 预合并成功(commit_id: 209857ade85aceaa8efe3de198780a70e08db0a9)
wuchenhao123
3 天前 评论:
3 天前 评论:
/ai review


atomgit-bot
3 天前 评论:
3 天前 评论:


不准确?
CANN-robot
3 天前 评论:
3 天前 评论:
| 🚀 CI 流水线已启动 |
|---|
| 📋 执行详情: 点击查看流水线 |


3 天前 添加了label:ci-pipeline-running
此处折叠了5条事件消息 查看更多
3 天前 修改了pull request 的描述
wang-minbo
3 天前 评论:
3 天前 评论:
/lgtm
/approve


3 天前 添加了label:approved
chenjianjun11
3 天前 评论:
3 天前 评论:
/lgtm


3 天前 添加了label:lgtm
3 天前 关闭了关联的issue
3 天前 合入了pull request
描述
修复了在 aiv 核数小于卡数时,单个aiv切换channel时多个channel共享一个sq队列计数器导致溢出,新增数组分别记录
关联的Issue
https://gitcode.com/cann/ops-transformer/issues/6728
测试
本地测试
文档更新
类型标签
一、变更概述
该 PR 修复 EngramFetchArch35 kernel 中跨 channel 切换时 SQ(Send Queue)在途
读计数丢失导致的 SQ 溢出问题:
(activeChannelHandle_ 成员一并删除)。
"每 (core, channel) 一个"的在途读计数,跨 channel 切换、跨 batch 持久保持,
仅在 mid-stream Drain 后清零。
RemoteFetchRank 通过 rankReadCnt(rankReadIdx) 维护。
替换 ScatterByRank / Process / FetchByRank 中的 4 处重复调用。
二、根因确认(修复动机成立)
旧代码 bug 场景(真实存在):
SQ 的在途上限。
但被切走的 channel 上仍有未 Drain 的在途读。
ownerRank += totalBlocks_轮询 ≥2 个远端 rank(每 rank 独立 channel),且 token 数超过一个 batch(indicesBatchSize_)或单 rank 在途读跨 batch 累积。
此时每次切换 channel / 进入下一 batch 都把计数清零,实际在途读数被低估,
累计 ≥ 32767 后硬件 SQ 溢出。
旧代码不会误清零,故旧 bug 仅存在于 tb < numRanks 且单核服务 ≥2 个
远端 rank 的配置。修复后两种模式均正确。
结论:这是一个真实的 bug,修复方向正确。
三、修复正确性核验(逐项通过)
索引边界安全性:PROVEN SAFE
(GetBlockIdx 保证),故 ownerRank / totalBlocks_ = k。
k_max = floor((numRanks_-1-aivId_)/tb) <= ceil(numRanks_/tb) - 1
= rankReadCntSlots - 1,恒在界内,不会越界。
slot ↔ channel 一一对应:CORRECT
每 remote 核只访问一个 channel(assignedRank/idxInRankGroup 不变),
单 slot 即该 channel 的计数。
按 residue 划分、互不重叠,跨核无共享计数需求(计数器本就在各核私有
UB 中)。
计数语义与旧代码一致(无切换场景):
FlushPreparedReads + Drain 后清零,SQ 峰值恰好为上限,与旧逻辑等价。
修复点,使非活跃 channel 的在途读被持续追踪。
计数迁移完整性:VERIFIED
无其它调用方依赖被删除的 sqReadCount_ 自增。
同步正确性:CORRECT
读写,方向正确;此后对该缓冲区只有标量访问(标量↔标量无需同步),
其它向量操作不触碰该 buffer,无 hazard。
UB 预算:UPDATED
缓冲区 ≤ Ceil(slots*4, 32)*32,slots 最大约 1024(tb=1 时),约 4KB,
开销可忽略。
totalBlocks_ 缓存:SAFE
旧文件 4 处调用点全部替换,无残留(新文件仅剩 Init 中 1 处)。
Batch 完整性(未被破坏):
activeBatchHandle_ 不会跨 channel 复用(前提是 MakeBatchHandle 仅在
preparedReadCount_==0 时重绑,现有代码满足,属既有逻辑)。
四、发现的问题与建议
【信息】1. numRanks_ == 1 时缓冲区空转
位置:Init(engram_fetch_arch35.h:227-232)
numRanks_==1 走 LocalFetchRange 路径,rankReadCntBuf_ 永不使用,但仍会
InitBuffer + Duplicate + 同步一次。开销极小(32B + 一条向量指令),
可不改;仅提示。
【信息】2. slots 计数略宽松(无影响)
tb < numRanks 时 slots = ceil(numRanks_/tb),对不均匀尾部(如
numRanks=5, tb=4,core3 只用 slot 0)会多分配少量 slot。仅浪费几十字节,
无正确性影响,可不改。
五、总体结论
修复方案正确、完整:
取代,索引在两种核分配模式下均可证明不越界,slot 与 channel 一一对应。
================================================================================