带你了解AKG正反向算子注册+关联流程
摘要:简要介绍一下akg正反向算子的注册和关联流程。
本文分享自华为云社区《AKG正反向算子注册+关联》,作者:木子_007 。
一、环境
硬件:eulerosv2r8.aarch64
mindspore:1.1
算子注册需要编译安装框架才能生效,所以默认环境中已经有了mindspore的源码,并且已经可以编译安装
二、正向算子制作及测试
这里制作一个计算向量平方的算子
正向:y = x**2
反向:y = 2*x
先介绍正向
2.1 定义正向算子
路径:mindspore/akg/python/akg/ms/cce/,创建cus_square.py
参照同级目录下计算逻辑的定义,定义向量平方的计算逻辑
"""cus_square"""
from akg.tvm.hybrid import script
from akg.ops.math import mul
import akg
def CusSquare(x):
output_shape = x.shape
k = output_shape[0]
n = output_shape[1] @script
def cus_square_compute(x):
y = output_tensor(output_shape, dtype=x.dtype)
for i in range(k):
for j in range(n):
y[i, j] = x[i, j] * x[i, j]
return y output = cus_square_compute(x) attrs = {
'enable_post_poly_loop_partition': False,
'enable_double_buffer': False,
'enable_feature_library': True,
'RewriteVarTensorIdx': True
} return output, attrs
然后在同级目录下的__init__.py文件中添加内容
from .cus_square import CusSquare
2.2 注册算子
到路径:mindspore/ops/_op_impl/akg/ascend,创建cus_square.py,添加如下代码
"""CusSquare op"""
from mindspore.ops.op_info_register import op_info_register, AkgAscendRegOp, DataType as DT op_info = AkgAscendRegOp("CusSquare") \
.fusion_type("ELEMWISE") \
.input(0, "x") \
.output(0, "output") \
.dtype_format(DT.F32_Default, DT.F32_Default) \
.get_op_info()
@op_info_register(op_info)
def _cus_square_akg():
"""CusSquare Akg register"""
return
然后在同级目录的__init__.py添加如下代码
from .cus_square import _cus_square_akg
2.3 定义算子原语
到:mindspore/ops/operations,新创建一个_cus_ops.py,添加如下代码
描述算子的输入:x,输出output
infer_shape:描述输出数据的shape
infer_dtype:说明输出数据的类型
x1_shape:指的是第一个输入的shape
x1_dtype:指的是第一个输入参数的dtype
import math from ..primitive import prim_attr_register, PrimitiveWithInfer
from ...common import dtype as mstype
from ..._checkparam import Validator as validator
from ..._checkparam import Rel class CusSquare(PrimitiveWithInfer):
"""CusSquare""" @prim_attr_register
def __init__(self):
self.init_prim_io_names(inputs=['x'], outputs=['output']) def infer_shape(self, x1_shape):
return x1_shape def infer_dtype(self, x1_dtype):
return x1_dtype
然后在同目录下的__init__.py文件中添加原语信息
from ._cus_ops import CusSquare
2.4 在ccsrc中添加算子的查询信息
在mindspore/ccsrc/backend/kernel_compiler/http://kernel_query.cc的KernelQuery函数中添加如下信息
// cus_square
const PrimitivePtr kPrimCusSquare = std::make_shared<Primitive>("CusSquare");
if (IsPrimitiveCNode(kernel_node, kPrimCusSquare)) {
kernel_type = KernelType::AKG_KERNEL;
}
2.5 编译安装框架
回到mindspore根目录
bash build.sh -e ascend -j4
cd ./build/package
pip install mindspore_ascend-1.1.2-cp37-cp37m-linux_aarch64.whl --force-reinstall
2.6 测试
import numpy as np
import mindspore.nn as nn
import mindspore.context as context
from mindspore import Tensor
from mindspore.ops import operations as P context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.square = P.CusSquare() def construct(self, data):
return self.square(data) def test_net():
x = np.array([[1.0, 4.0, 9.0]]).astype(np.float32)
net = Net()
output = net(Tensor(x))
print("x: ", x)
print("output: ", output)
if __name__ == "__main__":
test_net()
输出

