首页 > 其他分享 >【2023CANN训练营第二季】——Ascend C代码实操分享

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

时间:2023-12-21 19:32:02浏览次数:40  
标签:代码 Ascend value custom 修改 实操 算子 2023CANN type

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

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

3.算子分析

算子分析的流程图如下:

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

对应题目,本题主要解决的是Kernel侧代码、Host侧代码,单算子调用时的代码。 Addcdiv算子的数学表达式为:out= x+ y/z*value

算子分析表格为

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

整个算子分析计算过程分为三个阶段:CopyIn,Compute,CopyOutCopyIn:搬入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算子文件夹如下:

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

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类的初始化代码,题目有四个输入,一个输出,修改如下:

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

该代码使用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()方法实现

【2023CANN训练营第二季】——Ascend C代码实操分享_初始化_06

通过 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()函数代码如下:

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

这里用到了Muls()方法用于矢量中每个元素与标量求积

CopyOut()方法实现

【2023CANN训练营第二季】——Ascend C代码实操分享_初始化_08

4.2 op_host侧实现

addcdiv_custom_tiling.h文件实现

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

【2023CANN训练营第二季】——Ascend C代码实操分享_初始化_09

addcdiv_custom.cpp文件实现

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

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

5.算子工程编译和部署

算子kernel侧和host侧代码实现了之后,需要对算子工程进行编译,生成自定义算子安装包*.run编译之前要修改CMakePresets.json文件下的ASCEND_CANN_PACKAGE_PATH变量,修改成你实际的CANN安装路径,我的修改如下:

【2023CANN训练营第二季】——Ascend C代码实操分享_初始化_11

修改好之后,切换到AddcdivCustom目录下,执行以下命令: ./build.sh编译成功截图如下:

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

此时会生成一个build_out文件夹,里面有一个文件custom_opp_euleros_aarch64.run,使用以下命令部署 ./custom_opp_euleros_aarch64.run

【2023CANN训练营第二季】——Ascend C代码实操分享_初始化_13

看到SUCCESS代表算子部署成功

6.使用aclnn方式调用

把AddCustom算子的AclNNInvocation文件夹复制一遍,目录位于samples/operator/AddCustomSample / FrameworkLaunch/AclNNInvocation,目录结构如下:

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

需要修改的文件有scripts文件下的gen_data.py,verify_result.py,src文件下的main.cpp,op_runner.cpp

gen_data.py修改

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

verify_result.py修改

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

main.cpp修改

要修改输入输出文件的位置

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

op_runner.cpp修改

要修改调用的算子名称,以及引入aclnn_addcdiv_custom.h头文件

【2023CANN训练营第二季】——Ascend C代码实操分享_初始化_18

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

【2023CANN训练营第二季】——Ascend C代码实操分享_初始化_19

总结:

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

标签:代码,Ascend,value,custom,修改,实操,算子,2023CANN,type
From: https://blog.51cto.com/u_16353294/8926489

相关文章

  • 打造高效用户旅程:埋点分析系统的实操指南
    引言什么是用户行为在数字化时代,了解用户如何与我们的产品或服务互动是至关重要的。用户行为,在广义上,指的是用户在网站、应用程序或其他数字界面上的所有动作和反应。这些行为可能包括点击链接、浏览页面、填写表单,甚至是在社交媒体上分享内容。每一个动作都是用户体验的一部分,并......
  • Airtest-Selenium实操小课①:爬取新榜数据
    此文章来源于项目官方公众号:“AirtestProject”版权声明:允许转载,但转载必须保留原链接;请勿用作商业或者非法用途1.前言最近看到群里很多小伙伴都在用Airtest-Selenium做一些web自动化的尝试,正好趁此机会,我们也出几个关于web自动化的实操小课,仅供大家参考~今天跟大家分享的......
  • 一文掌握Ascend C孪生调试
    本文分享自华为云社区《一文掌握AscendC孪生调试》,作者:昇腾CANN。1What,什么是孪生调试AscendC提供孪生调试方法,即CPU域模拟NPU域的行为,相同的算子代码可以在CPU域调试精度,NPU域调试性能。孪生调试的整体方案如下:开发者通过调用AscendC类库编写AscendC算子kernel侧源码,kerne......
  • Ascend C 算子开发遇到的问题及解决方法
    摘要:在学习AscendC算子开发进阶课程的时候,进行AscendC自定义算子工程、算子调用等实验,在开发环境中遇到了一些问题,在这里记录一下。首先如果在启智社区CANN版本为6.3,要进行AscendC算子开发,需要更新CANN版本。在CANN社区根据你的架构,比如我的为CPU架构位aarch64,所以下载Ascend-......
  • 【2023CANN训练营第二季】——Ascend C自定义算子工程介绍及实验
    一、自定义算子工程介绍与创建自定义算子工程是一个包含用户编写的host侧和kerne|侧算子实现文件的,用于编译和安装自定义算子run包的工程框架。CANN软件包中提供了工程创建工具msopgen,开发者可以输入算子原型定义文件生成AscendC算子开发工程。需要编写AddCustom算子的原型定义......
  • 使用ensp搭建路由拓扑,并使用BGP协议实现网络互通实操BGP路由协议学习一
    1.使用ENSP搭建的网络拓扑如下:         数据准备:设备名称接口IP地址DeviceALoopback01.1.1.1/32Eth 1/0/0172.16.0.1/16Eth0/0/0192.168.0.1/24DeviceBLoopback02.2.2.2/32Eth 0/0/110.1.1.1/24GE0/0/0192.168.0.2/24Eth 0/0/010.1.3.1/24DeviceCLoopbac......
  • 使用ensp搭建路由拓扑,并使用ospf协议实现网络互通实操
    1.使用ENSP搭建如下拓扑:              数据准备为完成此配置例,需准备如下的数据:设备RouterIDProcessIDIP地址DeviceA1.1.1.11区域0:192.168.0.0/24区域1:192.168.1.0/24DeviceB2.2.2.21区域0:192.168.0.0/24区域2:192.168.2.0/24DeviceC3.3.3.31区域1......
  • 【运维实操】TIDB v6.1.1:全量备份、全量恢复和增量备份方法解析
    作者:Fly-bird背景:由于公司要求必须保证数据库的数据安全,我们生产环境的数据库采取全量备份+增量备份+实时同步从库的方式保证数据库的高可用,本文介绍我公司生产环境的数据库备份方式。注意:我们使用实时同步数据到从库的方式保障高可用(使用pump+drainer),同时支持恢复任意时刻数据的......
  • c: struct sort descending and ascending
     /***@filehello.c*@authoryourname(geovindu)*@brief*@idevscodec11,c17windows10*@version0.1*@date2023-11-05**@copyrightCopyright(c)2023**/#include<stdlib.h>#include<stdint.h>#include<stdio.h......
  • Linux 挂载磁盘详解及实操步骤
    转自:https://www.jb51.net/server/288639rwu.htm步骤如下:一、磁盘分区在Linux中,磁盘是通过分区来使用的。分区是将一个硬盘划分成几个逻辑部分来使用,在每个分区中可以存储不同的文件系统。因此,在挂载磁盘之前,我们需要先对磁盘进行分区。磁盘分区的过程可以通过命令行工具或图形......