news 2026/5/9 14:49:02

CANN / ops-cv:AI CPU算子开发指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN / ops-cv:AI CPU算子开发指南

AI CPU算子开发指南

【免费下载链接】ops-cv本项目是CANN提供的图像处理、目标检测相关的算子库,实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-cv

概述

使用说明

算子根据运行的硬件单元不同,可分为AI Core算子和AI CPU算子(少数)。前者使用Ascend C语言开发,运行在AI Core硬件单元;后者使用C++语言开发,运行在AI CPU硬件单元。

本文重点介绍如何基于标准工程开发AI CPU算子,如果您想贡献AI Core算子,请参考AI Core算子开发指南。

算子开发前,请先了解如下信息:

  • 基础知识:请先学习C++编程语言,了解基本语法和原理,参考《TBE&AI CPU算子开发》熟悉硬件架构、开发API等。

开发流程

AddExample算子为例,介绍标准AI CPU算子开发的全流程和交付件,完整样例请访问项目examples目录。

  1. 前提条件:参考项目README完成环境准备和源码下载,此处不再赘述。

  2. 工程创建:创建标准算子工程目录,方便后续算子编译和部署。

  3. 算子定义:确定算子功能与原型定义。

  4. Kernel实现:实现Device侧算子核函数。

  5. aclnn适配:自定义算子推荐aclnn接口调用,需提前完成二进制发布。如采用图模式调用算子,请参考图模式适配指南。

  6. 编译部署:通过工程编译脚本完成自定义算子的编译和安装。

  7. 算子验证:通过常见算子调用方式,验证自定义算子功能。

工程创建

目录创建是算子开发的重要步骤,为后续代码编写、编译构建和调试提供统一的目录结构和文件组织方式。

可通过build.sh快速创建算子目录,进入项目根目录,执行如下命令:

# 创建指定算子目录,如bash build.sh --genop_aicpu=examples/add_example # ${op_class}表示算子类型,如image类。 # ${op_name}表示算子名的小写下划线形式,如`AddExample`算子对应为add_example,新增算子不允许与已有算子重名。 bash build.sh --genop_aicpu=${op_class}/${op_name}

命令执行成功,会看到如下提示信息:

Create the AI CPU initial directory for ${op_name} under ${op_class} success

创建完成后,目录结构如下所示:

${op_name} # 替换为实际算子名的小写下划线形式 ├── examples # 算子调用示例 │ └── test_aclnn_${op_name}.cpp # 算子aclnn调用示例 ├── op_host # Host侧实现 │ └── ${op_name}_infershape.cpp # InferShape实现,实现算子形状推导,在运行时推导输出shape ├── op_kernel_aicpu # Device侧Kernel实现 │ ├── ${op_name}_aicpu.cpp # Kernel入口文件,包含主函数和调度逻辑 │ ├── ${op_name}_aicpu.h # Kernel头文件,包含函数声明、结构定义、逻辑实现 │ └── ${op_name}.json # 算子信息库,定义算子基本信息,如名称、输入输出、数据类型等 ├── tests # UT实现 │ └── ut # kernel/aclnn UT实现 └── CMakeLists.txt # 算子cmakelist入口

${op_class}为全新算子分类需额外在CMakeLists中添加add_subdirectory(${op_class}),否则无法正常编译。

if(ENABLE_EXPERIMENTAL) # genop新增experimental算子分类 # add_subdirectory(${op_class}) add_subdirectory(experimental/image) else() # genop新增非experimental算子分类 # add_subdirectory(${op_class}) add_subdirectory(image) endif()

算子定义

算子定义需要完成两个交付件:README.md${op_name}.json

交付件1:README.md

开发算子前需要先确定目标算子的功能和计算逻辑。

以自定义AddExample算子说明为例,请参考AddExample算子说明。

交付件2:${op_name}.json

算子信息库。

以自定义AddExample算子说明为例,请参考AddExample算子信息库。

Kernel实现

Kernel简介

Kernel是算子在NPU执行的核心部分,Kernel实现包括如下步骤:

代码实现

Kernel一共需要两个交付件:${op_name}_aicpu.cpp${op_name}_aicpu.h

