Matmul High-Level API Enabling MDL Template

Case Study

This case shows the optimized operator performance when the MDL template is enabled in the matrix multiplication of the high-level Matmul API in the matrix multiplication operator scenario. In the MDL template, the data movement from the global memory to A1/B1 in the MTE2 pipeline is a one-time large-packet transfer. That is, multiple basic blocks of Matmul computation can be transferred into the A1/B1 at a time, improving the bandwidth utilization. In this way, the subsequent MTE1 pipeline can reuse the cached data of the basic blocks in A1/B1 as much as possible, reducing the number of MTE2 transfers. For details about the MDL template, see MatmulConfig.

The operator specifications are as follows.

Table 1 Operator specifications

Input

Shape

Data Type

Format

a

128, 1024

float16

ND

b

1024, 30720

float16

ND

The AI Processor used in this case has 24 cores, each of which contains one AIC and two AIVs.

The tiling parameters are as follows:

Obtaining Profile Data

Use the msProf tool to obtain the Operator Simulation Pipeline and On-board Profiling data. The MDL template mainly optimizes the MTE2 transfer efficiency, and therefore the focus is on analyzing the MTE2 pipeline.

Analyzing Main Bottlenecks

Developing Optimization Solutions

The following figure shows the Matmul computation pipeline of the default Norm template. MTE2 transfers basic blocks from the global memory to A1 or B1 for multiple times, with only one basic block transferred at a time. The advantage of the Norm template is that it has a small startup overhead and can start the MTE1 pipeline in advance. The disadvantage of the Norm template is that in large-shape scenarios, MTE2 transfers data for multiple times, resulting in low transfer bandwidth utilization and high overall performance overhead.

Figure 1 Pipeline of the default Norm template

The procedure for implementing the Norm template is as follows:

  1. Create a Matmul object and use the default Norm template parameter CFG_NORM.

    1
    2
    3
    4
    5
    6
    7
    8
    #define 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; // Use CFG_NORM to define the Matmul object.
    

The following figure shows the Matmul computation pipeline of the MDL template. MTE2 transfers multiple basic blocks from the global memory to A1 or B1 at a time. Each time, stepM × stepKa basic blocks are transferred to A1 or stepN × stepKb basic blocks are transferred to B1. The advantage of the MDL template is that MTE2 transfers multiple basic blocks at a time, achieving high bandwidth utilization. The subsequent MTE1 pipeline can reuse the cached data in A1 or B1 as much as possible, reducing the number of repeated transfers by MTE2. The disadvantage of the MDL template is that the MTE2 header overhead time is long. The MTE1 pipeline can be started only after the MTE2 pipeline is complete, resulting in a late start time of MTE1.

Figure 2 Pipeline of the MDL template

For details about the complete example of enabling the MDL template by using the Matmul API, see Matmul API performance optimization sample. The procedure for enabling the MDL template is as follows:

  1. Create a Matmul object and use the default MDL template parameter CFG_MDL.

    1
    2
    3
    4
    5
    6
    7
    8
    #define 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_MDL> matmulObj; // Use CFG_MDL to define the Matmul object.
    

Verifying Optimization Benefits

Summary

The MDL template can be enabled in scenarios where the input shape is large, the number of MTE2 transfers is large, and the synchronization between MTE1 and MTE2 pipelines takes a long time. MTE2 can transfer multiple basic blocks from the global memory to A1 or B1 at a time. In this way, the subsequent MTE1 pipeline can reuse the cached data in A1 or B1 as much as possible, reducing the number of MTE2 transfers and improving operator performance.