Pull Request已成功合入, 合并人@CANN-robot
(感谢 pzyy00 的贡献)变更摘要
此 PR 修复了 SK(StreamK)算法中单核切 K 尾块的计算问题。主要将 FP32 场景下 split K 的触发判断从 BlockScheduler 构造函数移至 UpdateBlockK(原 UpdateSplitKIdx)方法中,并将判断条件从原有的 skKSingleCore_ > splitSingleK_ 改为基于常量阈值 FP32_SPLIT_K_THRESHOLD(2048) 的 realSingleCoreK_ >= FP32_SPLIT_K_THRESHOLD,同时为 splitSingleKRound_ 增加了 realSingleCoreK_ < splitSingleK_ 时的兜底保护,避免异常计算。调用方 kernel_matmul_streamk.h 同步更新了方法名。
主要改动
- Split K 触发逻辑延迟到运行时判断:将
isSplitSingleK_的设置从BlockScheduler构造函数移至UpdateBlockK(原UpdateSplitKIdx)方法中,确保判断时realSingleCoreK_等运行时参数已就绪,避免构造阶段使用未正确初始化的值导致尾块计算错误。 - Split K 判断条件改为固定阈值:引入常量
FP32_SPLIT_K_THRESHOLD = 2048,将原判断条件skKSingleCore_ > splitSingleK_替换为realSingleCoreK_ >= FP32_SPLIT_K_THRESHOLD,使 split K 的触发不依赖于动态的splitSingleK_,消除因参数变化导致的尾块划分异常。 splitSingleKRound_增加兜底保护:将splitSingleKRound_的计算从realSingleCoreK_ / splitSingleK_改为realSingleCoreK_ < splitSingleK_ ? 1 : (realSingleCoreK_ / splitSingleK_),防止realSingleCoreK_小于splitSingleK_时出现除零或结果为 0 的异常情况。- 方法重命名:
UpdateSplitKIdx重命名为UpdateBlockK,kernel_matmul_streamk.h中的调用方同步更新,使方法名更准确地反映其职责(更新 block K 相关状态而非仅更新 split K 索引)。


代码审查
审查总结
审查结果
| 文件 | 审查结论 |
|---|---|
matmul/common/cmct/kernel/kernel_matmul_streamk.h |
无独立问题(仅方法名重命名适配,由另一文件的问题覆盖) |
matmul/mat_mul_v3/op_kernel/arch35/block_scheduler_streamk.h |
发现 2 个问题 |
问题统计
| 优先级 | 数量 | 说明 |
|---|---|---|
| P0 | 1 | isSplitSingleK_ 在 blockMmadOp.Init() 调用前始终为 false,导致 split-K 模式下 C 矩阵累加丢失原子操作,造成数据竞争和精度错误 |
| P1 | 1 | UpdateBlockK 中 isSplitSingleK_ 只设 true 不设 false,跨 tile 时标记残留导致错误启用 split-K 逻辑 |
| P2 | 0 | — |
| P3 | 0 | — |
总体风险评估
高风险。P0 问题会导致 FP32 非 HF32 连续格式且 K ≥ 2048 场景下,split-K 的 C 矩阵累加失去原子保护,多 K 分片并发写入同一位置时产生数据竞争,计算结果不可信。P1 问题在 DP tile 与 SK tile 的 realSingleCoreK_ 跨越阈值时(如 k_ >= 2048 但 skKSingleCore_ < 2048)会触发错误的 K 分片参数计算。两个问题均需在上线前修复。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 2 |
| 🟡 建议 | 0 |
⛔ 需要修改


The following users do not have permission to comment /lgtm or /approve on any module in this PR:
商晓波


Pull Request 已合并或已关闭。
If you want to solve this problem, you can click here to do it in the FAQs.


描述
sk单核切k的basicapi模板存在尾核越界问题,只有在尾核的skSingleCore小于1024且其余核的skSingleCoreK大于或等于1024才会触发。针对sk模板切出的skSingleCoreK的非固定问题,将切k的标识位从block schedule层的初始化赋值改为针对realSingleCoreK_的比较进行设置
关联的Issue
https://gitcode.com/cann/ops-nn/issues/4064
测试
本地验证精度通过
文档更新
类型标签