news 2026/5/22 9:32:35

CANN/asc-devkit RTC运行时编译指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN/asc-devkit RTC运行时编译指南

RTC

【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit

RTC是Ascend C运行时编译库,通过aclrtc接口,在程序运行时,将中间代码动态编译成目标机器码,提升程序运行性能。

运行时编译库提供以下核心接口:

  • aclrtcCreateProg:根据输入参数(字符串形式表达的Ascend C源代码等)创建aclrtcProg程序实例。
  • aclrtcAddNameExpr(可选):注册需要导出的核函数名表达式,支持模板参数(如 "Kernel::add_custom<float>"),非模板核函数可跳过。
  • aclrtcCompileProg:编译给定的程序,支持用户自定义编译选项,比如指定NPU架构版本号:--npu-arch=dav-2201。支持的编译选项可以参考《毕昇编译器用户指南》。
  • aclrtcGetBinDataSize:获取编译后的Device侧二进制数据的大小。
  • aclrtcGetBinData:获取编译后的Device侧二进制数据。
  • aclrtcGetLoweredName(可选):获取核函数编译后的mangled name,用于后续通过aclrtBinaryGetFunction查找核函数句柄,非模板核函数可跳过。
  • aclrtcDestroyProg:在编译和执行过程结束后,销毁给定的程序。

编译完成后需要调用如下接口完成(仅列出核心接口)Kernel加载与执行。完整流程和详细接口说明请参考《Runtime运行时API》中的“Kernel加载与执行”章节。

  1. 通过aclrtBinaryLoadFromData接口解析由aclrtcGetBinData接口获取的算子二进制数据。
  2. 获取核函数句柄并根据核函数句柄操作其参数列表,相关接口包括aclrtBinaryGetFunction(获取核函数句柄)、aclrtKernelArgsInit(初始化参数列表)、aclrtKernelArgsAppend(追加拷贝用户设置的参数值如xDevice, yDevice, zDevice)等。
  3. 调用aclrtLaunchKernelWithConfig接口,启动对应算子的计算任务。

如下样例演示了如何使用aclrtc接口编译并运行一个核函数,该核函数中调用了printf进行打印。完整样例请参考LINK。

#include <cstdio> #include <vector> #include "acl/acl.h" #include "acl/acl_rt_compile.h" // 使用aclrtc接口需要包含的头文件 #ifndef ACL_RTC_NPU_ARCH #define ACL_RTC_NPU_ARCH "dav-2201" #endif #define ASCENDC_CHECK(expr) do { \ aclError ret = (expr); \ if (ret != ACL_SUCCESS) { \ fprintf(stderr, \ "Ascend Error: %s:%d code=%d %s\n",\ __FILE__, __LINE__, \ ret, aclGetRecentErrMsg()); \ return ret; \ } \ } while(0) const char *src = R""""( #include "debug/asc_printf.h" extern "C" __global__ __vector__ void hello_world() { printf("Hello World!!!\n"); } )""""; int main(int argc, char *argv[]) { aclrtcProg prog; ASCENDC_CHECK(aclrtcCreateProg(&prog, src, "hello_world.asc", 0, nullptr, nullptr)); // aclrtc流程,传入毕昇编译器的编译选项,调用aclrtcCompileProg进行编译 const char *options[] = { "--npu-arch=" ACL_RTC_NPU_ARCH, }; int numOptions = sizeof(options) / sizeof(options[0]); aclError ret = aclrtcCompileProg(prog, 1, options); if (ret != ACL_SUCCESS) { // 编译报错时打印错误信息 size_t size = 0; (void)aclrtcGetCompileLogSize(prog, &size); char log[size] = {0}; (void)aclrtcGetCompileLog(prog, log); printf("Compile Error Log : %s", log); } // aclrtc流程,获取Device侧二进制内容和大小 size_t binDataSizeRet; ASCENDC_CHECK(aclrtcGetBinDataSize(prog, &binDataSizeRet)); std::vector<char> deviceELF(binDataSizeRet); ASCENDC_CHECK(aclrtcGetBinData(prog, deviceELF.data())); // ----------------------------------------------- aclrt part ------------------------------------------------ aclrtBinHandle binHandle = nullptr; aclrtBinaryLoadOptions loadOption; loadOption.numOpt = 1; aclrtBinaryLoadOption option; option.type = ACL_RT_BINARY_LOAD_OPT_LAZY_MAGIC; option.value.magic = ACL_RT_BINARY_MAGIC_ELF_AICORE; loadOption.options = &option; ASCENDC_CHECK(aclrtSetDevice(0)); ASCENDC_CHECK(aclrtBinaryLoadFromData(deviceELF.data(), binDataSizeRet, &loadOption, &binHandle)); aclrtFuncHandle funcHandle = nullptr; const char *funcName = "hello_world"; ASCENDC_CHECK(aclrtBinaryGetFunction(binHandle, funcName, &funcHandle)); aclrtArgsHandle argsHandle = nullptr; ASCENDC_CHECK(aclrtKernelArgsInit(funcHandle, &argsHandle)); ASCENDC_CHECK(aclrtKernelArgsFinalize(argsHandle)); // 核函数执行 uint32_t numBlocks = 8; ASCENDC_CHECK(aclrtLaunchKernelWithConfig(funcHandle, numBlocks, nullptr, nullptr, argsHandle, nullptr)); ASCENDC_CHECK(aclrtSynchronizeDevice()); ASCENDC_CHECK(aclrtBinaryUnLoad(binHandle)); ASCENDC_CHECK(aclrtResetDevice(0)); // 编译和运行均已结束,销毁程序 ASCENDC_CHECK(aclrtcDestroyProg(&prog)); return 0; }

