已合并
engram修复aiv数小于rank数切换channel导致sq溢出 #14556
engram修复aiv数小于rank数切换channel导致sq溢出 #14556
已合并
wuchenhao123创建于 3 天前
wuchenhao123
wuchenhao123成员
3 天前

描述

修复了在 aiv 核数小于卡数时,单个aiv切换channel时多个channel共享一个sq队列计数器导致溢出,新增数组分别记录

关联的Issue

https://gitcode.com/cann/ops-transformer/issues/6728

测试

本地测试

文档更新

类型标签

一、变更概述

该 PR 修复 EngramFetchArch35 kernel 中跨 channel 切换时 SQ(Send Queue)在途
读计数丢失导致的 SQ 溢出问题:

  1. 删除单一标量计数器 sqReadCount_ 及其"channel 切换即清零"的逻辑
    (activeChannelHandle_ 成员一并删除)。
  2. 新增 UB 缓冲区 rankReadCntBuf_,以 rankReadIdx 为索引维护
    "每 (core, channel) 一个"的在途读计数,跨 channel 切换、跨 batch 持久保持,
    仅在 mid-stream Drain 后清零。
  3. PrepareRead 内的 ++sqReadCount_ 移除,计数增量改由唯一调用方
    RemoteFetchRank 通过 rankReadCnt(rankReadIdx) 维护。
  4. 将 GetBlockNum() 提升为成员 totalBlocks_,在 Init 中缓存一次,
    替换 ScatterByRank / Process / FetchByRank 中的 4 处重复调用。
  5. usedUb 预算中计入了新增的 rankReadCntBufSize。

二、根因确认(修复动机成立)

旧代码 bug 场景(真实存在):

  • HCOMM_SQ_MAX_PENDING = 32767(engram_fetch_utils.h:45),为每 channel 硬件
    SQ 的在途上限。
  • 旧逻辑在 activeChannelHandle_ 变化时无条件执行 sqReadCount_ = 0,
    但被切走的 channel 上仍有未 Drain 的在途读。
  • 触发条件:totalBlocks_ < numRanks_(核数少于 rank 数),单核通过
    ownerRank += totalBlocks_ 轮询 ≥2 个远端 rank(每 rank 独立 channel),
    且 token 数超过一个 batch(indicesBatchSize_)或单 rank 在途读跨 batch 累积。
    此时每次切换 channel / 进入下一 batch 都把计数清零,实际在途读数被低估,
    累计 ≥ 32767 后硬件 SQ 溢出。
  • 注:totalBlocks_ >= numRanks_ 时每远程核只绑一个 channel,
    旧代码不会误清零,故旧 bug 仅存在于 tb < numRanks 且单核服务 ≥2 个
    远端 rank 的配置。修复后两种模式均正确。

结论:这是一个真实的 bug,修复方向正确。

