General Matrix-Vector Multiplication, or GEMV, refers to a scenario in which matrix multiplication is performed on the left matrix A with shape (1, K) and a right matrix B with shape (K, N) in Matmul computation when M is 1. Matmul allows you to enable the GEMV mode by setting the data format of matrix A to VECTOR in the tiling process and on the kernel. In this way, the computation scenario where M is 1 can be efficiently processed. If the GEMV mode is disabled when M is 1, the M direction is processed as a non-alignment scenario during Matmul computation. Compared with the non-alignment processing mode, the GEMV mode moves less data and provides better performance.
The following uses Matmul with M = 1, K = 256, N = 32, and the data type of both the left and right matrices being half, as an example to illustrate the internal processing process of the Matmul API in GEMV mode.
When matrix A is moved from A1 to A2, the 1 x 256 vector is processed as a 16 x 16 matrix. The LoadData API is called to move the 16 x 16 fractal matrix at a time. The movement and matrix multiplication of matrix B are the same as those in basic scenarios, as shown in the following figure.
When matrix A is moved from A1 to A2, the 1 × 256 vector is processed as non-aligned matrix data. The M direction must be 32-byte aligned before the movement. The LoadData API is called to move a 16 × 16 fractal matrix each time, for a total of 16 times (K/16). As a result, the amount of moved data increases, and the performance is poorer than that in GEMV mode, as illustrated in the following figure.
Matrix multiplication is performed on matrix A (M = 1, K > 1) with the shape of (1, K). In other words, the input matrix A consists of vector data.
For a complete operator example, see matmul_gemv operator sample.
1 2 3 4 5 6 7 8 9 10 |
auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo()); matmul_tiling::MatmulApiTiling tiling(ascendcPlatform); // Call the API to set the format of matrix A to CubeFormat::VECTOR. tiling.SetAType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::VECTOR, matmul_tiling::DataType::DT_FLOAT16); tiling.SetBType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT16); tiling.SetCType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT); tiling.SetBiasType(AscendC::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT); ... // Other implementation details. optiling::TCubeTiling tilingData; int ret = tiling.GetTiling(tilingData); |
1 2 3 4 5 6 7 |
#include "lib/matmul_intf.h" using A_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::VECTOR, half>; using B_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, half>; using C_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, float>; using BIAS_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, float>; AscendC::Matmul<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE> mm; |