编译命令如下,编译时需要设置-I${ASCEND_HOME_PATH}/include,用于找到aclrtc相关头文件,并设置-L${ASCEND_HOME_PATH}/lib64链接alc_rtc动态库。

g++ rtc_hello_world.cpp -I${ASCEND_HOME_PATH}/include -L${ASCEND_HOME_PATH}/lib64 -lascendcl -lacl_rtc -o main

对于非模板核函数(如hello_world),编译器可自动导出符号,无需额外操作。
当核函数为模板函数时,编译器无法自动确定需要导出的特化实例,需要通过aclrtcAddNameExpr手动注册需要导出的核函数名(含模板参数);编译后通过aclrtcGetLoweredName获取mangled name,用于后续aclrtBinaryGetFunction查找句柄。

// 注册需要导出的核函数名(含模板参数) const char* kernelNameExpr = "Kernel::add_custom<float>"; aclrtcAddNameExpr(prog, kernelNameExpr); // ... 编译流程aclrtcCompileProg ... // 获取编译后的mangled name const char* manglingName = ""; aclrtcGetLoweredName(prog, kernelNameExpr, &manglingName);

完整样例请参考:rtc_template_add。

【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/22 9:32:27

FFXVIFix终极指南:3分钟解锁《最终幻想16》超宽屏与帧率限制

FFXVIFix终极指南&#xff1a;3分钟解锁《最终幻想16》超宽屏与帧率限制 【免费下载链接】FFXVIFix Migrated to https://codeberg.org/Lyall/FFXVIFix 项目地址: https://gitcode.com/gh_mirrors/ff/FFXVIFix 还在为《最终幻想16》的画面黑边和帧率卡顿烦恼吗&#xff…

作者头像 李华
网站建设 2026/5/22 9:26:23

Python爬虫实战:从零编写一个健壮的静态页面抓取器!

㊗️本期内容已收录至专栏《Python爬虫实战》&#xff0c;持续完善知识体系与项目实战&#xff0c;建议先订阅收藏&#xff0c;后续查阅更方便&#xff5e; ㊙️本期爬虫难度指数&#xff1a;⭐⭐⭐ (进阶) &#x1f250;福利&#xff1a; 一次订阅后&#xff0c;专栏内的所有文…

作者头像 李华
网站建设 2026/5/22 9:23:05

一个肖特基二极管的型号:B140HB

简 介&#xff1a; 本文介绍了利用AI查询肖特基二极管B140HB-13型号的过程。该二极管由每台半导体生产&#xff0c;耐压40V&#xff0c;导通电流1A&#xff0c;正向压降约0.53V。AI快速准确地识别了器件表面文字并匹配数据手册。文章还提到将使用该二极管设计电感耦合反向电源测…

作者头像 李华
网站建设 2026/5/22 9:16:27

CMS垃圾回收

CMS概念&#xff1a;CMS&#xff08;Concurrent Mark Sweep&#xff09;收集器是一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用&#xff0c;它是HotSpot虚拟机第一款真正意义上的并发收集器&#xff0c;它第一次实现了让垃圾收集线程与用户…

作者头像 李华
网站建设 2026/5/22 9:16:21

126、强化学习:在机器人运动控制中的实战

126、强化学习:在机器人运动控制中的实战 从一次“摔跤”说起 去年做四足机器人步态优化时,我遇到了一个让人抓狂的问题——传统MPC(模型预测控制)在粗糙地形上总是跑着跑着就侧翻。调了三个月的权重矩阵,换了四版动力学模型,结果还不如实验室新来的实习生用PPO算法训了…

作者头像 李华