CANN训练营,算子开发大作业解析

举报
马城林 发表于 2022/12/24 20:08:08 2022/12/24
【摘要】 前面的文章进行了算子开发的背景知识介绍,这篇博客通过对大作业的手把手解析,实战算子开发 1.内容介绍使用Mind Studio开发工具,基于TBE DSL方式开发一个Sinh算子。算子规格参考如下:算子类型:Sinh数学表达式:sinh(x)=(exp(x) - exp(-x)) / 2.0支持的数据类型:float16支持的数据排布格式:ND 2.分析将Sinh算子的计算过程拆解,通过组合...

前面的文章进行了算子开发的背景知识介绍,这篇博客通过对大作业的手把手解析,实战算子开发

1.内容介绍

使用Mind Studio开发工具,基于TBE DSL方式开发一个Sinh算子。
算子规格参考如下:

  • 算子类型:Sinh
  • 数学表达式:sinh(x)=(exp(x) - exp(-x)) / 2.0
  • 支持的数据类型:float16
  • 支持的数据排布格式:ND

2.分析

将Sinh算子的计算过程拆解,通过组合DSL计算接口完成算子开发
主要分为三个部分

  • e的指数运算
  • 求相反数运算,乘或除-1
  • 除法运算
  • 减法运算

对应的接口为

  • tbe.vexp,e指数运算
  • tbe.broadcast(生成指定形状的内容相同的张量)
  • tbe.vdiv,除法运算
  • tbe.vsub,减法运算

3.开始实现算子

  1. 创建TensorFlow算子工程,IR模式

image.png

image.png

  1. 算子原型定义
    进入“op_proto/”目录,编写IR实现文件“sinh.h”和“sinh.cc”,将算子注册到算子原型库中。网络运行时,GE会调用算子原型库的校验接口进行基本参数的校验,校验通过后,会根据原型库中的推导函数推导每个节点的输出shape与dtype,进行输出tensor的静态内存的分配
    image.png
    头文件,MindStudio自动生成
#ifndef GE_OP_SINH_H
#define GE_OP_SINH_H
#include "graph/operator_reg.h"
namespace ge {

REG_OP(Sinh)
    .INPUT(x, TensorType({DT_FLOAT16}))
    .OUTPUT(y, TensorType({DT_FLOAT16}))
    .OP_END_FACTORY_REG(Sinh)
}
#endif //GE_OP_SINH_H

输出推导

IMPLEMT_COMMON_INFERFUNC(SinhInferShape)
{   
    // 获取输出
    TensorDesc tensordesc_output = op.GetOutputDescByName("y");
    // 设置输出的形状,与输入一致
    tensordesc_output.SetShape(op.GetInputDescByName("x").GetShape());
    // 设置输出的数据类型,与输入一致(float16)
    tensordesc_output.SetDataType(op.GetInputDescByName("x").GetDataType());
    // 设置输出的数据排布格式,与输入一致(ND)
    tensordesc_output.SetFormat(op.GetInputDescByName("x").GetFormat());
    // 将设置好的输出更新输出的张量描述信息
    (void)op.UpdateOutputDesc("y", tensordesc_output);
    return GRAPH_SUCCESS;
}
  1. 算子计算代码实现

image.png

def sinh_compute(x, y, kernel_name="sinh"):
    # e的x次幂
    exp_res = tbe.vexp(x)
    # 生成一个与输入x形状,数据类型相同的全部为-1的张量
    neg_one = tbe.broadcast(-1, x.shape, x.dtype)
    # x除以-1,获取x的相反数
    neg_exp_res = tbe.vexp(tbe.vdiv(x, neg_one))
    # e^(x) - e^(-x)
    add_res = tbe.vsub(exp_res, neg_exp_res)
    # 生成一个与输入x形状,数据类型相同的全部为2.0的张量
    two_tensor = tbe.broadcast(2.0, x.shape, x.dtype)
    res = tbe.vdiv(add_res, two_tensor)
    return res
  1. 算子信息库实现,设置输入参数与输出的数据类型与排布格式

