核函数定义

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

  1. 函数原型定义

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

    extern "C" __global__ __aicore__ void add_custom(GM_ADDR x, GM_ADDR y, GM_ADDR z)
    {
    }

  2. 调用算子类的Init和Process函数。

    算子类的Init函数,完成内存初始化相关工作,Process函数完成算子实现的核心逻辑,具体介绍参见算子类实现
    extern "C" __global__ __aicore__ void add_custom(GM_ADDR x, GM_ADDR y, GM_ADDR z)
    {
        KernelAdd op;
        op.Init(x, y, z);
        op.Process();
    }

  3. 对核函数的调用进行封装,得到add_custom_do函数,便于主程序调用。#ifndef __CCE_KT_TEST__表示该封装函数仅在编译运行NPU侧的算子时会用到,编译运行CPU侧的算子时,可以直接调用add_custom函数。根据核函数调用章节,调用核函数时,除了需要传入参数x,y,z,还需要传入blockDim(核函数执行的核数),l2ctrl(保留参数,设置为nullptr),stream(应用程序中维护异步操作执行顺序的stream)来规定核函数的执行配置。

    #ifndef __CCE_KT_TEST__
    // call of kernel function
    void add_custom_do(uint32_t blockDim, void* l2ctrl, void* stream, uint8_t* x, uint8_t* y, uint8_t* z)
    {
        add_custom<<<blockDim, l2ctrl, stream>>>(x, y, z);
    }
    #endif