Cube编程范式把算子的实现流程分为5个基本任务:CopyIn,Split,Compute,Aggregate,CopyOut。CopyIn负责搬入操作,Split负责数据切分操作,Compute负责矩阵指令计算操作,Aggregate负责数据汇聚操作,CopyOut负责搬出操作。
具体任务之间的交互流程和流程图如下。
基于Ascend C方式实现矩阵算子的流程如下图所示。
下文将以Matmul算子为例对上述步骤进行详细介绍,Matmul算子的代码框架如下,完整代码请参见实现样例。
#include "kernel_operator.h"
// 根据编程范式实现算子类
class KernelMatmul {
public:
__aicore__ inline void Init(GM_ADDR a, GM_ADDR b, GM_ADDR c)
{
// ...
}
__aicore__ inline void Process()
{
CopyIn();
SplitA();
AscendC::LocalTensor<half> b1Local = inQueueB1.DeQue<half>();
AscendC::LocalTensor<half> a2Local = inQueueA2.DeQue<half>();
AscendC::LocalTensor<float> c2Local = outQueueCO2.AllocTensor<float>();
// split matrix b into 2 parts, [32, 16] and [32, 16]
for (int i = 0; i < 2; ++i) {
SplitB(b1Local, i);
Compute(a2Local);
Aggregate(c2Local, i);
}
inQueueB1.FreeTensor(b1Local);
inQueueA2.FreeTensor(a2Local);
outQueueCO2.EnQue<float>(c2Local);
CopyOut();
}
private:
__aicore__ inline void CopyIn()
{
// ...
}
__aicore__ inline void SplitA()
{
// ...
}
__aicore__ inline void SplitB(const LocalTensor<half>& b1Local, const int bSplitIdx)
{
// ...
}
__aicore__ inline void Compute(const LocalTensor<half>& a2Local)
{
// ...
}
__aicore__ inline void Aggregate(const LocalTensor<float>& c2Local, const int bSplitIdx)
{
// ...
}
__aicore__ inline void CopyOut()
{
// ...
}
private:
// ...
};
//核函数定义
extern "C" __global__ __aicore__ void matmul_custom(GM_ADDR a, GM_ADDR b, GM_ADDR c)
{
KernelMatmul op;
op.Init(a, b, c);
op.Process();
}