Matmul高阶API使能纯Cube模式
案例介绍
本案例呈现了在矩阵乘算子场景中,使能Matmul高阶API的纯Cube模式对算子性能的提升效果。如下图所示,Matmul API默认使用MIX模式,即用户从AIV侧发起消息,通过消息通信框架中转消息后,在AIC侧执行Matmul计算。这套消息处理机制会带来额外的Scalar性能开销。相较于MIX模式,纯Cube模式可以直接跳过消息通信框架,完成Matmul计算,提升算子性能。
输入 |
Shape |
Data type |
Format |
---|---|---|---|
a |
128, 64 |
float16 |
ND |
b |
64, 30720 |
float16 |
ND |
当前案例使用的AI处理器共24个核,每个核中包含1个AIC核和2个AIV核。
Tiling参数如下:
- 原始shape:M=128, N=30720, K=64。
- 单核shape:
- MIX场景:按48个AIV核进行切分,singleCoreM=128,singleCoreN=640,singleCoreK=64。
- 纯Cube场景:按24个AIC核进行切分,singleCoreM=128,singleCoreN=1280,singleCoreK=64。
- 基本块shape:baseM=128,baseN=256,baseK=64。
- L1相关Tiling参数:stepM=1,stepN=1,stepKa=4,stepKb=4,depthA1=8,depthB1=8。
获取性能数据
使用msProf工具获取算子仿真流水图和上板Profiling数据。因为纯Cube模式主要优化Scalar流水性能,可以重点分析Scalar的流水情况。
分析主要瓶颈点
设计优化方案
默认MIX模式下,用户在AIV侧发起消息,通过消息通信框架中转消息后,在AIC侧执行Matmul计算。基于这样的流程,用户使用Matmul高阶API编写算子代码时,可以使用REGIST_MATMUL_OBJ宏,无需区分AIV和AIC,但也因这套消息处理机制导致产生了额外的性能开销,如图1 默认MIX模式的Matmul流程示意图所示。REGIST_MATMUL_OBJ的详细内容请参考REGIST_MATMUL_OBJ。
实现默认MIX模式的具体步骤如下:
- Kernel侧,定义Matmul对象。
1 2 3 4 5 6 7
#include "lib/matmul_intf.h" using A_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, AType>; using B_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, BType>; using C_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, CType>; using BIAS_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, BiasType>; AscendC::Matmul<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, CFG_NORM> matmulObj;
- Host侧,Matmul多核Tiling对象调用SetDim接口设置参与运算的核数。
1 2 3 4
auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); matmul_tiling::MultiCoreMatmulTiling cubeTiling(*ascendcPlatform); int32_t blockDim = ascendcPlatform->GetCoreNumAiv(); // MIX模式使用GetCoreNumAiv获取AI处理器可用的核数。 cubeTiling.SetDim(blockDim);
- 调用核函数,参考核函数定义和调用,设置核函数的blockDim参数配置。
1
matmul_custom_do(ascendcPlatform->GetCoreNumAic(), stream, x1, x2, bias, y, workspaceDevice, tilingDevice); // MIX模式下,启动时,按照AIV和AIC组合启动,blockDim用于设置启动多少个AI Core。
在没有矢量计算的算子场景下,可以跳过消息通信框架的机制,使能纯Cube模式完成Matmul计算,减少消息通信的性能开销,提升算子性能。

Matmul API使能纯Cube模式的完整样例请参考Matmul API性能优化样例。使能纯Cube模式的主要步骤如下:
- Kernel侧,在定义Matmul对象的代码中,包含matmul_intf.h头文件前设置ASCENDC_CUBE_ONLY宏。
1 2 3 4 5 6 7 8
#define ASCENDC_CUBE_ONLY // 在#include "lib/matmul_intf.h"前,设置ASCENDC_CUBE_ONLY宏 #include "lib/matmul_intf.h" using A_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, AType>; using B_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, BType>; using C_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, CType>; using BIAS_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, BiasType>; AscendC::Matmul<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, CFG_NORM> matmulObj;
- Host侧,Matmul多核Tiling对象调用SetDim接口设置参与运算的核数。
1 2 3 4
auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); matmul_tiling::MultiCoreMatmulTiling cubeTiling(*ascendcPlatform); int32_t blockDim = ascendcPlatform->GetCoreNumAic(); // 纯Cube模式使用GetCoreNumAic接口获取AI处理器可用的核数。 cubeTiling.SetDim(blockDim);
- 调用核函数,参考核函数定义和调用,设置核函数的blockDim参数配置。
1
matmul_custom_do(ascendcPlatform->GetCoreNumAic(), stream, x1, x2, bias, y, workspaceDevice, tilingDevice); // 仅包含Cube计算的算子,blockDim用于设置启动多少个AIC。
- Kernel侧,核函数实现中增加AIV侧返回分支。
1 2 3 4 5 6 7 8 9
extern "C" __global__ __aicore__ void matmul_custom(GM_ADDR a, GM_ADDR b, GM_ADDR bias, GM_ADDR c, GM_ADDR workspace, GM_ADDR tilingGm) { if (g_coreType == AscendC::AIV) { // 纯Cube模式,AIV侧直接return return; } ... // 其他代码 }
验证优化方案性能收益
总结
在只有矩阵计算,没有矢量计算的场景下,可以考虑使能纯Cube模式,优化Matmul计算中的消息通信性能开销,提升算子性能。