如何调用Ascend C算子

news2024/9/28 16:16:48

Ascend C是CANN针对算子开发场景推出的编程语言,原生支持C和C++标准规范,兼具开发效率和运行性能。基于Ascend C编写的算子程序,通过编译器编译和运行时调度,运行在昇腾AI处理器上。使用Ascend C,开发者可以基于昇腾AI硬件高效实现自定义的创新算法。

本文重点介绍基于Ascend C算子编程语言完成自定义算子的开发和部署后,如何调用自定义算子验证算子功能。

三种常见的算子调用方式

目前,Ascend C算子有三种常见的调用方式:

  • Kernel直调:完成算子核函数开发和Tiling实现后,可基于内核调用符方式进行完成算子的调用,用来快速验证算法逻辑。
  • 单算子调用:相比于Kernel直调,单算子调用是一种较为标准的调用方式。开发者在完成所有算子交付件开发、编译部署之后,一般通过单算子调用方式验证单算子功能以满足交付条件,包括两种调用方式:
  • 单算子API执行:基于C语言的API执行算子,直接调用单算子API接口,无需提供单算子描述文件进行离线模型的转换。
  • 单算子模型执行:基于图IR执行算子,先编译算子(例如,使用ATC工具将Ascend IR定义的单算子描述文件编译成算子om模型文件),再调用AscendCL接口加载算子模型,最后调用AscendCL接口执行算子。
  • 在PyTorch、ONNX、TensorFlow等三方框架中调用算子:需要完成框架适配开发,即可从第三方框架实现算子调用。

当然,除了可以调用自定义算子进行功能验证外,开发者也可以通过单算子调用方式直接调用昇腾算子库中预制的算子,使用昇腾算力。

通过单算子API执行方式调用算子

通过单算子API执行方式调用算子,是算子交付阶段最重要的一种调用方式,也是Ascend C算子开发人员必须掌握的算子调用手段,下面做重点讲解。开发者若想了解其他方式,可以移至文末查阅“Ascend C一站式学习资源”[1]。

Ascend C算子开发并编译部署完成后,会在算子包安装目录下的op_api目录下会自动生成单算子API,以默认安装场景为例,单算子调用的头文件.h和动态库libcust_opapi.so所在的目录结构为:

├── opp    //算子库目录 
│   ├── vendors     //自定义算子所在目录 
│       ├── config.ini 
│       └── vendor_name1   // 存储对应厂商部署的自定义算子,此名字为编译自定义算子安装包时配置的vendor_name,若未配置,默认值为customize 
│           ├── op_api 
│           │   ├── include 
│           │   │  └── aclnn_xx.h 
│           │   └── lib 
│           │       └── libcust_opapi.so 
...

aclnn_xx.h中的算子API形式一般定义为“两段式接口”,形如:

aclnnStatus aclnnXxxGetWorkspaceSize(const aclTensor *src, ..., aclTensor *out, uint64_t workspaceSize, aclOpExecutor **executor); 
aclnnStatus aclnnXxx(void* workspace, int64 workspaceSize, aclOpExecutor* executor, aclrtStream stream);

单算子API可以直接在应用程序中调用,大致过程为:

  1. 使用第一段接口aclnnXxxGetWorkspaceSize计算本次API调用计算过程中需要多少的workspace内存
  2. 获取到本次API计算需要的workspace大小后,按照workspaceSize大小申请Device侧内存
  3. 调用第二段接口aclnnXxx,调用对应的单算子二进制执行计算

完整调用流程如下:

1.png

下面提供单算子调用的关键代码示例,供开发者参考:

// 1.AscendCL初始化 
aclRet = aclInit("../scripts/acl.json"); 
 
// 2.运行管理资源申请 
int deviceId = 0; 
aclRet = aclrtSetDevice(deviceid); 
// 获取软件栈的运行模式,不同运行模式影响后续的接口调用流程(例如是否进行数据传输等) 
aclrtRunMode runMode; 
bool g_isDevice = false; 
aclError aclRet = aclrtGetRunMode(&runMode); 
g_isDevice = (runMode == ACL_DEVICE); 
 
// 3.申请内存存放算子的输入输出 
// ...... 
 
// 4.传输数据 
if (aclrtMemcpy(devInputs_[i], size, hostInputs_[i], size, kind) != ACL_SUCCESS) { 
    return false; 
} 
 
// 5.计算workspace大小并申请内存 
size_t workspaceSize = 0; 
aclOpExecutor *handle = nullptr; 
auto ret = aclnnAddCustomGetWorkspaceSize(inputTensor_[0], inputTensor_[1], outputTensor_[0], 
                                          &workspaceSize, &handle); 