交付件1:${op_name}_aicpu.h

算子类声明

Kernel实现的第一步,需在头文件op_kernel_aicpu/${op_name}_aicpu.h进行算子类的声明,算子类需继承CpuKernel基类。 如需查看详细实现,请参考add_example_aicpu.h。

// 1、算子类声明 // 包含AI CPU基础库头文件 #include "cpu_kernel.h" // 定义命名空间aicpu(固定不允许修改),并定义算子Compute实现函数 namespace aicpu { // 算子类继承CpuKernel基类 class AddExampleCpuKernel : public CpuKernel { public: ~AddExampleCpuKernel() = default; // 声明函数Compute(需要重写),形参CpuKernelContext为CPUKernel的上下文,包括算子输入、输出和属性信息 uint32_t Compute(CpuKernelContext &ctx) override; }; } // namespace aicpu

交付件2:${op_name}_aicpu.cpp

Compute函数实现与AI CPU算子注册

获取输入/输出Tensor信息并进行合法性校验,然后实现核心计算逻辑(如加法操作),并将计算结果设置到输出Tensor中。

如需查看详细实现,请参考add_example_aicpu.cpp。

// 2、Compute函数实现 #include "add_example_aicpu.h" namespace { // 算子名 const char* const kAddExample = "AddExample"; const uint32_t kParamInvalid = 1; } // namespace // 定义命名空间aicpu namespace aicpu { // 实现自定义算子类的Compute函数 uint32_t AddExampleCpuKernel::Compute(CpuKernelContext& ctx) { // 从CpuKernelContext中获取input tensor Tensor* input0 = ctx.Input(0); Tensor* input1 = ctx.Input(1); // 从CpuKernelContext中获取output tensor Tensor* output = ctx.Output(0); // 对tensor进行基本校验, 判断是否为空指针 if (input0 == nullptr || input1 == nullptr || output == nullptr) { return kParamInvalid; } // 获取input tensor的数据类型 auto data_type = static_cast<DataType>(input0->GetDataType()); // 获取input tensor的数据地址,例如输入的数据类型是int32 auto input0_data = reinterpret_cast<int32_t*>(input0->GetData()); // 获取tensor的shape auto input0_shape = input->GetTensorShape(); // 获取output tensor的数据地址,例如输出的数据类型是int32 auto y = reinterpret_cast<int32_t*>(output->GetData()); // AddCompute函数根据输入类型执行相应计算。 // 由于C++自身不支持半精度浮点类型,可借助第三方库Eigen(建议使用3.3.9版本)表示。 switch (data_type) { case DT_FLOAT: return AddCompute<float>(...); case DT_INT32: return AddCompute<int32>(...); .... default : return PARAM_INVALID; } } // 3、注册算子Kernel实现,用于框架获取算子Kernel的Compute函数。 REGISTER_CPU_KERNEL(kAddExample, AddExampleCpuKernel); } // namespace aicpu

aclnn适配

通常算子开发和编译完成后,会自动生成aclnn接口(一套基于C 的API),无需做其他配置,可直接在应用程序中调用aclnn接口实现调用算子。

编译部署

算子开发完成后,需对算子工程进行编译,生成自定义算子安装包*.run,具体操作如下:

  1. 准备工作。

    参考工程创建完成基础环境搭建,同时检查算子开发交付件是否完备,是否在对应算子分类目录下。

  2. 编译自定义算子包。

    AddExample算子为例,假设开发交付件在examples目录,完整代码参见add_example_aicpu目录。

    # 编译指定算子,如bash build.sh --pkg --ops=add_example -j16 bash build.sh --pkg --soc=${soc_version} --vendor_name=${vendor_name} --ops=${op_list} [--experimental] [-j${n}]
    • --soc:${soc_version}表示NPU型号。Atlas A2系列产品使用"ascend910b"(默认),Atlas A3系列产品使用"ascend910_93",Ascend 950PR/Ascend 950DT产品使用"ascend950"。
    • --vendor_name(可选):${vendor_name}表示构建的自定义算子包名,默认名为custom。
    • --ops(可选):${op_list}表示待编译算子,不指定时默认编译所有算子。格式形如"--ops=add_example"。
    • --experimental(可选):若编译的算子为贡献算子,需配置--experimental。
    • -j(可选):指定编译线程数,加快编译速度。

    若提示如下信息,说明编译成功:

    Self-extractable archive "cann-ops-cv-${vendor_name}_linux-${arch}.run" successfully created.
  3. 安装自定义算子包。

    # 安装run包 ./build_out/cann-ops-cv-${vendor_name}_linux-${arch}.run

    自定义算子包安装在${ASCEND_HOME_PATH}/opp/vendors路径中,${ASCEND_HOME_PATH}表示CANN软件安装目录,可提前在环境变量中配置。

  4. (可选)卸载自定义算子包。

    自定义算子包安装后在${ASCEND_HOME_PATH}/opp/vendors/custom_cv/scripts目录会生成uninstall.sh,通过该脚本可卸载自定义算子包,命令如下:

    bash ${ASCEND_HOME_PATH}/opp/vendors/custom_cv/scripts/uninstall.sh

