Ascend C Add算子样例代码详解

核函数定义

核函数(Kernel Function)是Ascend C算子设备侧实现的入口。在核函数中,需要为在一个核上执行的代码规定要进行的数据访问和计算操作,当核函数被调用时,多个核都执行相同的核函数代码,具有相同的参数,并行执行。

// 实现核函数
extern "C" __global__ __aicore__ void add_custom(GM_ADDR x, GM_ADDR y, GM_ADDR z)
{
    // 初始化算子类,算子类提供算子初始化和核心处理等方法
    KernelAdd op;
    // 初始化函数,获取该核函数需要处理的输入输出地址,同时完成必要的内存初始化工作
    op.Init(x, y, z);
    // 核心处理函数,完成算子的数据搬运与计算等核心逻辑
    op.Process();
}

// 调用核函数
void add_custom_do(uint32_t blockDim, void* l2ctrl, void* stream, uint8_t* x, uint8_t* y, uint8_t* z)
{
    add_custom<<<blockDim, l2ctrl, stream>>>(x, y, z);
}

使用__global__函数类型限定符来标识它是一个核函数,可以被<<<…>>>调用;使用__aicore__函数类型限定符来标识该核函数在设备端AI Core上执行:

__global__ __aicore__ void kernel_name(argument list);

编程中使用到的函数可以分为三类:核函数(device侧执行)、host侧执行函数、device侧执行函数(除核函数之外的)。三者的调用关系如下图所示:
● host侧执行函数可以调用同类的host执行函数,也就是通用C/C++编程中的函数调用;也可以通过<<<>>>调用核函数。
● device侧执行函数(除核函数之外的)可以调用同类的device侧执行函数。
● 核函数可以调用device侧执行函数(除核函数之外的)。
在这里插入图片描述

Add算子代码分析

Add算子设计规格

在这里插入图片描述

核函数开发

调用算子类的Init和Process函数

extern "C" __global__ __aicore__ void add_custom(GM_ADDR x, GM_ADDR y, GM_ADDR z)
{
    KernelAdd op;
    op.Init(x, y, z);
    op.Process();
}

矢量编程范式实现算子类

class KernelAdd {
public:
__aicore__ inline KernelAdd(){}
// 初始化函数,完成内存初始化相关操作
__aicore__ inline void Init(GM_ADDR x, GM_ADDR y, GM_ADDR z){}
// 核心处理函数,实现算子逻辑,调用私有成员函数CopyIn、Compute、CopyOut完成矢量算子的三级流水操作
__aicore__ inline void Process(){}

private:
// 搬入函数,完成CopyIn阶段的处理,被核心Process函数调用
__aicore__ inline void CopyIn(int32_t progress){}
// 计算函数,完成Compute阶段的处理,被核心Process函数调用
__aicore__ inline void Compute(int32_t progress){}
// 搬出函数,完成CopyOut阶段的处理,被核心Process函数调用
__aicore__ inline void CopyOut(int32_t progress){}

private:
TPipe pipe;  //Pipe内存管理对象
TQue<QuePosition::VECIN, BUFFER_NUM> inQueueX, inQueueY;  //输入数据Queue队列管理对象,QuePosition为VECIN
TQue<QuePosition::VECOUT, BUFFER_NUM> outQueueZ;  //输出数据Queue队列管理对象,QuePosition为VECOUT
GlobalTensor<half> xGm, yGm, zGm;  //管理输入输出Global Memory内存地址的对象,其中xGm, yGm为输入,zGm为输出
};

内部函数调用关系
在这里插入图片描述
由此可见除了Init函数完成初始化外,Process中完成了对流水任务:“搬入、计算、搬出”的调用,开发者可以重点关注三个流水任务的实现。
核函数运行验证
异构计算架构中,NPU(kernel侧)与CPU(host侧)是协同工作的,完成了kernel侧核函数开发后,即可编写host侧的核函数调用程序,实现从host侧的APP程序调用算子,执行计算过程。
代码整体结构
● 调用算子的应用程序:main.cpp。
● 输入数据和真值数据生成脚本文件:gen_data.py。
● 验证输出数据和真值数据是否一致的验证脚本:verify_result.py。
● 编译cpu侧或npu侧运行的算子的编译工程文件:CMakeLists.txt。
● 编译运行算子的脚本:run.sh。
以调用算子的应用程序的编写为例
NPU侧运行算子的调用程序
在这里插入图片描述
完整代码

