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<NPUTensorDesc, N> 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<NPUTensorDesc, N> 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<NPUTensorDesc, N> 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<NPUAttrDesc, N> 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<NPUAttrDesc, N> attrs = {npuAttrScalar};
    return attrs;
    }
    // 输入参数为"other”: “Scalar"和"alpha”: "Scalar"时,对应的适配函数adds_npu_attr实现
    SmallVector<NPUAttrDesc, N> 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<NPUAttrDesc, N> 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.     // constructs the attr of the NPUAttrDesc
    
  19.     auto attrs = add_npu_attr(self, other, alpha);
    
  20.     // executing the NPU operator
    
  21.     CalcuOpUtil::execute_npu_operate("Axpy", inputs, outputs, attrs);
    
  22. }
    
  23. 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<int64_t, SIZE> 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;
}

Ascend Pytorch算子适配层开发相关推荐

  1. Ascend Pytorch算子功能验证

    Ascend Pytorch算子功能验证 编写测试用例 以add算子为例,测试脚本文件命名为:add_testcase.py.以下示例仅为一个简单的用例实现,具体算子的实现,需要根据算子定义进行完整的 ...

  2. 【2023 · CANN训练营第一季】——Ascend C算子开发入门——第一次课

    前言:昇腾AI处理器的算子开发增加了一种新的方式,称之为TIK2,正式名称是Ascend C算子开发.不同于采用Python的DSL和TIK方式,Ascend C使用C/C++作为前端语言的算子开发工 ...

  3. 自定义算子高性能开发

    自定义算子高性能开发 在计图中,一共有三种方法来开发自定义的算子: 使用元算子进行组合. 使用Code算子开发自定义算子. 使用计图编译器编译自定义的模块和custom op. 其中,元算子开发是最为 ...

  4. 基于Anaconda安装GPU版PyTorch深度学习开发环境

    基于Anaconda安装GPU版PyTorch深度学习开发环境 1 安装Anaconda 2 安装GPU计算驱动 2.1 检查是否有合适的GPU 2.2 下载CUDA和cuDNN 2.3 安装CUDA ...

  5. 【VM服务管家】VM4.x算子SDK开发_3.4 控件嵌入类

    目录 3.4.1 图片存储:图片保存的方法 3.4.2 辅助十字线:给图像添加辅助十字线的方法 3.4.3 控件调用:在WPF中使用Winform控件的方法 3.4.4 图形改变事件:渲染控件上图形改 ...

  6. CANN训练营第三季_昇腾CANN算子精讲课_TBE算子Sinh开发笔记_算子开发(二)

    1.作业算子要求 2.检查版本对应关系 在Mindstudio软件包下载界面可以检查安装的mindstudio版本和cann版本是否一致,如果不一致可能会导致后面算子工程创建出错. 这里我用的Mind ...

  7. 什么,PyTorch还能开发新药?哈佛推出这款工具包,10行代码训练“药神”模型...

    萧箫 编辑整理 量子位 报道 | 公众号 QbitAI 最近,来自哈佛大学等机构的研究人员,开发出了一个AI"药神"工具包,为加速新冠疫情下的新药研发助力. 这款名为DeepPur ...

  8. 服务器(2080Ti)配置pytorch,distiller开发环境踩坑记录

    公司计算资源限制,将开发环境转移到学校实验室的服务器上进行,需要重新配置一遍开发环境.服务器配置为10块RTX 2080Ti的显卡.本以为有了之前一次配置环境的经验会很顺利,naive... 1.to ...

  9. CANN训练营第三季_昇腾CANN算子精讲课_TBE算子Sinh开发笔记_UT测试(三)

    UT测试: UT测试是为了测试算子代码的正确性和不同场景下的覆盖率的测试,UT测试在硬件CPU上执行,MindStudio提供了gtest框架方便进行UT测试. 参考:https://www.hias ...

最新文章

  1. Manifest值冲突解决方法
  2. SharePoint 列表应用实例 - 显示约束
  3. linux内核 header.s,Linux启动代码header.S研究
  4. [CPP]--Unicode 字符编码
  5. 如何打开CMD命令行
  6. 租借云服务器 工业信号数据采集,一种工业用物联网云服务平台智能采集方法...
  7. 阿里云全球首次互联网8K直播背后的技术解读
  8. vb发送邮箱连接服务器失败,VB:如何用需要身份验证的SMTP邮件服务器发信
  9. .NET Core 1.0 CentOS7 尝试
  10. GWT EJB3 Maven JBoss 5.1集成教程
  11. 第一百一十九期:支付宝历年双十一背后的技术揭秘
  12. java swing 图片上加热点_外卖图片品牌全靠P,4元成本料理包加热后,平台上20元卖出...
  13. webgis之qgis缓存
  14. 蓝牙车库门禁卡原理及实践
  15. 同文输入法 android,同文输入法app下载-同文输入法手机版-同文输入法最新版_易玩网...
  16. iPAD越狱后下载破解版的pad软件方法总录
  17. python - 文件打包发布流程
  18. (Cys-RGD)包被CdTe量子|3-巯基丙酸(MPA)包被近红外发光CdTe量子
  19. [转载]提升你幽默感的100句经典短语
  20. 苹果7 plus手机显示无服务器,天了噜!iPhone 7 Plus 居然有这些功能!非买不可!...

热门文章

  1. 使用python愉快地做高数线代题目~
  2. 2022-2028年中国海洋电力行业市场深度分析及发展策略分析报告
  3. 求字符串全排列 python实现
  4. centos7samba服务的搭建
  5. 解决git本地提交不到远程库
  6. shell编程_linux
  7. Transformer的PyTorch实现
  8. glove 安装错误
  9. SQL性能下降原因及Join查询
  10. LeetCode简单题之两数之和 IV - 输入 BST