【2023CANN训练营第二季】——Ascend C代码实操分享

news2024/10/6 10:28:54

1.实操题目:

使用Ascend C实现Addcdiv算子
参考pytorch的Addcdiv算子,实现Ascend C算子Addcdiv,算子命名为AddcdivCustom相关算法:out= x+ y/z*value
要求:
1、完成Kernel侧实现代码和host侧调用算子代码,支持fp16类型输入
2、完成AcInn方式调用编写好的算子
3、根据提供的测试用例,使用aclnn方式调用验证通过,精度偏差小于1e-3

2.环境准备

我是在华为云ModelArts西南贵阳一创建的Notebook,镜像为:

mindspore_2.2.0-cann_7.0.1-py_3.9-euler_2.10.7-aarch64-snt9b

image.png

3.算子分析

算子分析的流程图如下:
image.png
对应题目,本题主要解决的是Kernel侧代码、Host侧代码,单算子调用时的代码。
Addcdiv算子的数学表达式为:out= x+ y/z*value
算子分析表格为
image.png

整个算子分析计算过程分为三个阶段:CopyIn,Compute,CopyOut
CopyIn:搬入x,y,z,value到Local内存,其中value是标量,要解决标量怎么传入
Compute:使用Local内存进行计算
CopyOut:搬运Local计算结果到out
这里我打算创建两个临时变量tmpBuf1和tmpBuf2分别用于存放y/z,y/z*value的值。

4.算子开发

4.1创建算子工程

CANN软件包中提供了工程创建工具msopgen,我们可以输入算子原型定义文件生成Ascend C算子开发工程。
编写AddcdivCustom算子的原型定义json文件,如下:

[
    {
        "op": "AddcdivCustom",
        "language": "cpp",
        "input_desc": [
            {
                "name": "x",
                "param_type": "required",
                "format": ["ND"],
                "type": ["fp16"]
            },
            {
                "name": "y",
                "param_type": "required",
                "format": ["ND"],
                "type": ["fp16"]
            },
            {
                "name": "z",
                "param_type": "required",
                "format": ["ND"],
                "type": ["fp16"]
            },
            {
                "name": "value",
                "param_type": "required",
                "format": ["ND"],
                "type": ["fp16"]
            }
        ],
        "output_desc": [
            {
                "name": "out",
                "param_type": "required",
                "format": ["ND"],
                "type": ["fp16"]
            }
        ]
    }
]

然后使用以下命令生成算子文件夹:

/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/bin/msopgen gen -i /home/ma-user/work/samples/addcdiv_custom.json -c ai_core-Ascend910B2  -lan cpp -out /home/ma-user/work/samples/AddcdivCustom

生成的AddcdivCustom算子文件夹如下:
image.png

build_out文件夹是后面编译部署生成的,这里我们主要要修改的文件有:CMakePresets.json,op_host目录下的addcdiv_custom_tiling.h、addcdiv_custom.cpp、op_kernel目录下的addcdiv_custom.cpp。
下面分别展开


4.2 op_kernel侧实现

Init()方法实现

可以先把Add_custom算子的kernel侧实现代码复制过来,然后在此基础上进行修改,首先是KernelAddcdiv类的初始化代码,题目有四个输入,一个输出,修改如下:
image.png
该代码使用GM_ADDR初始化x,y,z,value,out五个变量,x,y,z都是输入矢量,用SetGlobalBuffer()方法分配内存,因为value是标量,这里通过reinterpret_cast将value强制转换为__gm__ half类型,并赋给inputVal1进行运算。后面还初始化了临时变量tmpBuf1,tmpBuf2,这两个变量使用了 TPosition::VECCALC 类型的缓冲区对象,定义如下:

TBuf<TPosition::VECCALC> tmpBuf1, tmpBuf2;
CopyIn()方法实现

image.png

通过 inQueueX.AllocTensor(),inQueueY.AllocTensor() 和 inQueueZ.AllocTensor(),为本地张量(LocalTensor)对象 xLocal、yLocal 和 zLocal 在本地内存中分配空间。这些本地张量对象用于存储从全局内存复制过来的数据。

Compute()方法实现

Compute()函数是算子开发的核心,这里我用到了上述定义的两个临时变量,y/z的值暂时放在tmpBuf1,y/z*value的值放在tmpBuf2。
使用Get()方法从临时变量获取指定长度的Tensor参与计算:

LocalTensor<half> tmp1 = tmpBuf1.Get<half>();
LocalTensor<half> tmp2 = tmpBuf2.Get<half>();

Compute()函数代码如下:
image.png
这里用到了Muls()方法用于矢量中每个元素与标量求积

CopyOut()方法实现

image.png

4.2 op_host侧实现

addcdiv_custom_tiling.h文件实现