// AscendCL初始化
CHECK_ACL(aclInit(nullptr));
// 运行管理资源申请
aclrtContext context;
int32_t deviceId = 0;
CHECK_ACL(aclrtSetDevice(deviceId));
CHECK_ACL(aclrtCreateContext(&context, deviceId));
aclrtStream stream = nullptr;
CHECK_ACL(aclrtCreateStream(&stream));
// 分配Host内存
uint8_t *xHost, *yHost, *zHost;
uint8_t *xDevice, *yDevice, *zDevice;
CHECK_ACL(aclrtMallocHost((void**)(&xHost), inputByteSize));
CHECK_ACL(aclrtMallocHost((void**)(&yHost), inputByteSize));
CHECK_ACL(aclrtMallocHost((void**)(&zHost), outputByteSize));
// 分配Device内存
CHECK_ACL(aclrtMalloc((void**)&xDevice, inputByteSize, ACL_MEM_MALLOC_HUGE_FIRST));
CHECK_ACL(aclrtMalloc((void**)&yDevice, inputByteSize, ACL_MEM_MALLOC_HUGE_FIRST));
CHECK_ACL(aclrtMalloc((void**)&zDevice, outputByteSize, ACL_MEM_MALLOC_HUGE_FIRST));
// Host内存初始化
ReadFile("./input/input_x.bin", inputByteSize, xHost, inputByteSize);
ReadFile("./input/input_y.bin", inputByteSize, yHost, inputByteSize);
CHECK_ACL(aclrtMemcpy(xDevice, inputByteSize, xHost, inputByteSize, ACL_MEMCPY_HOST_TO_DEVICE));
CHECK_ACL(aclrtMemcpy(yDevice, inputByteSize, yHost, inputByteSize, ACL_MEMCPY_HOST_TO_DEVICE));
// 用内核调用符<<<>>>调用核函数完成指定的运算,add_custom_do中封装了<<<>>>调用
add_custom_do(blockDim, nullptr, stream, xDevice, yDevice, zDevice);
CHECK_ACL(aclrtSynchronizeStream(stream));
// 将Device上的运算结果拷贝回Host
CHECK_ACL(aclrtMemcpy(zHost, outputByteSize, zDevice, outputByteSize, ACL_MEMCPY_DEVICE_TO_HOST));
WriteFile("./output/output_z.bin", zHost, outputByteSize);
// 释放申请的资源
CHECK_ACL(aclrtFree(xDevice));
CHECK_ACL(aclrtFree(yDevice));
CHECK_ACL(aclrtFree(zDevice));
CHECK_ACL(aclrtFreeHost(xHost));
CHECK_ACL(aclrtFreeHost(yHost));
CHECK_ACL(aclrtFreeHost(zHost));
// AscendCL去初始化
CHECK_ACL(aclrtDestroyStream(stream));
CHECK_ACL(aclrtDestroyContext(context));
CHECK_ACL(aclrtResetDevice(deviceId));
CHECK_ACL(aclFinalize());

编译运行

bash run.sh -r npu -v Ascend910A

输出结果

Scanning dependencies of target add_npu
[ 33%] Building CCE object cmake/npu/CMakeFiles/add_npu.dir/__/__/add_custom.cpp.o
[ 66%] Building CCE object cmake/npu/CMakeFiles/add_npu.dir/__/__/main.cpp.o
[100%] Linking CCE executable ../../../add_npu
[100%] Built target add_npu
INFO: compile op on npu succeed!
INFO: execute op on npu succeed!
test pass

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

stable diffusion 模型融合