三、修复正确性核验(逐项通过)

  1. 索引边界安全性:PROVEN SAFE

    • tb >= numRanks:rankReadIdx 恒为 0,slots = 1。
    • tb < numRanks:ownerRank = aivId_ + k*totalBlocks_,且 aivId_ < tb
      (GetBlockIdx 保证),故 ownerRank / totalBlocks_ = k。
      k_max = floor((numRanks_-1-aivId_)/tb) <= ceil(numRanks_/tb) - 1
      = rankReadCntSlots - 1,恒在界内,不会越界。
  2. slot ↔ channel 一一对应:CORRECT

    • tb >= numRanks:GetCoreAssignment 对固定 aivId_ 结果确定,
      每 remote 核只访问一个 channel(assignedRank/idxInRankGroup 不变),
      单 slot 即该 channel 的计数。
    • tb < numRanks:slot k 对应 channel(aivId_+k*tb, 0),各核负责的 rank
      按 residue 划分、互不重叠,跨核无共享计数需求(计数器本就在各核私有
      UB 中)。
  3. 计数语义与旧代码一致(无切换场景):

    • needDrain 在下发前判断 (cnt + 1 >= 32767),即第 32767 个读触发
      FlushPreparedReads + Drain 后清零,SQ 峰值恰好为上限,与旧逻辑等价。
    • isLast(CQE 标记)读不清零、不 Drain,计数跨 batch 保留——这正是
      修复点,使非活跃 channel 的在途读被持续追踪。
  4. 计数迁移完整性:VERIFIED

    • PrepareRead 在新旧代码中均仅有 RemoteFetchRank 两个调用点,
      无其它调用方依赖被删除的 sqReadCount_ 自增。
    • hcomm_ 的读请求仅经 PrepareRead 下发,全部被计数覆盖。
  5. 同步正确性:CORRECT

    • Init 中 Duplicate(PIPE_V) 后紧跟 SyncFuncHardEvent::V_S 再做标量
      读写,方向正确;此后对该缓冲区只有标量访问(标量↔标量无需同步),
      其它向量操作不触碰该 buffer,无 hazard。
  6. UB 预算:UPDATED

    • rankReadCntBufSize 已计入 usedUb(engram_fetch_arch35.h:238),
      缓冲区 ≤ Ceil(slots*4, 32)*32,slots 最大约 1024(tb=1 时),约 4KB,
      开销可忽略。
  7. totalBlocks_ 缓存:SAFE

    • GetBlockNum() 在 kernel 生命周期内不变,Init 缓存一次安全;
      旧文件 4 处调用点全部替换,无残留(新文件仅剩 Init 中 1 处)。
  8. Batch 完整性(未被破坏):

    • 每个 RemoteFetchRank 末尾 preparedReadCount_ > 0 即 BatchCommit,
      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。仅浪费几十字节,
无正确性影响,可不改。

五、总体结论

修复方案正确、完整:

  • 单一标量计数在 channel 切换时清零的缺陷被"每 (core, channel) 槽位计数"
    取代,索引在两种核分配模式下均可证明不越界,slot 与 channel 一一对应。
  • 计数迁移无遗漏调用点,UB 预算、同步、batch 复用约束均未被破坏。
  • 未发现新引入的 bug 或行为回归。
    ================================================================================
likedislike
Pull Request已成功合入, 合并人@CANN-robot
(感谢 wuchenhao123 的贡献)
wuchenhao123wuchenhao123成员
3 天前 创建了 pull request,commit 5e8d4a83
atomgit-bot
atomgit-bot
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:

likedislike
不准确?
CANN-robotCANN-robot成员
3 天前 添加了label:cann-cla/yes
CANN-robot
CANN-robot成员
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 /approve or /lgtm
  • Commenting /approve implies 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. 👍

likedislike
CANN-robot
CANN-robot成员
3 天前 评论:

CLA Signature Pass

wuchenhao123, thanks for your pull request. All authors of the commits have signed the CLA. 👍

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

/compile

likedislike
wuchenhao123wuchenhao123成员
3 天前 预合并成功(commit_id: 209857ade85aceaa8efe3de198780a70e08db0a9)
wuchenhao123
wuchenhao123成员
3 天前 评论:

/ai review

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

代码审查

✅ 未发现问题


🧩 本次 Review 已使用自定义 Skill:

likedislike
不准确?
CANN-robot
CANN-robot成员
3 天前 评论:
🚀 CI 流水线已启动
📋 执行详情: 点击查看流水线
likedislike
CANN-robotCANN-robot成员
3 天前 添加了label:ci-pipeline-running
此处折叠了5条事件消息 查看更多
wuchenhao123wuchenhao123成员
3 天前 修改了pull request 的描述
wang-minbo成员
3 天前 评论:

/lgtm
/approve

likedislike
CANN-robotCANN-robot成员
3 天前 添加了label:approved
chenjianjun11成员
3 天前 评论:

/lgtm

likedislike
CANN-robotCANN-robot成员
3 天前 添加了label:lgtm
CANN-robotCANN-robot成员
3 天前 关闭了关联的issue
CANN-robotCANN-robot成员
3 天前 合入了pull request