This case shows the optimized performance when the NBuffer33 template is enabled in the matrix multiplication of the high-level Matmul API. The implementation of the NBuffer33 template is as follows: Matrix A of single-core computing is divided into three 3x3 base blocks. The three 3x3 base blocks of matrix A are fully loaded and stored in the L1 buffer. Each time, the matrix multiplication is performed with the 3x1 base blocks of matrix B. In addition, the 3x1 base blocks of matrix B required for the next computation are concurrently moved into DoubleBuffer until the matrix multiplication in the singleCoreN direction is completed. In the MTE2 Bound scenario, the NBuffer33 algorithm is used for data tiling, staggering the movement pipeline, reducing the size of data moved at a time, and balancing the data traffic of MTE2 and FixPipe to achieve even bandwidth distribution between them. For details about the NBuffer33 template, see MatmulPolicy.
In the MTE2 Bound scenario, the NBuffer33 template can be enabled when the tiling parameters meet the restrictions.
The operator specifications are as follows.
|
Input |
Shape |
Data Type |
Format |
|---|---|---|---|
|
a |
256, 192 |
float16 |
ND |
|
b |
192, 512 |
float16 |
ND |
On the AI processor used in the current case, there are 24 cores in total, and the high-level API Matmul in CUBE_ONLY is enabled for the operator. The MDL template is used. The tiling parameters are as follows:
Use the msProf tool to obtain the Operator Simulation Pipeline and On-board Profiling data, and focus on analyzing Cube and FixPipe pipelines.
Enable the NBuffer33 template: Before calling the GetTiling API, call the SetMatmulConfigParams API to enable the NBuffer33 mode so that the obtained tiling information meets the requirements. Enable the NBuffer33 template when creating a Matmul object on the kernel side. For details about the complete example of enabling the NBuffer33 template, see operator sample of enabling the NBuffer33 template policy. The specific procedure is as follows:
1 2 3 4 5 6 7 8 |
matmul_tiling::MatmulConfigParams matmulConfigParams(1, false, Matmul_tiling::ScheduleType::N_BUFFER_33, /* NBuffer33 mode */ matmul_tiling::MatrixTraverse::NOSET, false); cubeTiling.SetMatmulConfigParams(matmulConfigParams); if (cubeTiling.GetTiling(tilingData) == -1) { std::cout << "Generate tiling failed." << std::endl; return {}; } |
1 2 3 4 5 6 7 |
AscendC::MatmulImpl< AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, aType>, AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, bType>, AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, cType>, AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, biasType>, CFG_MDL, AscendC::MatmulCallBackFunc<nullptr, nullptr, nullptr>, AscendC::Impl::Detail::NBuffer33MatmulPolicy> matmulObj; |


In the MTE2 Bound scenario, if the tiling parameters meet the condition that stepM, stepKa, and stepKb are less than or equal to 3, you can enable the NBuffer33 template to stagger the movement pipelines by splitting the matrix, reducing the size of data transferred at a time and balancing the data traffic between MTE2 and FixPipe.