三、反向算子的制作和测试
3.1 制作流程
反向算子的计算逻辑:对向量元素进行求导,如 y = x^2,则求导之后 y` = 2x
实际例子就是输入向量[1, 4, 9] 输出就是 [2, 8, 18]
反向算子明明为CusSquareGrad,与前边的计算平方的算子流程相同,这里只贴一下关键代码,流程不再赘述
计算逻辑代码cus_square_grad.py
"""cus_square_grad"""
from akg.tvm.hybrid import script
import akg def CusSquareGrad(x):
output_shape = x.shape
k = output_shape[0]
n = output_shape[1] @script
def cus_square_compute_grad(x):
y = output_tensor(output_shape, dtype=x.dtype)
for i in range(k):
for j in range(n):
y[i, j] = x[i, j] * 2
return y output = cus_square_compute_grad(x) attrs = {
'enable_post_poly_loop_partition': False,
'enable_double_buffer': False,
'enable_feature_library': True,
'RewriteVarTensorIdx': True
} return output, attrs
注册原语
class CusSquareGrad(PrimitiveWithInfer):
"""
CusSquareGrad
""" @prim_attr_register
def __init__(self):
self.init_prim_io_names(inputs=['x'], outputs=['output']) def infer_shape(self, x1_shape):
return x1_shape def infer_dtype(self, x1_dtype):
return x1_dtype
3.2 测试
import numpy as np
import mindspore.nn as nn
import mindspore.context as context
from mindspore import Tensor
from mindspore.ops import operations as P context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.square = P.CusSquareGrad() # 替换为grad算子 def construct(self, data):
return self.square(data) def test_net():
x = np.array([[1.0, 4.0, 9.0]]).astype(np.float32)
net = Net()
output = net(Tensor(x))
print("x: ", x)
print("output: ", output)
if __name__ == "__main__":
test_net()
输出

四、正反向算子关联及测试
在源码 mindspore/mindspore/ops/_grad/grad_array_ops.py中添加如下代码
@bprop_getters.register(P.CusSquare)
def get_bprop_cussquare(self):
"""Generate bprop of CusSquare"""
cus_square_grad = P.CusSquareGrad()
matmul = ops.Mul()
def bprop(x, out, dout):
gradient = cus_square_grad(x)
dx = matmul(gradient, dout)
return (dx,)
return bprop
bprop函数的输入是,正向的输入x,正向的输出out,反向的梯度输入dout
上面代码的意思是指定算子CusSquare的反向梯度的计算方法,CusSquareGrad作为其中的一个函数使用
gradient = cus_square_grad(x)计算的是本平方算子的梯度,但并不能直接返回这个梯度
反向网络到该算子,最后返回的是dx,注意算子的反向梯度计算一定要放在整个网络的反向链式梯度计算中
测试
import numpy as np
import mindspore.nn as nn
import mindspore.context as context
from mindspore import Tensor
from mindspore.ops import operations as P
from mindspore.ops import composite as C context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.square = P.CusSquare() def construct(self, data):
return self.square(data) def test_net():
x = Tensor(np.array([[1.0, 4.0, 9.0]]).astype(np.float32))
grad = C.GradOperation(get_all=True) # 计算网络梯度
net = Net()
output = grad(net)(x)
print("x: ", x)
print("output: ", output)
if __name__ == "__main__":
test_net()
输出

带你了解AKG正反向算子注册+关联流程的更多相关文章
- [源码分析] 带你梳理 Flink SQL / Table API内部执行流程
[源码分析] 带你梳理 Flink SQL / Table API内部执行流程 目录 [源码分析] 带你梳理 Flink SQL / Table API内部执行流程 0x00 摘要 0x01 Apac ...
- 如何设计一个 App 的注册登录流程?
移 动设备发力之前的登录方式很简单:用户名/邮箱+密码+确认密码,所有的用户登录注册都是围绕着邮箱来做.随着移动设备和社交网络的普及,邮箱不再是唯 一,渐渐的出现了微博,QQ,微信等第三方登录方式,手 ...
- 第三节:带你详解Java的操作符,控制流程以及数组
前言 大家好,给大家带来带你详解Java的操作符,控制流程以及数组的概述,希望你们喜欢 操作符 算数操作符 一般的 +,-,*,/,还有两个自增 自减 ,以及一个取模 % 操作符. 这里的操作算法,一 ...
- Android Market google play store帐号注册方法流程 及发布应用注意事项
Android Market google play store帐号申请 注册方法流程 在 Google Play 中发布软件之前,您需要完成以下三项工作: 创建开发人员个人资料 接受开发人员分发协议 ...
- Android Market google play store帐号注册方法流程 及发布应用注意事项【转载】
[转载]http://www.cnblogs.com/zdz8207/archive/2012/07/09/google-play-store-registered.html Android Mark ...
- Nacos(二)源码分析Nacos服务端注册示例流程
上回我们讲解了客户端配置好nacos后,是如何进行注册到服务器的,那我们今天来讲解一下服务器端接收到注册实例请求后会做怎么样的处理. 首先还是把博主画的源码分析图例发一下,让大家对整个流程有一个大概的 ...
- Spring Security 的注册登录流程
Spring Security 的注册登录流程 数据库字段设计 主要数据库字段要有: 用户的 ID 用户名称 联系电话 登录密码(非明文) UserDTO对象 需要一个数据传输对象来将所有注册信息发送 ...
- 使用Microsoft自带的小工具将可执行文件(.exe)注册为系统服务
首先,我们从Microsoft下载Windows Resource Kits,Download 下载完成后,运行rktools.exe进行安装. 安装完成后,我们打开安装目录,将其中的"in ...
- Nacos(一)源码分析Nacos注册示例流程
nacos官方地址:https://nacos.io/zh-cn/ 大家可以看一下nacos的中文手册以及官方源码,博主就不带领大家快速入门 了,官方文档中都有而且非常标准,比其他博客写的好多了并且还 ...
- Spring Cloud Eureka源码分析之服务注册的流程与数据存储设计!
Spring Cloud是一个生态,它提供了一套标准,这套标准可以通过不同的组件来实现,其中就包含服务注册/发现.熔断.负载均衡等,在spring-cloud-common这个包中,org.sprin ...
随机推荐
- sprintf函数内存越界
最近在做项目的时候遇到sprintf函数内存越界的问题,现在分享给大家,希望对大家有用. 首先介绍了sprintf 这个函数. 函数原型: int sprintf(char *str, const ...
- 概率期望 DP 题解合集
期望这东西学了一次忘了,再学一次过了两天又不会了.我是鱼. 故写此博客以便加深记忆及日后复习. NOIP 前恶补期望(? 希望有用,RP++() 经典问题 1 某事件发生概率为 \(p\),则该事件首 ...
- Java之对象内存分析
相信大家有时候在读代码的时候应该都会有以下情况: 这个对象本定义在上面,乱跑什么?怎么又到下面去了? 欸?我明明改变了这个对象的值,怎么没变呢? 要想搞清楚某一对象在程序中是怎样活蹦乱跳的,首先我们要 ...
- AndroGenshin
是一个apk文件 jadx打开以后发现主要操作 找到mainactivity,研究代码可以知道主要操作就是对两个字符串进行RC4加密再进行一次换表的base64操作,最后再将加密后的结果与flag做对 ...
- 一个小型markdown读写编辑器推荐
在作业完成时我和很多同学们发现并没有很好地利用博客园里面自带的markdown标记语法的形式完成作业 因此我在网上自己搜索发现了这款软件 下载地址 在帮助里可以学到一些简单的使用形式 可以方便编辑已有 ...
- C语言所有运算符及优先级、结合性
C 语言所有运算符及优先级.结合性 参考:<C Primer Plus 第六版> Tip:有关优先级.结合性的表格在最后面. [1]算数运算符 '+'("加号")(二元 ...
- [CF1854C] Expected Destruction
题目描述 You have a set $ S $ of $ n $ distinct integers between $ 1 $ and $ m $ . Each second you do th ...
- [NOI online2022提高C] 如何正确地排序
题目描述 有一个 \(m\times n\) 的数组 \(a_{i,j}\). 定义: \(f(i,j)=\min\limits_{k=1}^m(a_{k,i}+a_{k,j})+\max\limit ...
- 【matlab混沌理论】1.4.双摆杆的不同参数模型
双摆杆运动模型.初始条件的微小差异,会导致千差万别的运动现象,这是混沌理论重要体现.主要考虑初始条件有两摆杆长度.质量.初始摆杆角度.重力加速度. input: % 参数定义 L1 = 1; % 第一 ...
- Redis入门实践
安装Redis 下载:官网:https://redis.io/download/,选择稳定版下载. 上传至linux 解压Redis:tar -zxvf redis-6.2.7.tar.gz,得到: ...