算子验证

验证算子前需确保已配置了环境变量,命令如下:

export LD_LIBRARY_PATH=${ASCEND_HOME_PATH}/opp/vendors/${vendor_name}_cv/op_api/lib:${LD_LIBRARY_PATH} export ASCEND_CUSTOM_OPP_PATH=${ASCEND_HOME_PATH}/opp/vendors/${vendor_name}_cv
  • UT验证

    算子开发过程中,可通过UT验证(如Kernel)方式进行快速验证,如需查看详细实现,请参考Kernel UT。

  • aclnn调用验证

    开发好的算子完成编译部署后,可通过aclnn方式验证功能,方法请参考算子调用方式。

【免费下载链接】ops-cv本项目是CANN提供的图像处理、目标检测相关的算子库,实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-cv

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

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

CANN/ops-cv图像处理算子库

贡献指南 【免费下载链接】ops-cv 本项目是CANN提供的图像处理、目标检测相关的算子库&#xff0c;实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-cv 本项目欢迎广大开发者体验并参与贡献&#xff0c;请在参与社区贡献之前参见cann-community先了解…

作者头像 李华
网站建设 2026/5/9 14:41:31

VideoWorld 2:跨域视频理解的通用知识迁移技术

1. 项目背景与核心价值VideoWorld 2这个项目名乍看简单&#xff0c;却暗含了计算机视觉领域最前沿的研究方向——如何让AI系统从真实视频流中提取可迁移的通用知识。这不同于传统的视频分析任务&#xff0c;其核心挑战在于突破特定场景的局限&#xff0c;建立跨领域的认知能力。…

作者头像 李华
网站建设 2026/5/9 14:39:34

GPT-3.5在独裁者游戏中的公平性实验:AI决策的统计模式与伦理启示

1. 项目概述&#xff1a;当AI成为“裁判”&#xff0c;公平性如何定义&#xff1f;最近在翻看一些行为经济学和博弈论的资料时&#xff0c;一个经典的实验模型——“独裁者游戏”——反复出现在眼前。这个实验很简单&#xff1a;两个人&#xff0c;一笔钱。一个人是“独裁者”&…

作者头像 李华
网站建设 2026/5/9 14:38:37

VR+AI科学可视化:从图神经网络特征到沉浸式可解释性探索

1. 项目概述&#xff1a;当VR遇见AI科学发现最近几年&#xff0c;我一直在关注一个交叉领域的有趣动向&#xff1a;虚拟现实&#xff08;VR&#xff09;和人工智能&#xff08;AI&#xff09;如何联手&#xff0c;去解决那些传统上“只可意会&#xff0c;难以言传”的科学难题。…

作者头像 李华
网站建设 2026/5/9 14:36:04

AI控制框架KendaliAI:从模型调用到智能体编排的工程化实践

1. 项目概述&#xff1a;一个面向开发者的AI控制与集成框架最近在GitHub上看到一个挺有意思的项目&#xff0c;叫KendaliAI。这个名字很有意思&#xff0c;“Kendali”在印尼语里是“控制”的意思&#xff0c;顾名思义&#xff0c;这是一个关于AI控制的框架。作为一个在软件开发…

作者头像 李华