为了实现多核并行,提升计算效率,需要将矩阵数据进行切分,分配到不同的核上进行处理。主要的切分策略有切分K轴和不切分K轴两种。
不切分K轴、仅切分M、N轴的策略如下:
比如,下图中共有8个核参与计算,将A矩阵沿着M轴划分为4块,将B矩阵沿着N轴切分为两块,单核上仅处理某一分块(比如图中绿色部分为core5上参与计算的数据):SingleCoreM * K大小的A矩阵分块和SingleCoreN * K大小的B矩阵分块相乘得到SingleCoreM * SingleCoreN大小的C矩阵分块。
切分M、N、K轴的策略如下图所示:
比如下图中,C矩阵中的R矩阵块,是通过A1*B1+A2*B2+A3*B3累加得到的,其中,A1*B1、A2*B2、A3*B3可在多个核上并行计算。
SetDim设置当前AI处理器可用的核数,通过Tiling计算得到执行Matmul计算实际使用的核数,实际使用的核数小于等于AI处理器可用的核数。SetBlockDim按照实际使用的核数由用户进行配置。
多核处理Matmul矩阵计算场景。
无
该场景的关键代码示例如下。Matmul多核对齐场景的完整样例请参考:多核切M、N的样例:Matmul多核Kernel直调样例;多核切K的样例:多核切K场景的算子样例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// 构造多核Tiling对象 auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(socVersion); matmul_tiling::MultiCoreMatmulTiling cubeTiling(*ascendcPlatform); // 仅包含Cube计算的算子,设置可参与矩阵乘运算的核数为当前AI处理器上的Cube核数 cubeTiling.SetDim(ascendcPlatform.GetCoreNumAic()); cubeTiling.SetAType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT16); cubeTiling.SetBType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT16); cubeTiling.SetCType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT); cubeTiling.SetBiasType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT); cubeTiling.SetOrgShape(M, N, K); cubeTiling.SetShape(M, N, K); cubeTiling.EnableBias(isBias); optiling::TCubeTiling tilingData; // 获取Tiling参数 int ret = tiling.GetTiling(tilingData); // if ret = -1, gen tiling failed |