ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CANN asc-devkit 算子调用实战:基于 aclnn 单算子 API 与 aclop 单算子模型的两种调用方式解析

CANN asc-devkit 算子调用实战:基于 aclnn 单算子 API 与 aclop 单算子模型的两种调用方式解析 人工智能深度学习算子库CANNAscend【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址https://gitcode.com/cann/asc-devkit点击查看免费下载导读本文以 CANN asc-devkit 仓库中 01_acl_invocation 样例 为核心系统讲解在完成自定义算子开发部署后如何通过aclnn 单算子 API 执行基于 C 语言的两段式接口免离线模型转换与aclop 单算子模型调用基于atc --singleop生成的单算子离线模型两种方式在 Host 侧驱动昇腾 AI 处理器执行自定义算子。读完本文你将掌握aclnnAddCustomGetWorkspaceSize/aclnnAddCustom与aclopExecuteV2的完整调用流程、工程编译配置、单算子描述文件编写以及结果验证方法可直接套用到自己的自定义算子验证场景。背景为什么要区分 aclnn 与 aclop 两种调用方式在 CANN 生态中算子开发完成后并不等于可以直接被上层框架使用还需要在 Host 侧通过 ACLAscend Computing Language运行时接口把算子发下去执行。面向不同的集成场景CANN 提供了两种单算子执行路径本样例的父级文档 99_acl_based 目录 将其归纳为目录名称功能描述00_acl_compilation自定义算子编译、打包和部署的实现方法01_acl_invocationAclnn 和 Aclop 算子调用的实现方法其中 01_acl_invocation 正是本文的主体它包含两个子样例目录名称功能描述支持的产品aclnn_invocation介绍 Aclnn 算子调用单算子 API 执行的实现方法Ascend 950PR/Ascend 950DT、Atlas A3/A2 训练与推理系列产品、Atlas 200I/500 A2 推理产品、Atlas 推理系列产品aclop_invocation介绍 Aclop 算子调用单算子模型执行的实现方法与 aclnn 样例相同两个样例都以自定义的AddCustom算子z x y输入输出 shape 均为[8, 2048]float16ND 格式为对象分别演示两种调用路径的完整代码是理解单算子调用的最小可运行范本。两种调用方式的原理差异aclnn单算子 API 执行免离线模型转换单算子 API 执行是基于 C 语言 API 直接执行算子的方式无需提供单算子描述文件、无需经过离线模型转换只要自定义算子工程已完成编译、打包和部署Host 程序即可直接链接算子侧生成的 op_api 库并调用对应的aclnnOpType接口。以本样例为例对应算子生成的接口是aclnnAddCustom采用两段式调用aclnnAddCustomGetWorkspaceSize获取本次计算所需 workspace 大小并在 Device 上申请对应内存aclnnAddCustom真正下发算子计算。这种先查 workspace、再执行的模式是 aclnn 系列接口的统一约定workspace 是算子执行过程中 Kernel 侧所需的临时存储空间由框架根据算子实现动态计算Host 侧需要按其返回值申请显存后传入。aclop单算子模型调用离线模型驱动单算子模型调用走的是离线模型路径在 Host 应用运行前需要先用atc --singleop工具将单算子描述文件add_custom.json转换为单算子离线模型然后在应用中通过aclopSetModelDir指定模型目录再调用aclopExecuteV2执行。该路径不需要生成aclnnOpType形式的算子专用接口而是以算子类型名OpType 输入输出描述 数据 Buffer的通用形式驱动模型执行。两种方式的取舍可归纳为aclnn 免模型转换、接口语义更贴近具体算子参数即为张量适合快速验证算子功能与算子侧自研集成aclop 需要提前用 atc 生成模型但接口更通用适合以 OpType 为键的框架级调度场景。前置条件先编译、打包、部署自定义算子工程两个调用样例的 README 都明确要求运行前必须先进入 自定义算子工程样例 完成编译、打包和部署。该工程内同时提供AddCustom、AddCustomTemplate、AddCustomTilingSink、LeakyRelu四个算子实现其中被本样例调用的AddCustom基于 Ascend C 的矢量计算接口Add实现tiling 侧使用totalLength、tileNum两个参数控制数据切分。部署命令在该工程根目录下执行mkdir -p build cd build cmake .. make -j binary package ./custom_opp_*.run执行结果出现SUCCESS即部署成功。部署产物会安装到ASCEND_OPP_PATH默认${install_path}/cann/opp下的vendors/customize目录这正是后续 aclnn 样例链接cust_opapi库、aclop 样例查找模型文件时依赖的环境。环境变量配置根据 CANN 安装方式 配置环境变量source ${install_path}/cann/set_env.sh说明${install_path}为 CANN 包安装目录未指定安装目录时默认安装至/usr/local/Ascend下。编译脚本中使用的ASCEND_HOME_PATH、ASCEND_OPP_PATH均由该脚本注入。aclnn 样例详解aclnnAddCustom 两段式调用目录结构aclnn_invocation/ ├── CMakeLists.txt // 编译工程文件 ├── main.cpp // 算子调用主程序 ├── README.md // 样例说明文档 └── scripts/ └── gen_data.py // 测试数据生成脚本数据准备gen_data.pygen_data.py 使用 numpy 生成 shape 为(8, 2048)的测试数据input0.bin全 1.1 的 float16 矩阵input1.bin全 2.2 的 float16 矩阵golden.bin(input0 input1)的 float16 结果作为验证基准数据以二进制格式写入input/与output/目录供主程序ReadFile读取。主程序核心流程aclnn_invocation/main.cpp 完整演示了三段式生命周期可拆解为以下五步Step 1初始化 ACL 环境const int32_t deviceId 0; aclrtStream stream nullptr; CHECK_ACL(aclnnInit(nullptr)); // 初始化 aclnn替代传统 aclInit CHECK_ACL(aclrtSetDevice(deviceId)); // 指定设备 CHECK_ACL(aclrtCreateStream(stream)); // 创建流注意 aclnn 路径使用aclnnInit/aclnnFinalize而非aclInit/aclFinalize这是 aclnn 接口族的使用约定。Step 2创建 aclTensor 并准备 Device 数据先申请 Device 显存再用aclCreateTensor将显存包装为带 shape、dtype、format 语义的张量描述void* input0DeviceMem nullptr; CHECK_ACL(aclrtMalloc(input0DeviceMem, bufferSize, ACL_MEM_MALLOC_HUGE_FIRST)); aclTensor* input0 aclCreateTensor( shape.data(), shape.size(), ACL_FLOAT16, nullptr, 0, ACL_FORMAT_ND, shape.data(), shape.size(), input0DeviceMem);其中 shape 为{8, 2048}、bufferSize 8 * 2048 * sizeof(aclFloat16)三个张量input0、input1、output0同构创建。随后通过aclrtMemcpy以ACL_MEMCPY_HOST_TO_DEVICE方向将 Host 数据拷入 DeviceCHECK_ACL(aclrtMemcpy(input0DeviceMem, bufferSize, input0HostData.data(), bufferSize, ACL_MEMCPY_HOST_TO_DEVICE));Step 3两段式调用——先查 workspace 再执行uint64_t workspaceSize 0; aclOpExecutor* executor nullptr; CHECK_ACL(aclnnAddCustomGetWorkspaceSize(input0, input1, output0, workspaceSize, executor)); void* workspaceDeviceMem nullptr; if (workspaceSize 0) { CHECK_ACL(aclrtMalloc(workspaceDeviceMem, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST)); } CHECK_ACL(aclnnAddCustom(workspaceDeviceMem, workspaceSize, executor, stream));这段代码体现了 aclnn 两段式接口的标准用法第一段返回workspaceSize可能为 0即算子无需额外 workspace和复用的executor句柄第二段把 workspace 显存与流传入执行。workspaceSize 为 0 时不能申请 0 字节显存因此代码用if (workspaceSize 0)做了保护。Step 4同步与结果回拷CHECK_ACL(aclrtSynchronizeStream(stream)); // 等待算子异步执行完成 CHECK_ACL(aclrtMemcpy(output0HostData.data(), bufferSize, output0DeviceMem, bufferSize, ACL_MEMCPY_DEVICE_TO_HOST));Step 5结果校验与资源释放程序打印前 10 个结果元素并用VerifyResult与 golden 数据比对float16 先转 float容差1e-3Fprintf(\ntest %s\n, VerifyResult(output0HostData, goldenData) ? pass : failed);释放顺序为aclDestroyTensor→aclrtFree含 workspace→aclrtDestroyStream→aclrtResetDevice→aclnnFinalize与申请顺序严格对称。编译配置CMakeLists.txtaclnn_invocation/CMakeLists.txt 的关键点在于除 ACL 运行时头文件与库外还要链接部署自定义算子包时生成的 op_api 产物target_include_directories(execute_add_op PRIVATE $ENV{ASCEND_HOME_PATH}/include $ENV{ASCEND_OPP_PATH}/vendors/customize/op_api/include ) target_link_directories(execute_add_op PRIVATE $ENV{ASCEND_HOME_PATH}/lib64 $ENV{ASCEND_OPP_PATH}/vendors/customize/op_api/lib ) target_link_libraries(execute_add_op PRIVATE cust_opapi // 自定义算子生成的 aclnn 接口库 nnopbase // 算子基础库 acl_rt // ACL 运行时 )cust_opapi正是aclnnAddCustom等接口的载体——这也是为什么必须先部署自定义算子工程再编译本样例。编译运行mkdir -p build cd build python3 ../scripts/gen_data.py # 生成 input/ 与 output/ 下的测试数据 cmake .. make -j ./execute_add_op执行结果result is: 3.3 3.3 3.3 3.3 3.3 3.3 3.3 3.3 3.3 3.3 test pass1.1 2.2 3.3符合z x y预期。aclop 样例详解aclopExecuteV2 单算子模型执行目录结构aclop_invocation/ ├── add_custom.json // 单算子描述文件atc 模型转换输入 ├── CMakeLists.txt // 编译工程文件 ├── main.cpp // 算子调用主程序 ├── README.md // 样例说明文档 └── scripts/ └── gen_data.py // 测试数据生成脚本与 aclnn 样例相比多了一个add_custom.json它是离线模型转换的输入描述文件。单算子描述文件 add_custom.jsonadd_custom.json 声明了算子类型、输入输出描述[ { op: AddCustom, input_desc: [ { name: x, param_type: required, format: ND, shape: [8, 2048], type: float16 }, { name: y, param_type: required, format: ND, shape: [8, 2048], type: float16 } ], output_desc: [ { name: z, param_type: required, format: ND, shape: [8, 2048], type: float16 } ] } ]其中op必须与算子工程注册的 OpTypeAddCustom一致input_desc/output_desc的name需与算子 Host 侧注册的输入输出名对应本算子为 x、y、zshape、type、format决定 atc 生成固定 shape 模型的输入输出规格。主程序核心流程aclop_invocation/main.cpp 使用经典的 ACL C 接口流程如下Step 1初始化并指定模型目录CHECK_ACL(aclInit(nullptr)); // aclop 路径使用 aclInit/aclFinalize CHECK_ACL(aclrtSetDevice(deviceId)); CHECK_ACL(aclrtCreateStream(stream)); CHECK_ACL(aclopSetModelDir(.)); // 指定 atc 生成的单算子模型所在目录注意与 aclnn 样例的区别这里调用aclInit且执行前必须aclopSetModelDir指向模型目录本例模型输出到.即 build 目录。Step 2用 TensorDesc DataBuffer 描述输入输出与 aclnn 的aclTensor不同aclop 路径使用描述aclCreateTensorDesc 数据aclCreateDataBuffer分离的模型const char* opType AddCustom; auto* input0 aclCreateTensorDesc(dataType, shape.size(), shape.data(), format); // input1、output0 同理format 为 ACL_FORMAT_NDdataType 为 ACL_FLOAT16 void* input0DeviceMem nullptr; CHECK_ACL(aclrtMalloc(input0DeviceMem, bufferSize, ACL_MEM_MALLOC_HUGE_FIRST)); auto* input0Buffer aclCreateDataBuffer(input0DeviceMem, bufferSize);TensorDesc 放入inputDesc/outputDesc两个std::vectorDataBuffer 放入inputBuffers/outputBuffers保持下标一一对应。Step 3执行 aclopExecuteV2CHECK_ACL(aclopExecuteV2(opType, inputDesc.size(), inputDesc.data(), inputBuffers.data(), outputDesc.size(), outputDesc.data(), outputBuffers.data(), opAttr, stream));opAttr由aclopCreateAttr()创建本算子无属性传入空属性即可opType字符串即单算子描述文件中的op值ACL 依据该 OpType 在模型目录中查找对应模型并执行。Step 4同步、回拷与校验CHECK_ACL(aclrtSynchronizeStream(stream)); CHECK_ACL(aclrtMemcpy(output0HostData.data(), bufferSize, output0DeviceMem, bufferSize, ACL_MEMCPY_DEVICE_TO_HOST));校验逻辑与 aclnn 样例相同容差1e-3F的逐元素比对释放资源时额外调用aclDestroyDataBuffer、aclDestroyTensorDesc、aclopDestroyAttr。编译配置CMakeLists.txtaclop_invocation/CMakeLists.txt 不需要链接cust_opapi只需 ACL 基础库target_link_libraries(execute_add_op PRIVATE acl_op_executor // aclop 单算子模型执行库 acl_mdl // 模型加载/执行库 acl_rt // ACL 运行时 )这从工程层面印证了两条路径的本质差异aclnn 依赖算子工程产物cust_opapiaclop 依赖通用模型执行库。编译运行先 atc 生成单算子离线模型mkdir -p build cd build python3 ../scripts/gen_data.py # 使用 atc 模型转换工具生成单算子离线模型 atc --singleop../add_custom.json --output. --soc_version${soc_version} cmake .. make -j ./execute_add_op其中${soc_version}为 AI 处理器型号获取方式如下针对Atlas A2 训练/推理系列产品、Atlas 200I/500 A2 推理产品、Atlas 推理系列产品在安装昇腾 AI 处理器的服务器执行npu-smi info查询取Name信息实际配置值为 AscendName例如Name取值为 xxxyy实际配置值为 Ascendxxxyy针对Ascend 950PR/Ascend 950DT、Atlas A3 训练/推理系列产品执行npu-smi info -t board -i id -c chip_id查询取Chip Name与NPU Name实际配置值为Chip Name_NPU Name例如 Chip Name 为 Ascendxxx、NPU Name 为 1234则配置Ascendxxx_1234。其中id为设备 id通过npu-smi info -l查出的 NPU IDchip_id为芯片 id通过npu-smi info -m查出的 Chip ID。说明基于同系列的 AI 处理器型号创建的算子工程其基础功能算子开发、编译和部署通用。atc命令在 CANN 包安装目录默认/usr/local/Ascend的cann/atc/bin下环境变量配置后可直接使用。执行结果与 aclnn 样例一致出现test pass即验证通过。两种调用方式对比与选型建议对比维度aclnn 单算子 API 执行aclop 单算子模型执行前置步骤仅需部署自定义算子包部署算子包 atc --singleop生成离线模型模型转换不需要需要输入add_custom.json关键接口aclnnOpTypeGetWorkspaceSize/aclnnOpType两段式aclopSetModelDir/aclopExecuteV2数据对象aclTensor描述与数据一体aclTensorDescaclDataBuffer分离初始化aclnnInit/aclnnFinalizeaclInit/aclFinalize链接依赖cust_opapinnopbaseacl_rtacl_op_executoracl_mdlacl_rt适用场景算子功能快速验证、算子侧集成框架级以 OpType 为键的通用调度选择建议如果你的目标是验证刚开发的自定义算子功能是否正确aclnn 路径更直接——部署算子包后即可调用且接口参数即张量错误定位直观如果你需要模拟真实推理/训练框架加载算子模型的路径或在同一应用中按 OpType 动态调度多个算子则 aclop 路径更贴近生产形态。延伸阅读算子调用样例总览99_acl_based/README.md前置的自定义算子工程编译、打包、部署流程00_acl_compilation/custom_op/README.mdCANN 开发套件包安装与环境准备docs/zh/quick_start.md若需以 git 方式获取源码可执行git clone https://gitcode.com/cann/asc-devkit后进入examples/01_simd_cpp_api/02_features/99_acl_based/01_acl_invocation目录复现本文全部步骤。赞分享人工智能深度学习算子库CANNAscend【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址https://gitcode.com/cann/asc-devkit点击查看免费下载相关推荐Security-101 入门网络安全课程指南八模块课纲、多语言分发机制与学习路径基于保加利亚语版 README 解读Security 101 入门网络安全课程指南八模块课纲、多语言分发机制与学习路径基于保加利亚语版 README 解读 本文基于 Security 101人工智能深度学习算子库CANNAscendCANN ops-math ReduceSum 算子全解析aclnn 单算子调用与 GE IR 图模式实战指南CANN ops math ReduceSum 算子全解析aclnn 单算子调用与 GE IR 图模式实战指南 本指南以 CANN ops math 开源仓库算子库人工智能CANNCANN ops-nn WeightQuantBatchMatmulExperiment 算子 aclnn 单算子调用样例深度解析CANN ops nn WeightQuantBatchMatmulExperiment 算子 aclnn 单算子调用样例深度解析 本指南以 experimen人工智能算子库深度学习CANNAscend上一篇如何快速下载网页视频资源猫抓浏览器扩展完整使用指南下一篇Lenovo Legion Toolkit深度自定义联想笔记本性能控制的终极解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表