新闻详情

新闻详情

首页 / 资讯中心 / 详情

CANN ops-transformer 两段式接口(aclnn API)调用机制与实践指南

发布时间:2026/9/19 6:02:20来源:尧图网络
CANN ops-transformer 两段式接口(aclnn API)调用机制与实践指南
CANN ops-transformer 两段式接口aclnn API调用机制与实践指南【免费下载链接】ops-transformer本项目是CANN提供的transformer类大模型算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-transformer两段式接口是 CANN ops-transformer 中基于单算子 API 执行方式调用算子时的标准范式先调用aclxxXxxGetWorkspaceSize获取本次调用所需的 workspace 临时内存大小再按需申请 NPU 内存最后调用aclxxXxx完成实际计算。本文以仓库中真实算子接口如 AttentionUpdate、AddExample及其头文件、示例代码为证据系统讲解两段式接口的调用流程、参数含义、内存管理、异常排查与编译运行方法帮助开发者写出正确、可复用的 aclnn API 调用代码。两段式接口概述在 CANN ops-transformer 中基于单算子 API 执行方式调用算子 API 时通常分为两段式样式形如aclnnStatus aclxxXxxGetWorkspaceSize(const aclTensor *src, ..., aclTensor *out, ..., uint64_t *workspaceSize, aclOpExecutor **executor); aclnnStatus aclxxXxx(void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream);其中aclxx表示算子接口前缀例如aclnnXxx表示对应的算子类型例如 Add 算子对应aclnnAdd、AttentionUpdate 算子对应aclnnAttentionUpdate。两段接口的协作关系为必须先调用第一段接口aclxxXxxGetWorkspaceSize用于计算本次 API 调用过程中需要多少 workspace 内存获取到计算所需的workspaceSize后按照workspaceSize申请 NPU 内存然后调用第二段接口aclxxXxx执行计算。说明workspace 是指除输入/输出外算子在 NPU 上完成计算所需要的临时内存workspaceSize表示临时内存的大小。第二段接口aclxxXxx(...)不能重复调用如下调用方式会出现异常aclxxXxxGetWorkspaceSize(...) aclxxXxx(...) aclxxXxx(...) // 重复调用会异常第一段接口aclxxXxxGetWorkspaceSize第一段接口负责规划。它基于输入/输出张量、算子属性以及设备信息完成参数校验、输出 shape 推导、tiling 计算并给出执行本次算子计算所需的最小 workspace 大小同时创建算子执行器aclOpExecutor。以仓库中 AttentionUpdate 算子为例其第一段接口声明位于 attention/attention_update/op_host/op_api/aclnn_attention_update.hACLNN_API aclnnStatus aclnnAttentionUpdateGetWorkspaceSize( const aclTensorList *lse, const aclTensorList *localOut, int64_t updateType, aclTensor *out, aclTensor *lseOut, uint64_t *workspaceSize, aclOpExecutor **executor);其参数语义与仓库头文件注释一致参数方向说明lseinNPU device 侧的aclTensorList数据类型支持 FLOAT32数据格式支持 NDlocalOutinNPU device 侧的aclTensorList数据类型支持 FLOAT32、FLOAT16、BFLOAT16数据格式支持 NDupdateTypeinint64_t控制lseOut是否输出支持 0、1分别表示不输出 / 输出 lseOutoutoutNPU device 侧的aclTensor数据类型支持 FLOAT32、FLOAT16、BFLOAT16数据格式支持 NDlseOutoutNPU device 侧的aclTensor作为 lse_m 可选输出数据类型支持 FLOAT32workspaceSizeout返回用户需要在 NPU device 侧申请的 workspace 大小executorout返回 op 执行器包含算子计算流程从 attention/attention_update/op_host/op_api/aclnn_attention_update.cpp 的源码实现可以看到第一段接口内部会做一系列校验与推导例如CheckNotNull逐项检查lse、localOut、out及列表内每个张量不为空指针CheckDtypeValid依据ATTENTION_UPDATE_DTYPE_SUPPORT_LIST等支持列表校验输入数据类型是否合法这些正是两段式接口提前暴露参数问题的价值所在——参数错误会在 GetWorkspaceSize 阶段即被拦截并返回错误码而不是等到真正执行时才失败。第二段接口aclxxXxx 执行计算第二段接口负责执行。它接收第一段接口返回的workspace指针、workspaceSize、executor以及用户指定的aclrtStream流将算子计算任务下发到 NPU。ACLNN_API aclnnStatus aclnnAttentionUpdate(void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream);其中executor是框架定义的一种执行器数据结构用来执行算子计算的容器。通常调用第一段接口aclxxXxxGetWorkspaceSize时框架会自动创建aclOpExecutor调用第二段接口aclxxXxx后会自动释放该对象参见 docs/zh/context/data_structure.md 中对aclOpExecutor的说明。这里需要特别强调的是原文档中的警告第二段接口aclxxXxx不能重复调用。因为executor在一次调用生命周期内只能消费一次重复调用会触发ACLNN_ERR_INNER_NOT_TRANS_EXECUTOR561102API 内部未调用 uniqueExecutor ReleaseTo等异常。正确的做法是一次GetWorkspaceSize 一次Xxx严格配对使用。workspace 内存的申请与释放workspaceSize返回的是字节大小用户需要自行在 NPU device 侧通过aclrtMalloc申请内存并在计算结束后通过aclrtFree释放。仓库示例 attention/attention_update/examples/test_aclnn_attention_update.cpp 中的标准写法为uint64_t workspaceSize 0; aclOpExecutor *executor nullptr; ret aclnnAttentionUpdateGetWorkspaceSize(lseList, localOutList, update_type, out, nullptr, workspaceSize, executor); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(aclnnAttentionUpdateGetWorkspaceSize failed. ERROR: %d\n, ret); return ret); // 根据第一段接口计算出的 workspaceSize 申请 device 内存 void *workspaceAddr nullptr; if (workspaceSize 0) { ret aclrtMalloc(workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(allocate workspace failed. ERROR: %d\n, ret); return ret); } // 调用第二段接口执行计算 ret aclnnAttentionUpdate(workspaceAddr, workspaceSize, executor, stream); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(aclnnAttentionUpdate failed. ERROR: %d\n, ret); return ret);要点必须判空workspaceSize 0时才需要申请内存若为 0 则传nullptr即可内存属性使用ACL_MEM_MALLOC_HUGE_FIRST标志申请 NPU 侧大页内存释放时机必须在流同步aclrtSynchronizeStream之后释放避免任务尚未完成时内存被回收使用智能指针如std::unique_ptrvoid, aclError (*)(void *)管理workspaceAddr可以在异常分支自动释放示例工程中即采用了该模式。完整的 aclnn API 调用流程两段式接口并非孤立的两个函数而是嵌入在一整套 aclnn API 调用流程中。仓库文档 docs/zh/invocation/quick_op_invocation.md 给出了完整的调用流程图完整调用步骤可归纳为以下七步以仓库示例 examples/add_example/examples/test_aclnn_add_example.cpp 和 AttentionUpdate 示例中的通用骨架为参考初始化 AscendCL调用aclInit、aclrtSetDevice、aclrtCreateStream完成 device/stream 初始化构造输入与输出使用aclrtMalloc申请张量内存、aclrtMemcpy搬运数据再调用aclCreateTensor创建aclTensor多个张量可组合为aclTensorList调用第一段接口aclxxXxxGetWorkspaceSize(...)得到workspaceSize与executor申请 workspace 内存按workspaceSize调用aclrtMalloc申请 device 内存调用第二段接口aclxxXxx(workspaceAddr, workspaceSize, executor, stream)同步等待调用aclrtSynchronizeStream(stream)等待异步任务执行结束固定写法获取输出并释放资源将 device 侧结果aclrtMemcpy拷回 host 侧打印依次aclDestroyTensor、aclrtFree、aclrtDestroyStream、aclrtResetDevice、aclFinalize。其中第 35 步即两段式接口的核心部分其余步骤为 aclnn API 调用的通用外壳。仓库中的算子示例如 attention/attention_update/examples/test_aclnn_attention_update.cpp均按此骨架组织可作为新算子调用的模板。返回码与异常排查两段式接口的每一段都会返回aclnnStatus状态码。常见返回码如下详见 docs/zh/context/aclnn_return_code.md状态码名称状态码值状态码说明ACLNN_SUCCESS0成功ACLNN_ERR_PARAM_NULLPTR161001参数校验错误参数中存在非法的 nullptrACLNN_ERR_PARAM_INVALID161002参数校验错误如输入的两个数据类型不满足输入类型推导关系ACLNN_ERR_RUNTIME_ERROR361001API 内部调用 npu runtime 的接口异常ACLNN_ERR_INNER_XXX561xxxAPI 内部发生异常其中与两段式接口生命周期强相关的内部异常码包括ACLNN_ERR_INNER_INFERSHAPE_ERROR561001API 内部进行输出 shape 推导发生错误ACLNN_ERR_INNER_TILING_ERROR561002API 内部做 npu kernel 的 tiling 时发生异常ACLNN_ERR_INNER_CREATE_EXECUTOR561101API 内部创建aclOpExecutor失败可能因为操作系统异常ACLNN_ERR_INNER_NOT_TRANS_EXECUTOR561102API 内部未调用 uniqueExecutor ReleaseTo典型场景即重复调用第二段接口ACLNN_ERR_INNER_OPP_KERNEL_PKG_NOT_FOUND561112没有加载到算子的二进制 kernel 库。排查方法对于异常状态码值可通过aclGetRecentErrMsg接口获取具体的错误信息。仓库文档 docs/zh/context/compile_and_run_sample.md 给出了实际排查示例——构造空指针q调用aclnnFlashAttentionScoreGetWorkspaceSize后aclnnFlashAttentionScoreGetWorkspaceSize failed. ERROR: 161001 [ERROR msg][PID:xxxx] xxx(timestamp) AclNN_Parameter_Error(EZ1001): The query cannot be nullptr.可以看到返回码 161001ACLNN_ERR_PARAM_NULLPTR配合aclGetRecentErrMsg能精确定位到具体是哪个参数为空这正是两段式接口第一段参数校验前置优势的体现。编译与运行两段式接口示例编写好包含两段式接口调用的.cpp文件后需要创建 CMakeLists.txt 并链接算子库。对于本项目标准内置算子依赖 ops-transformer 整包CMake 关键配置如下完整示例见 docs/zh/context/compile_and_run_sample.mdcmake_minimum_required(VERSION 3.18.4) project(ACLNN_EXAMPLE) add_compile_options(-stdc11) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ./bin) if(NOT $ENV{ASCEND_HOME_PATH} STREQUAL ) set(ASCEND_PATH $ENV{ASCEND_HOME_PATH}) else() set(ASCEND_PATH /usr/local/Ascend/cann) endif() set(INCLUDE_BASE_DIR ${ASCEND_PATH}/include) include_directories( ${INCLUDE_BASE_DIR} ${ASCEND_PATH}/include/aclnnop ) add_executable(opapi_test test_aclnn_xxx.cpp) target_link_libraries(opapi_test PRIVATE ${ASCEND_PATH}/lib64/libascendcl.so ${ASCEND_PATH}/lib64/libnnopbase.so ${ASCEND_PATH}/lib64/libopapi_math.so ${ASCEND_PATH}/lib64/libopapi_transformer.so ${ASCEND_PATH}/lib64/libc_sec.so)注意本项目编译生成算子样例时需额外链接libopapi_math.so动态库因为算子在实现过程中调用了部分 L0 接口这些接口封装在libopapi_math.so中因此在编译链接阶段需显式声明此项依赖。若调用自定义算子如 experimental 贡献目录下算子则需将libopapi_transformer.so替换为自定义算子包中的libcust_opapi.so并增加${ASCEND_PATH}/opp/vendors/${vendor_name}_transformer/op_api/include头文件路径${vendor_name}默认为custom。编译运行流程# 1. 生效 CANN 环境变量${INSTALL_DIR} 为 CANN 软件安装路径 source ${INSTALL_DIR}/set_env.sh # 2. 新建 build 目录并编译 mkdir -p build cd build cmake ../ -DCMAKE_CXX_COMPILERg -DCMAKE_SKIP_RPATHTRUE make # 3. 运行生成的可执行文件 cd bin ./opapi_test若执行结果报错、未出现预期结果可使用aclGetRecentErrMsg接口获取报错具体信息调用方式见上文返回码与异常排查一节。小结两段式接口是 CANN ops-transformer 中所有 aclnn API 的统一调用范式GetWorkspaceSize负责参数校验、shape 推导与 workspace 规划Xxx负责执行计算。正确使用两段式接口的关键在于严格先调第一段、按返回的workspaceSize申请内存、第二段只调用一次、计算完成后再释放内存并结合aclGetRecentErrMsg与返回码表进行问题定位。读者可进一步阅读仓库中的 两段式接口本文依据、数据结构、算子调用总览 与 编译运行样例并结合各算子目录下的examples/test_aclnn_*.cpp示例文件加深理解。【免费下载链接】ops-transformer本项目是CANN提供的transformer类大模型算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-transformer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