image.png

[Sinh]
input0.name=x
input0.dtype=float16
input0.paramType=required
input0.format=ND
output0.name=y
output0.dtype=float16
output0.paramType=required
output0.format=ND
opFile.value=sinh
opInterface.value=sinh
  1. 算子适配插件设置

image.png

#include "register/register.h"

namespace domi {
// register op info to GE
REGISTER_CUSTOM_OP("Sinh")
    .FrameworkType(TENSORFLOW)   // type: CAFFE, TENSORFLOW
    .OriginOpType("Sinh")      // name in tf module
    .ParseParamsByOperatorFn(AutoMappingByOpFn)
    .ImplyType(ImplyType::TVM);
}  // namespace domi
  1. 算子功能调试
from tbe import tvm
# 引入testing模块相关接口
from tbe.common.testing.testing import *
import tbe.dsl as tbe

import numpy as np


# 进入调试模式
with debug():
    # 设置在CPU模式下验证算子计算正确性
    ctx = get_ctx()
    # 初始化一个形状(3,3)数据类型为float16,正态分布的张量数组
    x = tvm.nd.array(np.random.uniform(size=[3, 3]).astype("float16"), ctx)
    # 初始化一个形状为(3,3),数据类型为float16,全零的张量作为输出
    y = tvm.nd.array(np.zeros([3, 3], dtype="float16"), ctx)
    # 计算图占位符
    data_x = tvm.placeholder([3, 3], name="data_1", dtype="float16")
    # 计算e^(x)
    exp_res = tbe.vexp(data_x)
    neg_one = tbe.broadcast(-1, data_x.shape, data_x.dtype)
    # 计算e^(-x)
    neg_exp_res = tbe.vexp(tbe.vdiv(data_x, neg_one))
    print_tensor(exp_res)
    print_tensor(neg_exp_res)
    # 计算e^(x) - e^(-x)
    add_res = tbe.vsub(exp_res, neg_exp_res)
    two_tensor = tbe.broadcast(2.0, data_x.shape, data_x.dtype)
    # 计算除以2.0的最终结果
    div_res = tbe.vdiv(add_res, two_tensor)
    print_tensor(div_res)
    exp_res = np.sinh(x.asnumpy())
    print(exp_res)
    # 计算相对误差与绝对误差
    assert_allclose(div_res, desired=np.sinh(x.asnumpy()), tol=[1e-4, 1e-4])
    # 自动调度
    s = tvm.create_schedule(div_res.op)
    # 算子编译
    build(s, [data_x, div_res], name="Sinh")
    # 算子执行
    run(x, y)

注意:算子调试因为是在CPU的仿真环境下进行的测试,但是,因为昇腾处理器与CPU计算单元的实现不同,硬件有差异,因此精度可能出现少许偏差,因此此方法只是大致验证计算逻辑,真实情况以ST测试为准。

  1. 算子ST测试
    在项目根目录单击右键,进行算子ST测试
    image.png

填写ST测试,json配置文件
image.png
在期望结果验证一栏中,脚本路径填写验证脚本的位置,脚本方法填写脚本的验证方法
点击右下角的run,配置ST测试的内容
image.png
出现此log表示ST测试成功

