4.AddReLU算子

AddReLU算子

大致代码参考官方教程即可快速入门-自定义算子开发-AscendC算子开发-CANN - 华为HarmonyOS开发者

一、创建工程

在~/mywork目录创建json文件:add_relu_custom.json

[ 
    { 
        "op": "AddReluCustom", 
        "input_desc": [ 
            { 
                "name": "x", 
                "param_type": "required", 
                "format": [ 
                    "ND", 
                    "ND", 
                    "ND" 
                ], 
                "type": [ 
                    "fp16", 
                    "float", 
                    "int32" 
                ] 
            }, 
            { 
                "name": "y", 
                "param_type": "required", 
                "format": [ 
                    "ND", 
                    "ND", 
                    "ND" 
                ], 
                "type": [ 
                    "fp16", 
                    "float", 
                    "int32" 
                ] 
            } 
        ], 
        "output_desc": [ 
            { 
                "name": "z", 
                "param_type": "required", 
                "format": [ 
                    "ND", 
                    "ND", 
                    "ND" 
                ], 
                "type": [ 
                    "fp16", 
                    "float", 
                    "int32" 
                ] 
            } 
        ] 
    } 
]

使用msopgen命令创建工程:

msopgen gen -i ~/mywork/add_relu_custom.json -c ai_core-kirin9020 -out ~/mywork/AddReluCustom

二、算子实现

代码同官方教程中的AddCustom算子基本一样,除了名字之外,只需要修改kernel侧代码里面的Compute( )函数,在Add接口后面添加一行:

// 计算函数,完成Compute阶段的处理,被核心Process函数调用 
__aicore__ inline void Compute(int32_t progress) 
{ 
    // 将Tensor从队列中取出,用于后续计算 
    AscendC::LocalTensor<DTYPE_X> xLocal = inQueueX.DeQue<DTYPE_X>(); 
    AscendC::LocalTensor<DTYPE_Y> yLocal = inQueueY.DeQue<DTYPE_Y>(); 
    // 从Queue中分配输出Tensor 
    AscendC::LocalTensor<DTYPE_Z> zLocal = outQueueZ.AllocTensor<DTYPE_Z>(); 
    // 调用Add接口进行计算 
    AscendC::Add(zLocal, xLocal, yLocal, this->tileLength); 
    // 第二步:ReLU激活(原地操作,将负数置0)
    AscendC::Relu(zLocal, zLocal, this->tileLength);
    // 将计算结果LocalTensor放入到VecOut的Queue中 
    outQueueZ.EnQue<DTYPE_Z>(zLocal); 
    // 释放输入Tensor 
    inQueueX.FreeTensor(xLocal); 
    inQueueY.FreeTensor(yLocal); 
} 

然后编译

./build.sh

三、运行测试

生成测试数据:

import numpy as np

# 1. 生成输入数据
np.random.seed(42)
x = np.random.randn(32).astype(np.float16)
y = np.random.randn(32).astype(np.float16)

# 2. 计算标杆数据(golden)
temp = x + y
golden = np.maximum(temp, 0).astype(np.float16)

# 3. 保存为.bin文件
x.tofile('./addrelu_x.bin')
y.tofile('./addrelu_y.bin')
golden.tofile('./addrelu_golden.bin')

创建json文件:add_relu_config.json

{
    "op_type": "AddReluCustom",
    "data_script": "",
    "gen_data": false,
    "inputs": [
        {
            "name": "x",
            "dtype": "float16", 
            "format": "ND",
            "ignore": false,
            "shape": [32],
            "param_type": "required",
            "data_file": "/home/dj/mywork/AddReluCustom/addrelu_x.bin"
        },
        {
            "name": "y",
            "dtype": "float16",
            "format": "ND",
            "ignore": false,
            "shape": [32],
            "param_type": "required",
            "data_file": "/home/dj/mywork/AddReluCustom/addrelu_y.bin"
        }
    ],
    "outputs": [
        {
            "name": "z",
            "dtype": "float16",
            "format": "ND",
            "ignore": false,
            "shape": [32],
            "param_type": "required",
            "data_file": "/home/dj/mywork/AddReluCustom/addrelu_golden.bin"
        }
    ]
}

CPU测试命令:

ascendebug kernel \
    --backend cpu \
    --chip-version kirin9020 \
    --repo-type customize \
    --json-file ./add_relu_config.json \
    --core-type AiCore \
    --work-dir ./debug_workspace

仿真测试命令:

ascendebug kernel --backend simulator --repo-type customize --json-file ./add_relu_config.json --core-type AiCore --chip-version kirin9020 --work-dir ./debug_workspace --block-num 1 --timeout 1200 


posted @ 2026-09-13 22:46  Tikas  阅读(2)  评论(0)    收藏  举报