Pull Request已成功合入, 合并人@CANN-robot
(感谢 林旭 的贡献)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
PR Approval Progress
✅ Congratulations! All modules have met the lgtm and approve requirements.
Module Approval Details
| module | lgtm status | approve status |
|---|---|---|
| repo-cann/ops-tensor | ✅ 陈琦, 陈康 (2/2) | ✅ 陈琦 (1/1) |
💡 Tip:
- Committer can comment
/approveor/lgtm- Commenting
/approveimplies both code review (lgtm) and intent to merge (approve)
CLA Signature Pass
LINxu233, thanks for your pull request. All authors of the commits have signed the CLA. 👍


变更摘要
此 PR 对 GEMM 库中的 Block Scheduler、Block MMAD 和 Kernel 层进行了较大范围的重构,主要围绕 basic 和 streamk 两种调度策略展开。核心改动包括:引入蛇形遍历(snake-scan)的 tile 索引逻辑以提升缓存效率、在 common_utils.h 中新增窗口长度和 tile 索引相关常量、重构 BlockSchedulerMatmulStreamK 和 BlockSchedulerMatmulBasic 的 tile 分配与坐标计算方式、调整 BlockMmad 的 Compute 接口签名使其支持 workspace 张量和 SK 场景标记传递,以及统一 StreamK kernel 的 DP+SK 混合调度流程。此外,dispatch_policy.h 中的 MatmulMultiBlockBasic 新增了第三个模板参数以增强策略灵活性。
主要改动
-
Scheduler 重构(basic / streamk):
block_scheduler_matmul_basic.h和block_scheduler_matmul_streamk.h经历了大幅重写,tile 分配逻辑从简单的线性索引改为基于窗口(WINDOW_LEN)的蛇形扫描方案,偶数行反向遍历nTileIdx,GetBlockShape和GetBlockCoord的实现也随之调整。 -
common_utils.h新增常量与工具: 新增WINDOW_LEN = 4、BLOCK_BYTE_SIZE = 32、IDX_M_TILEIDX/IDX_N_TILEIDX等 tile 索引常量以及IDX_M_IDX/IDX_N_IDX/IDX_K_IDX维度索引常量,被 scheduler 和 epilogue 模块共同引用。 -
BlockMmad Compute 接口调整:
block_mmad_matmul_streamk.h和block_mmad_matmul_basic.h中的Compute方法签名发生变化,StreamK 版本的Compute增加了gmWorkSpace张量、K 坐标及isSkScene标志参数,以支持在 DP+SK 混合场景下正确传递累加所需的中间 workspace 信息。 -
Kernel 层调度流程统一:
kernel_matmul_streamk.h的 tile 遍历从blockNum步进改为usedCoreNum步进,并新增 SK 预取(preload)逻辑,使得 DP 阶段的 core 可以预先加载 SK 阶段的 tile;kernel_matmul_basic.h和kernel_batch_matmul_broadcast.h也做了对应的轻量调整。 -
Epilogue 与 DispatchPolicy 配套适配:
block_epilogue_matmul_streamk.h的Init方法参数列表发生变更,适配新的 scheduler 输出格式;dispatch_policy.h中MatmulMultiBlockBasic模板新增KernelSchedule_参数(默认KernelMmadMultiBlockBasic),使 basic 策略可复用于广播等变体。