// ... 
void *workspace = nullptr; 
if (workspaceSize != 0) { 
    if (aclrtMalloc(&workspace, workspaceSize, ACL_MEM_MALLOC_NORMAL_ONLY) != ACL_SUCCESS) { 
        ERROR_LOG("Malloc device memory failed"); 
    } 
} 
 
// 6.执行算子 
if (aclnnAddCustom(workspace, workspaceSize, handle, stream) != ACL_SUCCESS) { 
    (void)aclrtDestroyStream(stream); 
    ERROR_LOG("Execute Operator failed. error code is %d", static_cast<int32_t>(ret)); 
    return false; 
} 
 
// 7.同步等待 
aclrtSynchronizeStream(stream); 
 
// 8.处理执行算子后的输出数据,例如在屏幕上显示、写入文件等,由用户根据实际情况自行实现 
// ...... 
 
// 9.释放运行管理资源 
aclRet = aclrtResetDevice(deviceid); 
// .... 
 
// 10.AscendCL去初始化 
aclRet = aclFinalize();

运行一个完整的算子调用程序

昇腾的gitee仓中提供了完整的样例工程LINK,工程目录结构如下:

├──input                                                 // 存放脚本生成的输入数据目录 
├──output                                                // 存放算子运行输出数据和真值数据的目录 
├── inc                           // 头文件目录  
│   ├── common.h                 // 声明公共方法类,用于读取二进制文件  
│   ├── operator_desc.h          // 算子描述声明文件,包含算子输入/输出,算子类型以及输入描述与输出描述  
│   ├── op_runner.h              // 算子运行相关信息声明文件,包含算子输入/输出个数,输入/输出大小等  
├── src  
│   ├── CMakeLists.txt    // 编译规则文件 
│   ├── common.cpp         // 公共函数,读取二进制文件函数的实现文件 
│   ├── main.cpp    // 单算子调用应用的入口 
│   ├── operator_desc.cpp     // 构造算子的输入与输出描述  
│   ├── op_runner.cpp   // 单算子调用主体流程实现文件 
├── scripts 
│   ├── verify_result.py    // 真值对比文件 
│   ├── gen_data.py    // 输入数据和真值数据生成脚本文件 
│   ├── acl.json    // acl配置文件

步骤1 增加头文件引用。

安装部署完成后,会在算子包安装目录下的op_api目录生成单算子调用的头文件aclnn_xx.h和动态库libcust_opapi.so,编写单算子的调用代码时,要包含自动生成的单算子API执行接口头文件:

#include "aclnn_add_custom.h"

步骤2 修改CMakeLists文件。

编译算子调用程序时,需要在头文件的搜索路径include_directories中增加算子包安装目录下的op_api/include目录,便于找到该头文件;同时需要链接cust_opapi动态库。

  • 设置CUST_PKG_PATH变量为算子包安装目录下的op_api目录,以下样例仅为参考,请根据算子包部署的实际目录位置进行设置。
if (NOT DEFINED ENV{DDK_PATH}) 
    set(INC_PATH "/usr/local/Ascend/ascend-toolkit/latest") 
    message(STATUS "set default INC_PATH: ${INC_PATH}") 
else () 
    message(STATUS "env INC_PATH: ${INC_PATH}") 
endif() 
set(CUST_PKG_PATH "${INC_PATH}/opp/vendors/customize/op_api")
  • 在头文件的搜索路径include_directories中增加算子包安装目录下的op_api/include目录。
include_directories( 
    ${INC_PATH}/runtime/include 
    ${INC_PATH}/atc/include 
    ../inc 
    ${CUST_PKG_PATH}/include 
)
  • 链接cust_opapi链接库。
target_link_libraries(execute_add_op 
    ascendcl 
    cust_opapi 
    acl_op_compiler 
    nnopbase 
    stdc++ 
)

步骤3 生成测试数据。

在样例工程目录下,执行如下命令:

python3 scripts/gen_data.py

会在工程目录下input目录中生成两个shape为(8,2048),数据类型为float16的数据文件input_0.bin与input_1.bin,用于进行AddCustom算子的验证。代码样例如下:

import numpy as np 
a = np.random.randint(100, size=(8, 2048,)).astype(np.float16) 
b = np.random.randint(100, size=(8, 2048,)).astype(np.float16) 
a.tofile('input_0.bin') 
b.tofile('input_1.bin')

步骤4 程序编译与运行。

1. 开发环境上,设置环境变量,配置AscendCL单算子验证程序编译依赖的头文件与库文件路径,如下为设置环境变量的示例。${INSTALL_DIR}表示CANN软件安装目录,例如,$HOME/Ascend/ascend-toolkit/latest。{arch-os}为运行环境的架构和操作系统,arch表示操作系统架构,os表示操作系统,例如x86_64-linux。

