热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java与python3混合开发_AscendPytorch算子适配层开发

AscendPytorch算子适配层开发适配方法找到和PyTorch算子功能对应的NPUTBE算子,根据算子功能计算出输出Tensor的size,再根据

Ascend Pytorch算子适配层开发

适配方法

找到和PyTorch算子功能对应的NPU TBE算子,根据算子功能计算出输出Tensor的size,再根据TBE算子原型构造对应的input/output/attr,传递给ACL完成TBE算子的执行。

说明:

TBE算子实现的源文件存放路径由开发套件包Toolkit的安装方式决定:

· 若使用root用户安装,则存放在:/usr/local/Ascend/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe/impl/

· 若使用非root用户安装,则存放在:~/.local/Ascend/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe/impl/

开发者可以通过查看算子实现源文件,确定算子的功能。

存放路径和命名格式

对NPU的TBE算子适配文件保存在pytorch/aten/src/ATen/native/npu目录下,命名风格采用大驼峰,命名格式: + .cpp,如:AddKernelNpu.cpp。

适配步骤

须知:

适配代码基于C++开发。

1. 引入依赖头文件。

2. #include "ATen/native/npu/utils/CalcuOpUtil.h"

3. #include "ATen/native/npu/utils/KernelNpuOutputSize.h"

#include "ATen/native/npu/utils/NpuUtils.h"

说明:

"CalcuOpUtil.h"文件中主要包含与ACL接口相关的函数。

"KernelNpuOutputSize.h"中主要包含算子输出shape的推导函数。

"NpuUtils.h"文件中主要包含公共能力的函数。

4. 定义Add算子适配主体函数。

结合native_functions.yaml 中 add算子的分发定义,算子适配中应包含如下函数:

o add_npu_input 构造输入的NPUTensorDesc对象

o add_npu_output 构造输出的NPUTensorDesc对象

o add_npu_attr 构造NPU TBE Add算子attr属性

o add_out_npu 算子适配函数(yaml中npu派发函数,支持传入输出tensor),other参数支持 Tensor & Scalar

o add_npu 算子适配函数(yaml中npu派发函数),other参数支持 Tensor & Scalar

5. 实现函数 add_npu_input。

将NPU适配函数(add_npu_input)的输入构造成NPUTensorDesc对象。

// 输入参数为"self": "Tensor"和"other": "Tensor"时,适配函数add_npu_input的实现

SmallVector add_npu_input(const Tensor& self,const Tensor& other) {

bool isSelfWrapped = CalcuOpUtil::is_scalar_wrapped_to_tensor(self);

bool isOtherWrapped = CalcuOpUtil::is_scalar_wrapped_to_tensor(other);

auto inputs = CalcuOpUtil::create_npu_input_tensor_desc({self, other});

// 't + 2' to work with any type of tensor, not just LongTensor (which is what

// integersin Python represent).

if (isSelfWrapped && (!isOtherWrapped)) {

inputs[0].scalarType = other.scalar_type();

} else if (isOtherWrapped && (!isSelfWrapped)) {

inputs[1].scalarType = self.scalar_type();

}

return inputs;

}

// 输入参数为"self": "Tensor"和"other": "Scalar"时,适配函数add_npu_input的实现

SmallVector add_npu_input(const Tensor& self,const Scalar& other) {

return CalcuOpUtil::create_npu_input_tensor_desc({self});

}

6. 实现函数 add_npu_output。

将函数 add_npu_output的输出tensor对象构造成NPUTensorDesc对象。

// 输出参数为 "Tensor" 时,适配函数add_npu_output的实现

SmallVector add_npu_output(const Tensor& result) {

return CalcuOpUtil::create_npu_output_tensor_desc({result});

}

说明:

一般来说,算子的输出不需要特殊处理,直接调用CreateNpuOutputTensorDesc即可。

7. 实现函数 add_npu_attr。

根据NPU TBE算子原型中所需的attr规格,将参数适配成NPU TBE算子原型所需要的attr属性。

// 输入参数为"other": "Tensor"和"alpha": "Scalar"时,对应的适配函数add_npu_attr实现

SmallVector add_npu_attr(const Tensor& self, const Tensor& other, Scalar alpha) {

float value = CalcuOpUtil::get_scalar_float_value(alpha);

NPUAttrDesc npuAttrScalar = NPUAttrDesc("alpha", value);

SmallVector attrs = {npuAttrScalar};

return attrs;

}

// 输入参数为"other": "Scalar"和"alpha": "Scalar"时,对应的适配函数adds_npu_attr实现

SmallVector adds_npu_attr(const Tensor& self,const Scalar& other,const Scalar& alpha) {

float otherValue = CalcuOpUtil::get_scalar_float_value(other);

float alphaValue = CalcuOpUtil::get_scalar_float_value(alpha);

float value = otherValue * alphaValue;

NPUAttrDesc npuAttrValue = NPUAttrDesc("value", value);

SmallVector attrs = {npuAttrValue};

return attrs;

}

8. 实现函数 add_out_npu。