代码审查
审查总结
本次 diff 涉及 32 个文件,是一次大规模的 API 重构(Arguments → Params 统一重命名、L1/L0 参数集中到 Params 结构体、调度器构造简化、L0C 双缓冲同步调整等),总计新增约 1628 行、删除约 1687 行。
审查结果:发现 8 个问题
P1(2 个):
block_scheduler_matmul_basic.h:192-213—GetBlockCoord丢失非连续场景mOffsetNonContiguous和 SplitK 场景kOffset坐标信息block_mmad_matmul_basic.h:149-217— L0C 双缓冲模式的 FIX_M/M_FIX 硬件同步被移除,存在数据竞争风险
P2(5 个):
block_scheduler_matmul_basic.h:71-73— 构造函数在blockNum_ <= 0时提前返回,对象部分初始化block_scheduler_matmul_streamk.h:47-49— 构造函数在usedCoreNum_ <= 0时提前返回,对象部分初始化block_scheduler_qbmm.h:83-85— 同上模式,构造函数提前返回block_scheduler_matmul_basic.h:95-175—isNdFormat_从运行时参数改为模板参数,非 ND 格式分支在默认实例化中成为死代码kernel_matmul_basic.h:18-19(含 kernel_matmul_streamk.h 和 kernel_batch_matmul_broadcast.h) — 移除ASCENDC_CUBE_ONLY宏和旧版工具链条件编译
P3(1 个):
kernel_matmul_basic.h:169-172—UnsetHf32无条件调用与 StreamK kernel 的条件判断不一致
各文件审查确认
| 文件 | 结论 |
|---|---|
| docs/API/epilogue/README.md | 无问题 |
| docs/API/epilogue/block/block_epilogue.md | 无问题 |
| docs/API/epilogue/block/block_epilogue_empty.md | 无问题 |
| docs/API/epilogue/block/block_epilogue_matmul_streamk.md | 无问题 |
| docs/API/gemm/block/README.md | 无问题 |
| docs/API/gemm/block/block_mmad.md | 无问题 |
| docs/API/gemm/block/block_mmad_matmul_basic.md | 无问题 |
| docs/API/gemm/block/block_mmad_matmul_streamk.md | 无问题 |
| docs/API/gemm/block/block_mmad_qbmm_mx.md | 无问题 |
| docs/API/gemm/block/block_scheduler.md | 无问题 |
| docs/API/gemm/block/block_scheduler_matmul_basic.md | 无问题 |
| docs/API/gemm/block/block_scheduler_matmul_streamk.md | 无问题 |
| docs/API/gemm/kernel/README.md | 无问题 |
| docs/API/gemm/kernel/kernel.md | 无问题 |
| docs/API/gemm/kernel/kernel_matmul_basic.md | 无问题 |
| docs/API/gemm/kernel/kernel_matmul_streamk.md | 无问题 |
| include/blaze/epilogue/block/block_epilogue_empty.h | 无问题 |
| include/blaze/epilogue/block/block_epilogue_matmul_streamk.h | 无问题 |
| include/blaze/epilogue/fusion/default_fusion_op.h | 无问题 |
| include/blaze/gemm/block/block_mmad_a8w8_fixpipe_quant.h | 无问题 |
| include/blaze/gemm/block/block_mmad_matmul_basic.h | 发现问题 (P1 × 1) |
| include/blaze/gemm/block/block_mmad_matmul_streamk.h | 无独立问题 |
| include/blaze/gemm/block/block_scheduler_matmul_basic.h | 发现问题 (P1 × 1, P2 × 2) |
| include/blaze/gemm/block/block_scheduler_matmul_streamk.h | 发现问题 (P2 × 1) |
| include/blaze/gemm/block/block_scheduler_qbmm.h | 发现问题 (P2 × 1) |
| include/blaze/gemm/kernel/kernel_batch_matmul_broadcast.h | 无独立问题 |
| include/blaze/gemm/kernel/kernel_matmul_basic.h | 发现问题 (P2 × 1, P3 × 1) |
| include/blaze/gemm/kernel/kernel_matmul_streamk.h | 无独立问题 |
| include/blaze/gemm/kernel/kernel_qbmm_cube.h | 无问题 |
| include/blaze/gemm/kernel/kernel_qbmm_mx.h | 无问题 |
| include/blaze/gemm/policy/dispatch_policy.h | 无问题 |
| include/blaze/gemm/utils/common_utils.h | 无问题 |
整体风险评估
中等风险。主要关注点:L0C 双缓冲同步移除可能导致特定配置下的结果错误;GetBlockCoord 坐标信息丢失影响非连续格式和 SplitK 场景;三个调度器的构造函数提前返回模式是潜在的健壮性隐患。文档变更均为 API 同步更新,无安全风险。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 0 |
| 🟡 建议 | 5 |
⛔ 需要修改


🟡 Medium Priority
证据链:
建议:统一 L2 Cache 在大矩阵场景下的建议。两种修复方向:(A)若大矩阵应禁用 L2 Cache(与 StreamK 文档一致),将第389行改为"禁用 L2 Cache,增大 tile 尺寸";(B)若 Basic 调度器大矩阵应启用 L2 Cache,将第148行 ALL_L2_CACHE_DISABLE 的场景恢复为"小矩阵场景"。需要结合实际代码逻辑确认正确方向。


🔵 Low Priority
变更行(第43行):Params 结构体中 isHf32 字段的注释为 // ub默认不开db为1。
证据链:
- 对应源代码
include/blaze/gemm/block/block_scheduler_matmul_basic.h第46行注释为// HF32开启标志(HF32 enable flag) - 文档中的注释 "ub默认不开db为1" 含义不明确,看起来像是编辑过程中残留的碎片文本(可能是 "UB默认不开双缓冲" 之类的片段)
- 该注释与字段实际含义(HF32模式开关)完全无关,无法为读者提供有效信息
影响:读者看到 "ub默认不开db为1" 会感到困惑,不知道这个参数的真实用途。isHf32 控制 HF32 计算模式的开关(见文档第128-136行的专项说明),注释应反映这一含义。
修复方案:将注释修改为与源代码一致的 // HF32开启标志,或使用更清晰的描述如 // HF32 模式标志(0=关闭, 1=开启)。
建议:将 isHf32 字段的注释修改为与源代码一致的 // HF32开启标志。