这个文件要修改的地方是TilingData结构定义头文件的编写
image.png

addcdiv_custom.cpp文件实现

该文件是Tiling函数实现代码,主要修改算子原型注册代码,如下
image.png

5.算子工程编译和部署

算子kernel侧和host侧代码实现了之后,需要对算子工程进行编译,生成自定义算子安装包*.run
编译之前要修改CMakePresets.json文件下的ASCEND_CANN_PACKAGE_PATH变量,修改成你实际的CANN安装路径,我的修改如下:
image.png
修改好之后,切换到AddcdivCustom目录下,执行以下命令:
./build.sh
编译成功截图如下:
image.png
此时会生成一个build_out文件夹,里面有一个文件custom_opp_euleros_aarch64.run,使用以下命令部署
./custom_opp_euleros_aarch64.run
image.png
看到SUCCESS代表算子部署成功

6.使用aclnn方式调用

把AddCustom算子的AclNNInvocation文件夹复制一遍,目录位于samples/operator/AddCustomSample / FrameworkLaunch/AclNNInvocation,目录结构如下:
image.png
需要修改的文件有scripts文件下的gen_data.py,verify_result.py,src文件下的main.cpp,op_runner.cpp

gen_data.py修改

image.png

verify_result.py修改

image.png

main.cpp修改

要修改输入输出文件的位置
image.png

op_runner.cpp修改

要修改调用的算子名称,以及引入aclnn_addcdiv_custom.h头文件
image.png
修改完上述文件之后,就可以使用ACLNN的方式调用验证算子,进入AclNNInvocation文件夹,运行以下命令
bash run.sh
打印如下图,则代表测试通过!
image.png

总结:

以上就是Ascend C代码实操课的作业分享,其实理解了算子开发的流程之后,做起来就没那么吃力了,归纳起来就是先用msopgen工具生成算子工程文件,然后分别修改op_kernel侧和op_host侧的代码,然后进行编译和部署就可以了,后续还可以通过aclnn调用的方式调用AddCustom算子工程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1326473.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos 8.5 Oracle12c安装

由于多次安装踩坑&#xff0c;所以本次写了一份12c安装的完整版。可以直接使用。 一、安装数据库基本信息 名称 值 主机名 database 操作系统 CentOS Linux release 8.5.2111 Oracle用户名/密码 oracle Oracle 版本 12c Enterprise Edition Release 12.2.0.1.0 oracle…

【解决Typora图片不是显示问题】PicGo+Github+Typora+ onedrive/坚果云 实现笔记同步

【解决Typora图片不是显示问题】PicGo、Github、Typora实现笔记同步 写在前面&#xff1a; typora笔记软件使用记录typora图片上传问题&#xff1a;原因分析&#xff1a;解决方案&#xff1a;PicGoGithubTypora 坚果云/onedrive 实现笔记同步第一步. 设置上传模式&#xff1a;u…

解析Spring确定构造方法的过程

解析Spring确定构造方法的过程 文章目录 解析Spring确定构造方法的过程前言一、三个普通构造函数解析过程二、加Autowired 和 只有一个有参构造函数解析过程总结 前言 每次都是从关键代码进行定位解析&#xff0c;希望大家对Spring源码有一定的了解再看&#xff0c;本篇主要解…

IP子网划分【专题突破】

1、IP地址基础 IPv4地址是32位&#xff0c;采用点分十进制方式表示&#xff0c;其次必须掌握二进制的转换。 IPv6地址是128位&#xff0c;采用冒号分隔的十六进制表示方法。 2、IP地址的分类 RFC1918规定的私有地址 A类地址范围&#xff1a;10.0.0.0-10.255.255.255(1个A类…

在idea中不经意把模块remove moudle后在delete删除了怎么办

删除模块 我先演示一遍删除操作&#xff0c;看看您是不是这样误删的。 这时候模块已经被删除了 恢复模块 接下来进行恢复 File → Local_History → Show_History 打开历史记录 通过时间线或者找到要恢复的文件一步一步查找&#xff0c;找到要恢复的位置即可 以下位…

【python】进阶--->网络编程(一)

一、网络编程 网络 : 为了联络多方然后进行通信,将数据从一方传递给另一方. 网络协议 : 不同计算机只需要通过联网,那么就可以相互进行传递数据,那么不同种类的计算机之间就和不同语言的人之间沟通一样,需要一种大家都认可都遵循的协议即可. 那么计算机都遵循的网络通信协议叫…

二维码智慧门牌管理系统升级的重要性与功能

文章目录 前言一、系统的双重作用二、系统的挑战与未来发展三、结论与未来展望四、为未来智慧管理铺平道路 前言 随着科技不断进步&#xff0c;智能化管理已贯穿于我们日常生活的各个领域。其中&#xff0c;二维码智慧门牌管理系统升级解决方案因其独特的考核评估系统和实用功…