/home/HwHiAiUser/MindStudio-WorkSpace/sinh_v2_2b4f4f92/testcases/st/out/sinh/run/out has been downloaded to C:\Users\CharlieMa\Desktop\code\canncamp\sinh_v2\testcases\st\out\sinh\run\out on the local path.
execute command: export PYTHONPATH=/home/HwHiAiUser/Ascend/ascend-toolkit/6.0.RC1.alpha001/toolkit/python/site-packages:$PYTHONPATH && /home/HwHiAiUser/Ascend/ascend-toolkit/6.0.RC1.alpha001/toolkit/python/site-packages/bin/msopst mi compare -i /home/HwHiAiUser/MindStudio-WorkSpace/sinh_v2_2b4f4f92/testcases/st/out/sinh/st_report.json --error_threshold [0.01,0.05] --error_report true
2022-12-24 20:03:47 (32144) - [INFO] Load /home/HwHiAiUser/MindStudio-WorkSpace/sinh_v2_2b4f4f92/testcases/st/out/sinh/st_report.json success.
2022-12-24 20:03:47 (32144) - [INFO] Step:------>>>>>> Start to get result <<<<<<------
2022-12-24 20:03:47 (32144) - [INFO] Find result.txt in /home/HwHiAiUser/MindStudio-WorkSpace/sinh_v2_2b4f4f92/testcases/st/out/sinh/run/out/result_files/result.txt.
2022-12-24 20:03:47 (32144) - [INFO] There case 'Test_Sinh_001_case_001_ND_float16' run success.
2022-12-24 20:03:47 (32144) - [INFO] Index 1:------>>>>>> Start to compare Test_Sinh_001_case_001_ND_float16 result <<<<<<------
2022-12-24 20:03:47 (32144) - [INFO] The result file Test_Sinh_001_case_001_ND_float16_output_0.bin compares with the expected data Test_Sinh_001_case_001_ND_float16_expect_output_0_float16.bin
2022-12-24 20:03:47 (32144) - [INFO] The data type is float16, the numpy type is <class 'numpy.float16'>
2022-12-24 20:03:47 (32144) - [INFO] total_count:1; max_diff_thd:0.1;
2022-12-24 20:03:47 (32144) - [INFO] ---------------------------------------------------------------------------------------
2022-12-24 20:03:47 (32144) - [INFO] Index           ExpectOut       RealOut         FpDiff          RateDiff
2022-12-24 20:03:47 (32144) - [INFO] ---------------------------------------------------------------------------------------
2022-12-24 20:03:47 (32144) - [INFO] 00000001        0.1793213       0.1791992       0.0001221       0.0001221
2022-12-24 20:03:47 (32144) - [INFO] ---------------------------------------------------------------------------------------
2022-12-24 20:03:47 (32144) - [INFO] DiffThd         PctThd          PctRlt          Result
2022-12-24 20:03:47 (32144) - [INFO] ---------------------------------------------------------------------------------------
2022-12-24 20:03:47 (32144) - [INFO] 0.0100          95.00%          100.000000%     Pass
2022-12-24 20:03:47 (32144) - [INFO] End to get result. Duration:0.00 second.
2022-12-24 20:03:47 (32144) - [INFO] The st report saved in: /home/HwHiAiUser/MindStudio-WorkSpace/sinh_v2_2b4f4f92/testcases/st/out/sinh/st_report.json.
========================================================================
run command: /home/HwHiAiUser/Ascend/ascend-toolkit/6.0.RC1.alpha001/toolkit/python/site-packages/bin/msopst mi gen -i=/home/HwHiAiUser/MindStudio-WorkSpace/sinh_v2_2b4f4f92/testcases/st/sinh/ascend310/Sinh_case_20221224155534.json -out=/home/HwHiAiUser/MindStudio-WorkSpace/sinh_v2_2b4f4f92/testcases/st/out/sinh --case_name=Test_Sinh_001
------------------------------------------------------------------------
- test case count: 1
- success count: 1
- failed count: 0
------------------------------------------------------------------------
========================================================================
2022-12-24 20:03:47 (32144) - [INFO] Process finished!
Start download files from /home/HwHiAiUser/MindStudio-WorkSpace/sinh_v2_2b4f4f92/testcases/st/out to C:\Users\CharlieMa\Desktop\code\canncamp\sinh_v2\testcases\st\out on the local path.

自此,算子开发完成

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。