9. Tensor& add_out_npu(Tensor& result, const Tensor& self, const Tensor& other, Scalar alpha) {

10. if (other.dim() == 0 && !other.is_npu()) {

11. adds_out_npu(result, self, other.item(), alpha);

12. } else if (self.dim() == 0 && !self.is_npu()) {

13. adds_out_npu(result, other, self.item(), alpha);

14. } else {

15. // constructs the input and output NPUTensorDesc

16. auto inputs = add_npu_input(self, other);

17. auto outputs = add_npu_output({result});

18.

19. // constructs the attr of the NPUAttrDesc

20. auto attrs = add_npu_attr(self, other, alpha);

21. // executing the NPU operator

22. CalcuOpUtil::execute_npu_operate("Axpy", inputs, outputs, attrs);

23. }

24.

25. return result;

}

说明:

add_out_npu和add_npu的差别是add_out_npu支持显示指定输出tensor,往输出tensor中写入结果。

26. 实现函数 add_npu。

a. 定义并实现算子的shape推导函数,根据输入参数计算输出的size。

Shape推导函数定义规范:

"NPU适配函数名称" + "_" + "output" + "_" + "size",如add_npu_output_size();

说明:

§ Shape推导函数定义和实现存放在 pytorch/aten/src/ATen/native/npu/utils,对应的头文件和实现在 KernelNpuOutPutSize.h 和 KernelNpuOutPutSize.cpp中。

§ 在KernelNpuOutPutSize.h中,函数存放位置按照函数名字排序。

//输入参数为"self": "Tensor"和"other": "Tensor"时,Shape推导该函数

SmallVector add_npu_output_size(const Tensor& self,const Tensor& other) {

return broadcast_ops_npu_output_size(self, other); //定义Shape推导函数

}

// 输入参数为"self": "Tensor"和"other": "Scalar"时,Shape推导该函数

IntArrayRef add_npu_output_size(const Tensor& self, const Scalar& other) {

return input_same_output_size(self);

}

说明:

broadcast_ops_npu_output_size函数的作用是:当两个参数符合PyTorch广播机制时,函数会将两个参数自动扩展为相等大小

b. 调用对应的shape推导函数计算输出的size。

c. 根据输出的size调用at::empty_with_ format创建输出Tensor,函数支持指定输出Tensor的format,默认为NCHW格式。

说明:

当前制定的Format设置规则为重型算子锚点扩散+连续性法则混合规则。

§ 重型算子如卷积、Matmul,只支持某种特定format,适配时显示指定为其需要的format,format向周边扩散。

§ 而连续性法则指的是算子对格式不敏感,算子format指定为与第一个输入tensor的format相同即可。

§ NPU中的卷积只支持NC1HWC0格式,所以需要显式指定为NC1HWC0格式

d. 将构造好的输出Tensor和其他参数传给add_out_npu进行运算

e. // 输入参数为"self": "Tensor"和"other": "Tensor"时,对应的适配函数add_npu实现

f. //调用对应的Shape推导函数计算输出的size

g. Tensor add_npu(const Tensor& self, const Tensor& other, Scalar alpha) {

h. Tensor outputTensor = add_dest_output(self, other);

i. auto outputSize = add_npu_output_size(self, other);

j.

k. //根据输出的size调用at::empty_with_format创建输出Tensor,函数支持指定输出Tensor的format,默认为NCHW格式

l. Tensor result = at::empty_with_format(outputSize, outputTensor.options(), CalcuOpUtil::get_tensor_npu_format(outputTensor));

m.

n. //将构造好的输出Tensor和其他参数传给add_out_npu进行运算

o. add_out_npu(result, self, other, alpha);

p. return result;

q. }

r.

s. // 输入参数为"self": "Tensor"和"other": "Scalar"时,对应的适配函数add_npu实现

t. //调用对应的Shape推导函数计算输出的size

u. Tensor add_npu(const Tensor& self, Scalar other, Scalar alpha) {

v. auto outputSize = add_npu_output_size(self, other);

w.

x. //根据输出的size调用at::empty_with_format创建输出Tensor,函数支持指定输出Tensor的format,默认为NCHW格式

y. Tensor result = at::empty_with_format(outputSize, self.options(), CalcuOpUtil::get_tensor_npu_format(self));

z.

aa. //将构造好的输出Tensor和其他参数传给add_out_npu进行运算

bb. adds_out_npu(result, self, other, alpha);

cc. return result;

}



推荐阅读
  • 程度|也就是_论文精读:Neural Architecture Search without Training
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了论文精读:NeuralArchitectureSearchwithoutTraining相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • Mono为何能跨平台
    概念JIT编译(JITcompilation),运行时需要代码时,将Microsoft中间语言(MSIL)转换为机器码的编译。CLR(CommonLa ... [详细]
  • Question该提问来源于开源项目:react-native-device-info/react-native-device-info ... [详细]
  • 初识java关于JDK、JRE、JVM 了解一下 ... [详细]
  • RN即ReactNative基于React框架针对移动端的跨平台框架,在学习RN前建议最好熟悉下html,css,js,当然如果比较急,那就直接上手吧,毕竟用学习前面基础的时间,R ... [详细]
author-avatar
好运娟_968
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有