CANN训练营,算子开发大作业解析
【摘要】 前面的文章进行了算子开发的背景知识介绍,这篇博客通过对大作业的手把手解析,实战算子开发 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.开始实现算子
- 创建TensorFlow算子工程,IR模式
- 算子原型定义
进入“op_proto/”目录,编写IR实现文件“sinh.h”和“sinh.cc”,将算子注册到算子原型库中。网络运行时,GE会调用算子原型库的校验接口进行基本参数的校验,校验通过后,会根据原型库中的推导函数推导每个节点的输出shape与dtype,进行输出tensor的静态内存的分配
头文件,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;
}
- 算子计算代码实现
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
- 算子信息库实现,设置输入参数与输出的数据类型与排布格式
[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
- 算子适配插件设置
#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
- 算子功能调试
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测试为准。
- 算子ST测试
在项目根目录单击右键,进行算子ST测试
填写ST测试,json配置文件
在期望结果验证一栏中,脚本路径填写验证脚本的位置,脚本方法填写脚本的验证方法
点击右下角的run,配置ST测试的内容
出现此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)