【抛砖引玉】GhostMixV2.0的制作过程及关于Checkpoint模型融合的一点经验 - 知乎大家好,我是Ghost_Shell,也是GhostMix的作者。本来想写一篇文章整体介绍一下模型,一些你们可能没察觉到,但我非常固执的理念,也算是模型的特性。结果发现写太长了,就分开两部分,第一部分是…

技术驱动会展:展位导航系统的架构与实现

随着会展行业的快速发展&#xff0c;大型会展中心面临着如何提升参展者体验、提高招商效率的挑战。针对客户反馈的展馆面积大、展位查找困难等问题&#xff0c;维小帮提出一套智慧会展导航解决方案&#xff0c;旨在通过先进的室内导航技术提升会展中心的运营效率和参展者的满意…

后端实现预览pdf,mp4,图片

PDF预览 /*** pdf预览* param response*/RequestMapping(value "/preview")public void showPdf(HttpServletResponse response) {try {//String filePath this.getClass().getClassLoader().getResource("../../static/pdf/readme.pdf").getPath();Stri…

cad批量打印pdf怎么弄?介绍三种打印方法

cad批量打印pdf怎么弄&#xff1f;在CAD设计领域&#xff0c;批量打印PDF文件是一项常见且至关重要的任务。面对大量的CAD图纸&#xff0c;如何高效地进行转换和打印&#xff0c;成为了设计师们亟待解决的问题。今天&#xff0c;我们就来推荐三款能够批量打印PDF的CAD软件&…

2024年6月15日 (周六) 叶子游戏新闻

期刊杂志: 聚合读者、意林、知音、故事会、花火以及国内各大知名报纸电子版&#xff0c;无需付费即可观看各种免费资源 中医自学宝典: 集合了中医医案&#xff0c;医经&#xff0c;方剂 药材知识的app&#xff0c;更方便的免费学习中医知识 《赛博朋克2077》被取消DLC泄露&…

基于语音识别的智能电子病历(五)电子病历编辑器

前言 首先我们要明确一个概念&#xff1a;很多电子病历的编辑器&#xff0c;在输入文字的地方&#xff0c;有个麦克风按钮&#xff0c;点击一下&#xff0c;可以进行录音&#xff0c;然后识别的文字会自动输入到电子病历中&#xff0c;这种方式其实不能称为“基于语音识别的智…

WPF/C#:数据绑定到方法

在WPF Samples中有一个关于数据绑定到方法的Demo&#xff0c;该Demo结构如下&#xff1a; 运行效果如下所示&#xff1a; 来看看是如何实现的。 先来看下MainWindow.xaml中的内容&#xff1a; <Window.Resources><ObjectDataProvider ObjectType"{x:Type local…

湖南科技大学24计算机考研情况,软工学硕考数二,分数线290分,录取均分321分!

湖南科技大学&#xff08;Hunan University of Science and Technology&#xff09;坐落在伟人故里、人文圣地湘潭&#xff0c;处于长株潭核心区域&#xff0c;比邻湘潭九华经济技术开发区&#xff08;国家级&#xff09;&#xff0c;是应急管理部、国家国防科技工业局与湖南省…

全面国产化之路-信创

概叙 信创&#xff0c;即信息技术应用创新产业&#xff0c;这个词儿最早来源于“信创工委会”&#xff08;全称是信息技术应用创新工作委员会&#xff09;&#xff0c;是在2016年由24家专业从事软硬件关键技术研究及应用的国内单位共同发起成立的一个非营利性社会组织。后…

vulnhub靶场之FunBox-11

一.环境搭建 1.靶场描述 As always, its a very easy box for beginners. Add to your /etc/hosts: funbox11 This works better with VirtualBox rather than VMware. 2.靶场下载 https://www.vulnhub.com/entry/funbox-scriptkiddie,725/ 3.靶场启动 二.信息收集 1.寻找靶…

Python文件与面向对象知识点

目录 文件的基本概念 文件的读取 文件的追加 文件的写入 with语句 知识总结 面向对象的基本概念 类和实例 对象的属性和方法 类属性与方法 面向对象的三大特性 知识总结 文件的基本概念 文件的读取 文件的追加 文件的写入 with语句 知识总结 面向对象的基本概念 …

vue项目build 打包之后如何本地访问

vue项目build 打包之后如何本地访问 注意&#xff1a;vue项目build打包后 如果想实现本地访问 不能直接打开访问dist文件中的HTML文件&#xff08;因为页面带会报错打不开。&#xff09;&#xff0c;需要启一个服务&#xff0c;通过服务来访问&#xff1a; 具体操作过程如下&am…

Avalonia:一个.NET跨平台UI框架

概述 Avalonia是一个强大的框架&#xff0c;使开发人员能够使用. NET创建跨平台应用程序。它使用自己的渲染引擎来绘制UI控件&#xff0c;确保在各种平台上保持一致的外观和行为&#xff0c;包括Windows&#xff0c;macOS&#xff0c;Linux&#xff0c;Android&#xff0c;iOS…

Omnivore:全能开源稍后阅读神器,让文字爱好者畅享阅读乐趣!

热门开源项目推荐 项目地址&#x1f517;&#x1f517;&#x1f517;&#x1f517; https://gitcode.com/omnivore-app/omnivore/overview Omnivore&#xff1a;全能开源稍后阅读神器 Omnivore App 介绍 Omnivore是一个完整的开源稍后阅读解决方案&#xff0c;专为喜欢文字…

复分析——第6章—— Γ 函数和 ζ 函数(E.M. Stein R. Shakarchi)

第6章 Γ函数和Ζ函数(The Gamma and Zeta Functions) 毫不夸张地说&#xff0c;Γ函数和Ζ函数是数学中最重要的非初等函数之一。Γ函数在自然界中无处不在。它出现在大量计算中&#xff0c;并以分析中出现的大量恒等式为特征。对此的部分解释可能在于Γ函数的基本结构特性&…

树和二叉树的定义

目录 一、树的定义 1.1概念 1.2表示方式 1.3基本术语 1.4树结构和线性结构的比较 二、二叉树的定义 2.1概念 2.2二叉树的5种基本形态 三、二叉树的性质和存储结构 3.1二叉树的性质 3.1.1满二叉树 3.1.2完全二叉树 3.2二叉树的存储结构 3.2.1二叉树的顺序存储 3.2.…

Go语言开发框架GoFly已集成数据可视化大屏开发功能,让开发者只专注业务开发,本文指导大家如何使用

前言 框架提供数据大屏开发基础&#xff0c;是考虑当前市场软件应用有一大部分是需要把业务数据做出大屏&#xff0c;很多政府项目对大屏需求特别高&#xff0c;还有生产企业项目也对大屏有需求&#xff0c;没有提供基础规范的后台框架&#xff0c;在开发大屏需要很多时间去基…

AI大模型填报高考志愿靠谱吗?AI自己说:完全靠我不行

靠天靠地靠AI&#xff0c;最后还得靠自己。 2024年高考已经结束。近日&#xff0c;全国多个省份陆续公布高考查分时间和方式&#xff0c;大部分集中在6月25日左右。报什么学校、选什么专业&#xff0c;又成为考生和家长面临的一次大考。 人们常说&#xff0c;“高考七分报&am…

C malloc经典面试题解答与分析

本篇博客介绍关于C malloc经典的错误代码写法以及解决方法。 题目1 错误的代码&#xff1a; #include <iostream>void test01(char* p) {p (char*)malloc(10); }int main1() {char* p NULL;test01(&p);const char* str "hello";strcpy(p, str);print…

基于STM32的智能温室控制系统

目录 引言环境准备智能温室控制系统基础代码实现&#xff1a;实现智能温室控制系统 4.1 温湿度传感器数据采集4.2 光照传感器数据采集4.3 控制系统实现4.4 用户界面与数据可视化应用场景&#xff1a;智能温室管理与优化问题解决方案与优化收尾与总结 1. 引言 智能温室控制系…