Kernel Matmul Basic
功能说明
基础矩阵乘 Kernel,仅支持 AIC 计算,无 AIV 参与,不支持 workspace。适用于小矩阵、简单计算场景,集成 BlockScheduler 调度、BlockMmad 计算和 BlockEpilogueEmpty 后处理组件。
继承自:GemmUniversal 基础模板(特化实现)
特殊约束
BlockEpilogue 限制
仅支持 Block::BlockEpilogueEmpty,不支持任何后处理操作。
using BlockEpilogue = Blaze::Gemm::Block::BlockEpilogueEmpty;
计算模式
仅在 AIC 核函数中执行,不支持 AIV 计算(AIV 核直接返回)。
if ASCEND_IS_AIV {
return; // AIV 核直接返回,不执行任何计算
}
Workspace 不支持
不支持 workspace,无法存储中间结果,适用于完整 tile 计算场景。
非连续输入
不支持带 stride 的非连续输入(仅支持连续 ND/NZ layout)。
FP32 大 K
不支持 FP32 大 K 场景(K 轴切分受硬件限制),K 值过大时需使用 StreamK Kernel。
类型别名
| 类型 | 说明 |
|---|---|
| BlockMmad | BlockMmadMatmulBasic 组件 |
| ProblemShape | 问题规模类型:Shape<int64_t, int64_t, int64_t, int64_t> |
| BlockScheduler | BlockSchedulerMatmulBasic 组件 |
| BlockEpilogue | BlockEpilogueEmpty 组件 |
| BlockMmadParams | BlockMmad::Params |
| BlockEpilogueParams | BlockEpilogue::Params |
| BlockSchedulerParams | BlockScheduler::Params |
| AType | A 矩阵数据类型 |
| BType | B 矩阵数据类型 |
| CType | C 矩阵输出类型 |
| BiasType | Bias 数据类型 |
| LayoutA | A 矩阵布局类型 |
| LayoutB | B 矩阵布局类型 |
| LayoutC | C 矩阵布局类型 |
| LayoutBias | Bias 布局类型 |
静态常量
| 常量 | 说明 |
|---|---|
| isFp32 | 是否为 FP32 类型 |
| C0_SIZE | Cube 单元大小(FP32=16, FP16=32) |
| transA | A 矩阵是否转置 |
| transB | B 矩阵是否转置 |
| weightNZFormat | B 矩阵是否为 NZ 格式 |
Params 参数结构
结构定义
struct Params {
ProblemShape problemShape; // 问题规模 (m, n, k, batch)
BlockMmadParams mmadParams; // BlockMmad 参数
BlockEpilogueParams epilogueParams; // BlockEpilogue 参数(Empty 无需设置)
BlockSchedulerParams schParams; // BlockScheduler 参数
};
参数详解
ProblemShape 参数
| 参数 | 类型 | 说明 | 示例 |
|---|---|---|---|
| m | int64_t | M 轴尺寸 | 1024 |
| n | int64_t | N 轴尺寸 | 1024 |
| k | int64_t | K 轴尺寸 | 512 |
| batch | int64_t | Batch 数量(0 或 1 为单 batch) | 1 |
BlockMmad 参数
详见 BlockMmadMatmulBasic Params
BlockScheduler 参数
详见 BlockSchedulerMatmulBasic Params
BlockEpilogue 参数
Empty Epilogue 无需设置参数。
公共成员方法(Public API)
构造函数
__aicore__ inline GemmUniversal()
功能:构造 GemmUniversal(KernelMatmulBasic)对象。
析构函数
__aicore__ inline ~GemmUniversal()
功能:析构 GemmUniversal(KernelMatmulBasic)对象。
operator函数
__aicore__ inline void operator()(Params const& params)
功能:执行基础矩阵乘 Kernel 计算。 执行流程:
AIV 核检查:直接返回
↓
Init:设置问题规模、GM 地址
↓
BlockScheduler 初始化
↓
Block 索引检查:超出实际数量则返回
↓
HF32 模式设置(可选)
↓
BlockMmad 初始化
↓
创建 GM Tensor (ND/NZ layout)
↓
SetL2Cache:配置 L2 Cache(可选)
↓
遍历 tile → BlockMmad 执行(每个 tile 独立计算)
↓
UnsetHf32:关闭 HF32 模式
Tile 循环策略
Basic 特有的循环策略
for (int64_t tileIdx = curBlockIdx; tileIdx < tileNum; tileIdx += blockNum) {
// 每个 block 处理 tileIdx = curBlockIdx, curBlockIdx + blockNum, curBlockIdx + 2*blockNum, ...
// 多 block 并行处理不同 tile
// 每个 tile 独立调用 BlockMmad 执行矩阵乘
}
说明:
- 简单 stride 策略:block 按固定 stride(blockNum)遍历 tile
- 无 workspace:每个 tile 完整计算,不依赖中间结果
- 无 AIC-AIV 同步:单核计算,无需跨核同步
调用示例
Kernel 组装与调用
// ============== 1. 类型定义 ==============
using AType = half; // A 矩阵数据类型
using BType = half; // B 矩阵数据类型
using CType = half; // C 矩阵输出类型
using BiasType = half; // Bias 数据类型(可选)
using LayoutA = AscendC::Te::NZLayoutPtn; // A 矩阵布局(NZ/ND)
using LayoutB = AscendC::Te::NZLayoutPtn; // B 矩阵布局(NZ/ND)
using LayoutC = AscendC::Te::NDLayoutPtn; // C 矩阵布局(ND)
using LayoutBias = LayoutC; // Bias 布局
// ============== 2. ProblemShape 定义 ==============
// 形状:(m, n, k, batch),batch=0 或 1 表示单 batch
using ProblemShape = AscendC::Te::Shape<int64_t, int64_t, int64_t, int64_t>;
// ============== 3. BlockScheduler 组装 ==============
// FullLoadMode: 0=非全载(默认), 1=A全载, 2=B全载
constexpr int64_t FULL_LOAD_MODE = 0;
using BlockScheduler = Blaze::Gemm::Block::BlockSchedulerMatmulBasic<ProblemShape, FULL_LOAD_MODE>;
// ============== 4. BlockMmad 组装 ==============
// DispatchPolicy: 调度策略,FusedOpType: 融合操作类型
constexpr uint64_t FUSED_OP_TYPE = 0;
using DispatchPolicy = Blaze::Gemm::MatmulMultiBlockBasic<FULL_LOAD_MODE, FUSED_OP_TYPE>;
using BlockMmad = Blaze::Gemm::Block::BlockMmad<
DispatchPolicy, AType, LayoutA,
BType, LayoutB, CType, LayoutC,
BiasType, LayoutBias>;
// ============== 5. BlockEpilogue 组装 ==============
// Basic Kernel 仅支持 Empty,不支持后处理
using BlockEpilogue = Blaze::Gemm::Block::BlockEpilogueEmpty;
// ============== 6. Kernel 组装 ==============
using MatmulKernel = Blaze::Gemm::Kernel::GemmUniversal<
ProblemShape, BlockMmad, BlockEpilogue, BlockScheduler>;
// ============== 7. Params 构造 ==============
using Params = typename MatmulKernel::Params;
Params params;
// --- ProblemShape 参数 ---
params.problemShape = {m, n, k, batch}; // (M, N, K, Batch)
// --- BlockMmad 参数 ---
params.mmadParams.aGmAddr = aGM; // A 矩阵 GM 地址
params.mmadParams.bGmAddr = bGM; // B 矩阵 GM 地址
params.mmadParams.cGmAddr = cGM; // C 矩阵 GM 地址
params.mmadParams.biasGmAddr = biasGM; // Bias GM 地址(可选,nullptr 表示无 bias)
params.mmadParams.ml1 = 256; // L1 M 维度尺寸
params.mmadParams.nl1 = 256; // L1 N 维度尺寸
params.mmadParams.kl1 = 128; // L1 K 维度尺寸
params.mmadParams.ml0 = 128; // L0 M 维度尺寸
params.mmadParams.nl0 = 128; // L0 N 维度尺寸
params.mmadParams.kl0 = 64; // L0 K 维度尺寸
params.mmadParams.l1Stages = 2; // L1 缓冲数量(双缓冲)
params.mmadParams.l0cStages = 1; // L0C 缓冲数量(单缓冲)
// --- BlockScheduler 参数 ---
params.schParams.mL1 = 256; // M 轴 L1 tile 尺寸
params.schParams.nL1 = 256; // N 轴 L1 tile 尺寸
params.schParams.kL1 = 128; // K 轴 L1 tile 尺寸
params.schParams.baseM = 128; // M 轴 L0 base 尺寸
params.schParams.baseN = 128; // N 轴 L0 base 尺寸
params.schParams.baseK = 64; // K 轴 L0 base 尺寸
params.schParams.mTailCnt = 2; // M 轴尾块切分数量(Batch=1 场景)
params.schParams.nTailCnt = 2; // N 轴尾块切分数量(Batch=1 场景)
params.schParams.isHf32 = 0; // HF32 模式标志(0=关闭)
params.schParams.l2CacheMode = Blaze::Gemm::L2_CACHE_DEFAULT; // L2Cache 使能
// --- BlockEpilogue 参数 ---
// Empty Epilogue 无需设置参数
params.epilogueParams = {};
// ============== 8. Kernel 调用 ==============
MatmulKernel mm;
mm(params); // 执行矩阵乘计算
常用配置示例
小矩阵场景:
params.schParams.mL1 = 128;
params.schParams.nL1 = 128;
params.schParams.kL1 = 64;
params.schParams.baseM = 64;
params.schParams.baseN = 64;
params.schParams.baseK = 32;
params.mmadParams.l1Stages = 1; // 单缓冲
params.mmadParams.l0cStages = 1;
大矩阵场景:
params.schParams.mL1 = 256;
params.schParams.nL1 = 256;
params.schParams.kL1 = 128;
params.schParams.baseM = 128;
params.schParams.baseN = 128;
params.schParams.baseK = 64;
params.mmadParams.l1Stages = 2; // 双缓冲
params.mmadParams.l0cStages = 1;
params.schParams.l2CacheMode = Blaze::Gemm::ALL_L2_CACHE_DISABLE;
尾块优化场景(Batch=1):
params.schParams.mTailCnt = 4; // 尾块切为 4×4 = 16 份
params.schParams.nTailCnt = 4; // 16 个 Block 并行处理尾块
数据流
存储层次
GM (A/B/Bias) → BlockScheduler (tile 切分) → L1 (多缓冲) → L0A/L0B (双缓冲) → L0C (单缓冲或双缓冲) → GM (C)
Kernel 执行流程
BlockScheduler 初始化
↓
获取 tile 数量和形状 (L1/L0 tile)
↓
HF32 模式设置(可选)
↓
BlockMmad 初始化 (设置缓冲策略)
↓
创建 GM Tensor (ND/NZ layout)
↓
配置 L2 Cache (可选)
↓
遍历 tile → BlockMmad 执行 (每个 tile 独立计算)
↓
清理 (关闭 HF32)
性能优化建议
L2 Cache 配置
- 大矩阵场景:建议禁用 L2 Cache 避免缓存污染(
ALL_L2_CACHE_DISABLE) - 小矩阵场景:可保留 L2 Cache 提升数据复用(
L2_CACHE_DEFAULT)
L1/L0 缓冲配置
- 小矩阵场景:使用单缓冲(
l1Stages=1, l0cStages=1) - 中等矩阵场景:使用双缓冲(
l1Stages=2, l0cStages=1) - 大矩阵场景:使用四缓冲(
l1Stages=4, l0cStages=2)
Bias 预处理
- 常量 bias:可预先处理减少运行时开销
- 动态 bias:保持实时加载
NZ 格式优化
- 权重矩阵(B):优先使用 NZ 格式,提升 L1/L0 搬运效率
- 激活矩阵(A):使用 ND 格式即可
K 轴切分
kL1和baseK应根据数据局部性和复用率优化- 避免 K 轴切分过于细碎导致搬运开销增加
尾块优化(Batch=1 场景)
- 设置
mTailCnt和nTailCnt提高尾块并行度 - 建议值:2~4
适用场景
- 小矩阵:(m × n × k) 较小时,Basic Kernel 更高效
- 简单计算:无复杂后处理需求时,Basic Kernel 足够
- 单核场景:仅需 AIC 计算时,Basic Kernel 更简洁