🟡 Medium Priority
变更行(第45-47行):Params 结构体中的注释使用了 "鞧连续"(如 // 鞧连续场景m轴、// 鞧连续场景m轴stride)。
证据链:
- 对应源代码
include/blaze/gemm/block/block_scheduler_matmul_basic.h第48-50行正确使用了 "非连续"(如// 非连续场景m轴) - "鞧"(读作 qiū,意为皮革带)是一个罕见汉字,此处明显是 "非连续"(non-contiguous)的 UTF-8 字节序列被错误解码后的结果
- 该字符编码损坏发生在文档的三处注释中(第45、46、47行)
影响:用户阅读文档时无法理解 "鞧连续场景" 的含义,会误以为这是某个专用术语。由于 sliceM/srcNdStride/innerBatch 这几个参数与非连续(非 ND 连续格式)矩阵场景密切相关,注释含义完全无法从损坏后的文字中推断,可能导致用户错误配置参数。
修复方案:将三处 "鞧连续" 替换为 "非连续"。
|
47 | + uint32_t sliceM; // 非连续场景m轴 |
|
48 | + uint32_t srcNdStride; // 非连续场景m轴stride |
| 47
| - uint32_t innerBatch = 1; // |
|
49 | + uint32_t innerBatch = 1; // 非连续transpose场景内轴batch值 |


🟡 Medium Priority
变更行(第159行):表格中 innerBatch 参数的描述为 "非 transpose 场景内轴 batch",而适用场景列为 "transpose 场景"。
证据链:
- 源代码
include/blaze/gemm/block/block_scheduler_matmul_basic.h第50行注释为// 非连续transpose场景内轴batch值,意为"非连续格式下的转置场景内轴 batch 值" - 文档描述丢失了关键的 "非连续" 修饰语,并将 "transpose" 误改为 "非 transpose"(non-transpose)
- 表格中描述列说 "非 transpose 场景",场景列却说 "transpose 场景"——两者直接矛盾
影响:读者无法判断 innerBatch 究竟是用于 transpose 场景还是非 transpose 场景。根据源码注释,该参数的正确用途是:在非连续(非 ND)格式的 transpose 场景中设置内轴 batch 值。文档的描述和场景产生了自相矛盾,可能导致参数配置错误。
修复方案:将描述修改为 "非连续场景 transpose 内轴 batch",与源代码注释含义一致。
建议:将 innerBatch 的描述从 "非 transpose 场景内轴 batch" 改为 "非连续场景 transpose 内轴 batch"。
| 159
| - | innerBatch | 非 transpose |
|
159 | + | innerBatch | 非连续场景 transpose 内轴 batch | transpose 场景 | |


🟡 Medium Priority
变更行(第228-234行):block_mmad_matmul_streamk.md 的 Params 初始化示例使用位置初始化,但参数顺序错误。
证据链:
- 源代码
include/blaze/gemm/block/block_mmad_matmul_streamk.h第58-73行 Params 结构体字段顺序为:- aGmAddr, 2. bGmAddr, 3. cGmAddr, 4. biasGmAddr, 5. groupListGmAddr, 6. workspaceGmAddr
- 第5个位置参数
workspaceGM(意为 Workspace GM 地址)实际被赋给了第5个字段groupListGmAddr(GroupList 地址,预留扩展),而非预期的第6个字段workspaceGmAddr workspaceGmAddr使用默认值nullptr,导致 StreamK 模式下 Workspace 输出目标为空
影响:用户按此示例代码编写初始化逻辑后,StreamK 模式的 workspace 输出地址为 nullptr,可能导致运行时数据写入空地址,引发计算错误或程序崩溃。这是文档中的误导性代码示例,且 StreamK 场景下 workspaceGmAddr 是必需的关键参数。
修复方案:改用指定初始化器(designated initializers),与 Basic 文档示例风格保持一致:
建议:将示例代码从位置初始化改为指定初始化器,确保 workspaceGmAddr 字段被正确赋值:.workspaceGmAddr = workspaceGM。
|
234 | + BlockMmad::Params params = { |
|
235 | + .aGmAddr = aGM, // A 矩阵 GM 地址 |
|
236 | + .bGmAddr = bGM, // B 矩阵 GM 地址 |
|
237 | + .cGmAddr = cGM, // C 矩阵 GM 地址(DP 模式) |
|
238 | + .biasGmAddr = biasGM, // Bias GM 地址(nullptr 表示无 bias) |
|
239 | + .workspaceGmAddr = workspaceGM // Workspace GM 地址(SK 模式) |
| 234
240 | }; |


compile


流水线任务触发成功
任务链接 [9bfd67170c144c2e9e960d3f9336018d][流水线指导]
| 任务名称 | 状态 | 日志 | 下载链接 |
|---|---|---|---|
| Compile_Ascend_X86 | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_ARM | ✅ SUCCESS | >>>>> | >>>>> |
| codecheck | ✅ SUCCESS | >>>>> | |
| SCA | ✅ SUCCESS | >>>>> | |
| antipoison | ✅ SUCCESS | >>>>> | |
| Check_Pr | ✅ SUCCESS | >>>>> | |
| pre_comment | ✅ SUCCESS | >>>>> | |
| Compile_Ascend_X86_ubuntu24 | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_ARM_ubuntu24 | ✅ SUCCESS | >>>>> | >>>>> |
| codecheck_codestyle | ⚠️ WARNING | >>>>> | |
| precommit | ✅ SUCCESS | >>>>> |
[2026-06-25 23:32:43] CI执行结束


/lgtm


描述
1、修改scheduler params 定义和使用,同步修改init接口,只传入params和shape
2、修改blockMmad params定义和使用,同步修改init接口,只传入params和shape
3、移除scheduler无用接口和成员变量,整改public\private,部分变量调整为私有变量
4、AscendC::LOA_SIZE类似的ai_core only的函数整改,放到aicore函数内部
5、AuxGetL0C整改为C0_Element函数,AscendC::Te作用域。
6、Mmad的operator超大函数重构为CopyGm2L1,CopyL12L0,Compute三个小接口;
详细说明:
本次 PR 对 BlockScheduler 和 BlockMmad 两大核心组件进行了系统性重构,涉及 Basic 和 StreamK 两种矩阵乘调度策略。
重构的核心方向是将公共常量/工具集中到 common_utils.h,简化 BlockScheduler 的模板参数与调用接口,
同时增强 BlockMmad 的计算管线能力(如 L0C ping-pong 双缓冲、Bias 支持)以及引入更灵活的分派策略模板参数。
变更共涉及 31 个文件,整体代码行数净减少约 74 行。
主要改动
BlockScheduler 接口精简:BlockSchedulerMatmulBasic 移除了部分冗余模板参数,
删除了原有的 isFp32_、isNdFormat_ 特化相关的 GetBlockShape 重载,统一由单一接口返回六元组 BlockL1L0Shape(含 mL0/nL0);
BlockSchedulerMatmulStreamK 同步精简,移除未使用的 K 切分遗留代码,最终调度逻辑更清晰。
BlockMmad 计算管线增强:BlockMmadMatmulBasic 新增 L0C ping-pong 双缓冲机制(enableL0cPingPong_、l0cPingPong_),
Bias 搬运路径增加 btBufId 参数以适配 L0C 双缓冲场景;
BlockMmadMatmulStreamK 重构为完整的 CopyL1FromGM → CopyL0FromL1 → Compute 三段式管线,
支持 SK 场景下的 workspace 输出和 Bias 处理,代码结构更加模块化。
分派策略模板扩展:MatmulMultiBlockBasic 新增模板参数 KernelSchedule_(默认 KernelMmadMultiBlockBasic),
使得同一套 Basic 模板可被 KernelMmadMultiBlockBmmBroadcast 等不同调度类型复用,消除批处理广播场景对独立调度策略的依赖。
公共常量集中管理:common_utils.h 新增 DIMENSION_M/N/K、ZERO_FLAG~SEVENTH_FLAG、
FINAL_ACCUMULATION/NON_FINAL_ACCUMULATION、C0_SIZE_fp16/fp32/B8/B4/L0C 等常量,
原先分散在各 mmad 实现文件中的魔数被统一收拢,减少重复定义。
Kernel 层适配:kernel_matmul_basic.h 与 kernel_matmul_streamk.h 均适配了新的 Scheduler/Mmad 接口签名,
Basic 路径使用 TupleL1L0Shape 六元组调度,StreamK 路径围绕新的 GetSingleCoreShape/GetSingleCoreCoord/GetCurKSingleCore/CheckIsSkScene
接口重构了 Tile 迭代与 AIC/AIV 同步逻辑。
关联的Issue
https://gitcode.com/cann/ops-tensor/issues/10
测试
1、测试MM用例 basic、streamK模板
2、测试BMM用例
文档更新
已更新
类型标签