export DDK_PATH=${INSTALL_DIR} 
export NPU_HOST_LIB=${INSTALL_DIR}/{arch-os}/lib64

2. 编译样例工程,生成单算子验证可执行文件。

a. 切换到样例工程根目录,然后在样例工程根目录下执行如下命令创建目录用于存放编译文件,例如,创建的目录为“build”。

mkdir -p build

b. 进入build目录,执行cmake编译命令,生成编译文件,命令示例如下所示:

cd build 
cmake ../src

c. 执行如下命令,生成可执行文件。

make

会在工程目录的output目录下生成可执行文件execute_add_op。

3. 执行单算子。

a. 以运行用户(例如HwHiAiUser)拷贝开发环境中样例工程output目录下的execute_add_op到运行环境任一目录。

说明: 若您的开发环境即为运行环境,此拷贝操作可跳过。

b. 在运行环境中,执行execute_add_op:

chmod +x execute_add_op 
./execute_add_op

会有如下屏显信息:

[INFO]  Set device[0] success 
[INFO]  Get RunMode[1] success 
[INFO]  Init resource success 
[INFO]  Set input success 
[INFO]  Copy input[0] success 
[INFO]  Copy input[1] success 
[INFO]  Create stream success 
[INFO]  Execute aclnnAddCustomGetWorkspaceSize success, workspace size 0 
[INFO]  Execute aclnnAddCustom success 
[INFO]  Synchronize stream success 
[INFO]  Copy output[0] success 
[INFO]  Write output success 
[INFO]  Run op success 
[INFO]  Reset Device success 
[INFO]  Destory resource success

如果有Run op success,表明执行成功,会在output目录下生成输出文件output_z.bin。

4. 比较真值文件。

切换到样例工程根目录,然后执行如下命令:

python3 scripts/verify_result.py output/output_z.bin output/golden.bin

会有如下屏显信息:

test pass

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

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

相关文章

【ADC】ΔΣ ADC 中数字滤波器的延迟以及 SAR ADC 与 ΔΣ ADC 的差异对比总结

本文学习于TI 高精度实验室课程&#xff0c;深入探讨 delta-sigma 转换器中使用的数字滤波器。具体来说&#xff0c;本文将重点介绍数字滤波器如何引入延迟&#xff0c;因为这是 SAR 和 delta-sigma ADC 之间的显著差异。 文章目录 一、低延迟数字滤波器二、高延迟数字滤波器三…

MSVCR100.dll丢失怎么办,教你6种解决MSVCR100.dll丢失的方法

在计算机的日常使用中&#xff0c;我们可能会遇到各种各样的问题&#xff0c;其中之一就是MSVCR100.dll文件丢失。这个文件是Microsoft Visual C 2010的一个组件&#xff0c;如果丢失&#xff0c;可能会导致某些程序无法正常运行。那么&#xff0c;如何解决这个问题呢&#xff…

拉取指定版本的代码

// 获取指定版本的分支 https://git.swf.daimler.com/mbient/meta-mbient/-/blob/release/E066.1-2024.07.31-457-4870220-4882586/meta-mbient/recipes-mbient/dialog-domain-handlers/dialog-domain-handlers_git.bb?ref_typetags meta-mbient meta-mbient recipes-mbient …

大数据新视界 --大数据大厂之 Spark Streaming 实时数据处理框架:案例与实践

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

如何通过10个简单步骤,让AI创作效率翻倍,性能提升90%

本文背景 随着不断深入地使用 AI 以及体验更多产品 最近对于大模型的使用感悟又有了一些新收获。 今天&#xff0c;特意来和大家分享 10 个大模型的使用妙招 。 这既是分享&#xff0c;也是我自己的学习梳理。 下面介绍的这些技巧&#xff0c;适用于所有大模型应用&#xff08;…

9月26日

1.虚函数与纯虚函数&#xff1a; 在类中定义函数时&#xff0c;在函数前加关键字 virtual &#xff0c;允许在派生类中重写的方法。那么该函数就是虚函数。 纯虚函数&#xff1a;没有实现的方法&#xff0c;用于定义接口。 2.基类为什么需要虚析构函数&#xff1a; 确保删除派生…

使用 Higress AI 插件对接通义千问大语言模型

前言 什么是 AI Gateway AI Gateway 的定义是 AI Native 的 API Gateway&#xff0c;是基于 API Gateway 的能⼒来满⾜ AI Native 的需求。例如&#xff1a; 将传统的 QPS 限流扩展到 token 限流。将传统的负载均衡/重试/fallback 能力延伸&#xff0c;支持对接多个大模型厂…

