---
title: 对接KUPL MMA使能矩阵计算加速
description: "KUPL矩阵编程模块提供了诸如D=A*B+C形式的MMA接口，便于发挥鲲鹏硬件的矩阵算力。其设计理念是KUPL矩阵编程上层MMA接口通过C++模板库实现多种矩阵计算Ops，底层则使能鲲鹏硬件的矩阵算力进行加速，从而达到屏蔽用户感知底层硬件能力的情况下快速使能加速。相较于鲲鹏数学库KML_BLAS和加速算子库KuDNN而言，KUPL矩阵编程MMA只提供Kernel Level的接口，具体在Gemm算子场景开发者既可以通过直接调用数学库BLAS Gemm接口加速也可以通过调用KUPL MMA接口+矩阵分块等优化手段加速；然后在矩阵乘融合算子场景开发者只能通过KUPL MMA接口加速。KUPL矩阵编程具体接口介绍参考：《KUPL矩阵编程接口函数概念说明》(https://www.hikunpeng.com/document/detail/zh/kunpenghpcs/hpckit/devg/KunpengHPCKit_developer_104.html)。"
url: https://www.hikunpeng.com/document/detail/zh/kunpenghpcs/KunpengDeveloper/usermanual/topic_0000002566375881.html
sourcePath: /source/zh/kunpenghpcs/KunpengDeveloper/usermanual/topic_0000002566375881.html
indexId: 0a22a48cb6b80cd2da154f92230bc1dea04553ed636df507f2b63e4b51a3b27a78
---
# 对接KUPL MMA使能矩阵计算加速

KUPL矩阵编程模块提供了诸如D=A*B+C形式的MMA接口，便于发挥鲲鹏硬件的矩阵算力。其设计理念是KUPL矩阵编程上层MMA接口通过C++模板库实现多种矩阵计算Ops，底层则使能鲲鹏硬件的矩阵算力进行加速，从而达到屏蔽用户感知底层硬件能力的情况下快速使能加速。相较于鲲鹏数学库KML_BLAS和加速算子库KuDNN而言，KUPL矩阵编程MMA只提供Kernel Level的接口，具体在Gemm算子场景开发者既可以通过直接调用数学库BLAS Gemm接口加速也可以通过调用KUPL MMA接口+矩阵分块等优化手段加速；然后在矩阵乘融合算子场景开发者只能通过KUPL MMA接口加速。KUPL矩阵编程具体接口介绍参考：《KUPL矩阵编程接口函数概念说明》(https://www.hikunpeng.com/document/detail/zh/kunpenghpcs/hpckit/devg/KunpengHPCKit_developer_104.html)。

在此基于精度为Float64、Size为32*16*512的矩阵乘kernel算子为例，来介绍如何使用KUPL MMA接口来加速，具体代码示例如下：
```
#include "stdlib.h"
// 引用KUPL矩阵编程模块头文件并加载相应namespace
#include "kupl_mma.h"
using namespace kupl::tensor;
int main()
{
constexpr int MATRIX_M  = 32;
constexpr int MATRIX_N  = 16;
constexpr int MATRIX_K = 512;
double *data_a = (double *)malloc(sizeof(double) * MATRIX_M * MATRIX_K);
double *data_b = (double *)malloc(sizeof(double) * MATRIX_K * MATRIX_N);
double *data_c = (double *)malloc(sizeof(double) * MATRIX_M * MATRIX_N);
/*
创建KUPL Shape对象，用以描述计算矩阵的形状
如A矩阵的size为32*512，则KUPL Shape对象一维大小应设置成32(表示行数)、二维大小应设置成512(表示列数)
*/
auto shape_a = make_shape(Int<32>{}, Int<512>{});
auto shape_b = make_shape(Int<512>{}, Int<16>{});
auto shape_c = make_shape(Int<32>{}, Int<16>{});
/*
创建KUPL Stride对象，用以描述计算矩阵的各维度步长
如A矩阵是32*512大小的列主序矩阵，则KUPL Stride对象一维大小应设置成1(表示同一列相邻两行的元素在原始buffer中下标差值为1)、二维大小应设置成32(表示同一行相邻两列的元素在原始buffer中下标差值为32)
*/
auto stride_a = make_stride(Int<1>{}, Int<32>{});
auto stride_b = make_stride(Int<16>{}, Int<1>{});
auto stride_c = make_stride(Int<16>{}, Int<1>{});
/* 创建KUPL Layout对象，包含Shape和Stride信息 */
auto layout_a = make_layout(shape_a, stride_a);
auto layout_b = make_layout(shape_b, stride_b);
auto layout_c = make_layout(shape_c, stride_c);
/* 定义KUPL mma和store方法从而供后续mma和store接口调用 */
/*
基于底层Ops按照atom_shape进行各维度计算尺寸扩展，从而确实mma行为
如采用底层Ops为double精度下32x16x1的mma kernel，此处在M/N/K方向上atom_shape扩展分别为1/1/512，因此最终实现32x16x512的mma行为
*/
auto mma_atom_shape = make_shape(Int<1>{}, Int<1>{}, Int<1>{});
auto tiled_mma = make_tiled_mma(Ops<MMA_32x16x512_F64F64F64>{}, mma_atom_shape);
/*
基于底层Ops按照atom_shape进行各维度写回尺寸扩展，从而确定store行为
如采用底层Ops为double精度下32x16的矩阵store kernel，此处在M/N方向上atom_shape扩展分别为1/1，因此最终实现32x16的矩阵store行为
*/
auto store_atom_shape = make_shape(Int<1>{}, Int<1>{});
auto tile_store = make_tiled_store(Ops<STORE_32x16_F64>{}, store_atom_shape);
/* 创建KUPL tensor对象纳管用户矩阵buffer */
auto tensor_a = make_tensor(data_a, layout_a);
auto tensor_b = make_tensor(data_b, layout_b);
auto tensor_c = make_tensor(data_c, layout_c);
/* 调用mma和store接口进行计算及写回，从而快速使能矩阵算力 */
tensor_tiled_mma(tiled_mma, tensor_c, tensor_a, tensor_b, tensor_c);
tensor_tiled_store(tile_store, tensor_c);
free(data_a);
free(data_b);
free(data_c);
return 0;
}
```