CMSIS-4不是标准而是遗产协议:嵌入式静态工程深度评测指南 2026/9/19 6:59:28

CMSIS-4不是标准而是遗产协议:嵌入式静态工程深度评测指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Foundry Solidity测试原理与实战:EVM状态机驱动的合约验证 2026/9/19 6:59:28

Foundry Solidity测试原理与实战:EVM状态机驱动的合约验证

1. 为什么 Solidity 测试不能照搬 Java 或 Python 那套逻辑?刚从 Java 接口自动化测试框架或 pytest 测试框架转过来的朋友,第一眼看到forge test命令时,大概率会下意识敲出pytest tests/或mvn test—— 然后发现报错:command not…

阅读更多 →
Python爬虫实战:马蜂窝旅游数据采集与可视化 2026/9/19 6:59:28

Python爬虫实战:马蜂窝旅游数据采集与可视化

简介:面向旅游信息爬取与数据分析的应用场景,Python技术文档资源包共含1个doc文档,大小2.25MB,内容完整且结构清晰,适合Python初学者、数据分析爱好者以及需要完成课程设计或毕业设计的学生。文档以马蜂窝旅游网站为实…

阅读更多 →
Advanced SystemCare 系统优化实战:从C盘爆红到稳定维护的完整指南 2026/9/19 6:59:28