深入浅出 AbstractQueuedSynchronizer (AQS)

文章目录 什么是 AQSAQS 的工作原理同步状态&#xff08;state&#xff09;等待队列 AQS 是如何让线程排队并唤醒的公平锁和非公平锁AQS 的应用场景ReentrantLock&#xff08;可重入锁&#xff09;AQS 在 ReentrantLock 中的工作原理典型应用场景 CountDownLatch&#xff08;倒…

基于Django技术开发的酒店信息管理系统,包括员工用户功能和管理员用户功能两部分

项目摘要 该项目是基于Django技术开发的一套酒店管理系统&#xff0c;系统应用浏览器/服务期&#xff08;Browser/Server&#xff09;架构。系统主要包括员工用户功能和管理员用户功能两部分。开发员工信息管理、顾客信息管理、会员信息管理、停车场信息管理、餐厅信息管理、客…

HTML5+CSS3小实例:立方体控件的登录表单

实例:立方体控件的登录表单 技术栈:HTML+CSS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial…

【算法篇】二叉树类(1)(笔记)

目录 一、认识二叉树 1. 二叉树的种类 &#xff08;1&#xff09;满二叉树 &#xff08;2&#xff09;完全二叉树 &#xff08;3&#xff09;二叉搜索树 &#xff08;4&#xff09;平衡二叉搜索树 2. 二叉树的存储方式 3. 二叉树的遍历方式 4. 二叉树的定义 二、Leet…

(done) 使用泰勒展开证明欧拉公式

问问神奇的 GPT&#xff0c;how to prove euler formula? 一个答案如下&#xff1a;

华硕NUC亮相工博会,解锁工业AI PC解决方案

2024年9月24日至28日&#xff0c;中国国际工业博览会于上海国家会展中心盛大举行&#xff0c;华硕智能物联网展台位于展馆6.1H E183展位&#xff0c;在展位上华硕向大众展示了智能AI、物联网设备、华硕NUC等解决方案及IoT硬件产品&#xff0c;吸引了众多专业观众驻足交流和体验…

线程池的执行流程和配置参数总结

一、线程池的执行流程总结 提交线程任务&#xff1b;如果线程池中存在空闲线程&#xff0c;则分配一个空闲线程给任务&#xff0c;执行线程任务&#xff1b;线程池中不存在空闲线程&#xff0c;则线程池会判断当前线程数是否超过核心线程数&#xff08;corePoolSize&#xff09…

EfficientViT(2023CVPR):具有级联组注意力的内存高效视觉Transformer!

EfficientViT: Memory Efficient Vision Transformer with Cascaded Group Attention EfficientViT: 具有级联组注意力的内存高效视觉Transformer 万文长字&#xff0c;请耐心观看~ 论文地址&#xff1a; https://arxiv.org/abs/2305.07027 代码地址&#xff1a; Cream/Effici…

计算机毕业设计 饮食营养管理信息系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

《强化学习的数学原理》(2024春)_西湖大学赵世钰 Ch9 策略梯度方法 -9.3.1

之前看了 2 次视频&#xff0c;公式有点多&#xff0c; 还是没整理出来。 这个版本是以下步骤后的版本 基本把相关的核心论文过了一遍&#xff0c;代码整理了部分 PDF 资料 整理 v3 链接 视频 链接 习题 策略梯度方法需要估计值 函数近似&#xff1a; 状态/动作 价值、策略 参…

C++初阶:STL详解(四)——vector迭代器失效问题

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C&#xff1a;由浅入深篇 小新的主页&#xff1a;编程版小新-CSDN博客 一&#xff1a;迭代器失效的本质 迭代器的主…

VulnStack-红日靶机(二)

红日靶机二 环境搭建 只需要把虚拟机的 host-only&#xff08;仅主机&#xff09;网卡改为 10.10.10.0 网段&#xff0c;如下配置 把 NAT 网卡&#xff0c;改为 192.168.96.0 网段&#xff0c;如下 首先恢复到 v1.3 快照 让后点击放弃&#xff0c;放弃后再开机&#xff0c;用…

Shopify独立站运营必知必会:选品与防封技巧

独立站和第三方平台是目前最常见的跨境电商销售模式&#xff0c;相比于第三方平台&#xff0c;独立站的商家可以自己建站&#xff0c;自行决定运营模式和营销手段等策略&#xff0c;尤其是在准入门槛上&#xff0c;难度会更低&#xff0c;这些特点吸引了不少商家选择独立站开店…