鸿蒙、ChatGPT 入选全球十大工程成就丨 RTE 开发者日报 Vol.111

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

2023.12.18 关于 CentOS7 安装 Redis5

目录 安装步骤 创建符号连接 修改配置文件 启动 redis 服务器 停止 redis 服务器 安装步骤 CentOS7 的 yum 仓库中&#xff0c;redis 的默认版本为 3 系列为了 能让 CentOS7 安装上 Redis5&#xff0c;此处我们需要安装额外软件源 1、安装额外软件源 yum install cento…

Python与Flink的完美融合:合流基本操作解析

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Apache Flink 是一个流式处理框架&#xff0c;支持复杂事件处理和大规模数据分析。在 Flink 中&#xff0c;合流&#xff08;Join&#xff09;是一种常见的操作&#xff0c;用于将两个或多个流中的数据按照指定条…

vue 点击添加多个input且与v-model绑定

<template><div><tr v-for"(item, index) in formArr" :key"index"><td><el-input v-model"item.value1" placeholder"请输入" /></td><td><el-input v-model"item.value2" p…

【EasyExcel实践】万能导出,一个接口导出多张表以及任意字段(可指定字段顺序)-简化升级版

文章目录 前言正文一、项目简介二、核心代码2.1 pom.xml 依赖配置2.2 ExcelHeadMapFactory2.3 ExcelDataLinkedHashMap2.4 自定义注解 ExcelExportBean2.5 自定义注解 ExcelColumnTitle2.6 建造器接口 Builder2.7 表格工具类 ExcelUtils2.8 GsonUtil2.9 模版类 ExportDynamicCo…

金蝶云星空业务对象标识是否可以修改

文章目录 金蝶云星空业务对象标识是否可以修改业务背景说明根本原因开发规范终极临时解决方案 金蝶云星空业务对象标识是否可以修改 业务背景 开发人员不注意&#xff0c;新建业务对象或者直接扩展标准产品的业务对象就直接操作保存&#xff0c;然后再次打开界面发现标识已经…

数字生态文明:构建可持续发展的未来

数字技术的快速发展给人类社会带来了巨大的变革,同时也对生态环境产生了深远的影响。在这个背景下,数字生态文明的概念应运而生,它强调在数字时代实现经济、社会和环境的协调发展,构建可持续的未来。 一、数字生态文明的内涵 数字生态文明是指在数字经济发展过程中,遵循…

【数据库】函数依赖

什么是函数依赖 就是在具体的表中/问题中&#xff0c;哪个属性决定另外几个属性。 A属性值相同的时候&#xff0c;能否决定唯一的B U {学号&#xff0c;姓名&#xff0c;年龄&#xff0c;班号&#xff0c;班长&#xff0c;课号&#xff0c;成绩} 就有&#xff1a; ‘学号’ 决…

vxe-table 修改[表尾数据]footer的高度

下面展示一些 内联代码片。 <style> .vxe-table--render-default.size--small .vxe-footer--column.col--ellipsis {height: 20px; } </style>

ElementUI中修改el-table的滚动条样式

注意&#xff1a;本文仅基于webkit引擎浏览器&#xff1b; 如果是火狐浏览器&#xff0c;则是-moz-&#xff1b; 部分webkit引擎浏览器&#xff1a;Google Chrome谷歌浏览器、Safari浏览器、搜狗高速浏览器、QQ浏览器、360极速浏览器等… 当内容超出容器时会出现滚动条&#…

Modbus转Profinet网关的解决方案推荐

现场问题&#xff1a;现场PLC的上端接的是显示器&#xff0c;下端接多台温湿度仪器&#xff0c;但是温湿度仪器的数量超过PLC的插槽限制了&#xff0c;导致项目无法正常完工。 解决方案&#xff1a;在PLC的下端加入Modbus转Profinet网关&#xff08;XD-MDPN100/2000&#xff09…

为外来邮件设置警示消息

大家好&#xff0c;才是真的好。 新版本发布&#xff0c;我们总有很多新内容要讲。其中最重要的就是新功能的测试和介绍。今天我们就来介绍Domino 14中设置外来邮件的提示文本信息。 如果你的Domino服务器环境已经升级到14.0&#xff0c;就可以在服务器的配置文档当中&#x…

怎么放大图片保持清晰度?

怎么放大图片保持清晰度&#xff1f;在生活中我们可能会保存各种各样的图片&#xff0c;但有时保存下来的图片可能太小了&#xff0c;尺寸和像素都不符合自己的要求&#xff0c;当图片像素和尺寸都过小会带来各种缺点&#xff0c;首先就是当我们看图片的时候会感觉它很模糊&…