Advanced SystemCare 系统优化实战:从C盘爆红到稳定维护的完整指南

1. 为什么我还在用 Advanced SystemCare 做系统优化1.1 从一次C盘爆红说起大概两三年前,我手头一台用了快四年的笔记本突然开始频繁弹窗提示C盘空间不足,开机时间从十几秒一路涨到一分半,打开浏览器都要转好几圈。那台机器配置不算差&#xf…

阅读更多 →
多边形对角线计算原理与PHP实现 2026/9/19 6:59:28

多边形对角线计算原理与PHP实现

1. 多边形对角线的基础概念解析在几何学中,多边形对角线是一个看似简单却蕴含丰富数学原理的概念。作为一名长期从事几何算法开发的工程师,我发现很多初学者对这个基础概念的理解存在偏差。让我们从最基础的定义开始,逐步深入探讨。对角线是连…

阅读更多 →
PyPTO-Pro 对齐分段 Tile 布局(vec-14):用独立 32B 对齐 Tile 消除非对齐 VF 访存退化 2026/9/19 6:56:27

PyPTO-Pro 对齐分段 Tile 布局(vec-14):用独立 32B 对齐 Tile 消除非对齐 VF 访存退化

PyPTO-Pro 对齐分段 Tile 布局(vec-14):用独立 32B 对齐 Tile 消除非对齐 VF 访存退化 【免费下载链接】pypto-gym PyPTO-Gym 是基于 PyPTO 编程框架构建的算子与模型样例仓库 项目地址: https://gitcode.com/cann/pypto-gym 导读 本…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