下载
EN
注册

核函数定义

根据核函数定义中介绍的规则进行核函数的定义。

  1. 函数原型定义。

    本样例中,函数名为matmul_custom(核函数名称可自定义);根据算子分析中对算子输入输出的分析,确定有3个参数a,b,c,其中a,b都为输入内存,c为输出内存。根据核函数定义核函数的规则介绍,函数原型定义如下所示:使用__global__函数类型限定符来标识它是一个核函数,可以被<<<>>>调用;使用__aicore__函数类型限定符来标识该核函数在设备端aicore上执行;为方便起见,统一使用GM_ADDR宏修饰入参,GM_ADDR宏定义请参考核函数定义

    extern "C" __global__ __aicore__ void matmul_custom(GM_ADDR a, GM_ADDR b, GM_ADDR c)
    {
    }
  2. 调用算子类的Init和Process函数。
    算子类的Init函数,完成内存初始化相关工作,Process函数完成算子实现的核心逻辑,具体介绍参见算子类实现
    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();
    }
  3. 对核函数进行封装,得到matmul_custom_do函数,便于主程序调用。#ifndef ASCENDC_CPU_DEBUG表示该封装函数仅在编译运行NPU侧的算子时会用到,编译运行CPU侧的算子时,可以直接调用matmul_custom函数。根据核函数调用章节,调用核函数时,除了需要传入参数a,b,c,还需要传入blockDim(核函数执行的核数),l2ctrl(保留参数,设置为nullptr),stream(应用程序中维护异步操作执行顺序的stream)来规定核函数的执行配置。
    #ifndef ASCENDC_CPU_DEBUG
    // call of kernel function
    void matmul_custom_do(uint32_t blockDim, void* l2ctrl, void* stream, uint8_t* a, uint8_t* b, uint8_t* c)
    {
        matmul_custom<<<blockDim, l2ctrl, stream>>>(a, b, c);
    }
    #endif