一、背景与优化思路
在使用昇腾算力卡视频目标检测推理场景中,常规画框流程需将算力卡上的图像数据往返传输至CPU,占用大量PCIe带宽和CPU资源。针对昇腾算力卡,可通过AICPU自定义算子直接在算力卡上完成画框,避免数据往返传输,核心思路是将OpenCV画框API集成到AICPU算子中。
二、参考文档与核心概念
核心:AICPU自定义算子通过张量传输参数直接操作算力卡执行代码,集成OpenCV即可实现算力卡内画框,建议先从ReshapeCust算子样例理解整体流程。
三、基础样例编译(ReshapeCust算子)
1. 算子工程编译
Bash
# 1. 赋予编译脚本执行权限
chmod +x build.sh
# 2. 配置环境变量(取消屏蔽)
export ASCEND_TENSOR_COMPILER_INCLUDE=/usr/local/Ascend/ascend-toolkit/latest/compiler/include
export TOOLCHAIN_DIR=/usr/local/Ascend/ascend-toolkit/latest/toolkit/toolchain/hcc
# 3. 修复Python版本报错(根据本机实际版本修改)
vi cpukernel/CMakeLists.txt # 将python3.7.5改为python3.8
# 4. 执行编译
./build.sh -c
# 5. 生成部署包后执行部署(解决权限问题)
sudo chmod 777 /usr/local/Ascend/ascend-toolkit/8.2.RC1/opp/vendors/
./custom_opp_ubuntu_aarch64.run # 覆盖提示输入3次o、1次y
2. 算子验证工程编译
Bash
# 步骤1:JSON转模型
cd acl_execute_reshape/run/out
atc --singleop=test_data/config/reshape_op.json --soc_version=Ascend310 --output=op_models
# 步骤2:生成测试数据
cd test_data/data
python3.7.5 generate_data.py # 生成input_0.bin/input_1.bin
# 步骤3:编译验证工程
cd ../../../../src
export DDK_PATH=/usr/local/Ascend/ascend-toolkit/latest
export NPU_HOST_LIB=$DDK_PATH/runtime/lib64/stub
mkdir -p build && cd build
cmake .. && make
# 步骤4:执行验证
./execute_custom_reshape_op
四、新建DrawbboxCust自定义算子(核心步骤)
1. 复制并修改算子实现文件
Bash
# 复制算子代码文件
cd /oss/laijunhui/project/samples/cplusplus/level1_single_api/4_op_dev/1_custom_op/cpukernel/impl/
cp reshape_cust_kernels.cc drawbbox_cust_kernels.cc
cp reshape_cust_kernels.h drawbbox_cust_kernels.h
# 修改头文件(drawbbox_cust_kernels.h)
vi drawbbox_cust_kernels.h
# 1. 宏定义:_AICPU_DRAWBBOX_CUST_KERNELS_H_
# 2. 类名:DrawbboxCustCpuKernel
# 修改实现文件(drawbbox_cust_kernels.cc)
vi drawbbox_cust_kernels.cc
# 1. 头文件:#include "drawbbox_cust_kernels.h"
# 2. 算子名:const char *DRAWBBOX_CUST = "DrawbboxCust";
# 3. 函数:uint32_t DrawbboxCustCpuKernel::Compute(CpuKernelContext &ctx) { ... }
# 4. 注册:REGISTER_CPU_KERNEL(DRAWBBOX_CUST, DrawbboxCustCpuKernel);
2. 复制并修改算子注册文件
Bash
# 复制并修改ini配置
cd /oss/laijunhui/project/samples/cplusplus/level1_single_api/4_op_dev/1_custom_op/cpukernel/op_info_cfg/aicpu_kernel/
cp reshape_cust.ini drawbbox_cust.ini
vi drawbbox_cust.ini # 第一行改为 [DrawbboxCust]
# 复制并修改GE注册文件
cd /oss/laijunhui/project/samples/cplusplus/level1_single_api/4_op_dev/1_custom_op/op_proto/
cp reshape_cust.h drawbbox_cust.h
cp reshape_cust.cc drawbbox_cust.cc
# 修改头文件(drawbbox_cust.h)
vi drawbbox_cust.h
# 1. 宏:GE_OP_DRAWBBOX_CUST_H
# 2. 注册:REG_OP(DrawbboxCust) + .OP_END_FACTORY_REG(DrawbboxCust)
# 修改实现文件(drawbbox_cust.cc)
vi drawbbox_cust.cc
# 1. 头文件:#include "drawbbox_cust.h"
# 2. 推理函数:IMPLEMT_COMMON_INFERFUNC(DrawbboxCustInferShape) { ... }
# 3. 注册:COMMON_INFER_FUNC_REG(DrawbboxCust, DrawbboxCustInferShape);
3. 复制并修改验证工程
Bash
# 复制验证工程
cd /oss/laijunhui/project/samples/cplusplus/level1_single_api/4_op_dev/2_verify_op/
cp -r acl_execute_reshape/ acl_drawbbox
# 修改编译配置
cd acl_drawbbox/src
rm -rf build
vi CMakeLists.txt
# 1. 工程名:project(execute_custom_drawbbox_op)
# 2. 可执行文件:add_executable(execute_custom_drawbbox_op ...)
# 3. 链接:target_link_libraries(execute_custom_drawbbox_op ...)
# 4. 安装:install(TARGETS execute_custom_drawbbox_op ...)
# 修改算子配置JSON
cd ../run/out/test_data/config
cp reshape_op.json drawbbox_op.json
vi drawbbox_op.json # "op": "DrawbboxCust"
# 修改验证代码
vi ../../../../src/main.cpp # std::string opType = "DrawbboxCust";
4. 关键配置与集成OpenCV
(1)输入输出张量定义
修改drawbbox_op.json,定义画框所需参数的张量(图像信息、框数量/坐标/厚度等),确保shape和type与实际参数匹配。
(2)验证工程算子描述
修改OperatorDesc CreateOpDesc()函数,同步调整张量的size和type,与JSON配置一致。
(3)集成OpenCV画框API
在drawbbox_cust_kernels.cc的Compute函数中调用OpenCV画框接口,需静态链接昇腾算力卡专用的OpenCV库 (链接:https://pan.baidu.com/s/1Z8sGoSI3eqUfime9aF5wSQ 密码: r80o)。
(4)重新编译与验证
Bash
# 1. 重新编译算子工程(生成新的部署包并部署)
cd 1_custom_op && ./build.sh -c && ./custom_opp_ubuntu_aarch64.run
# 2. 重新转换模型(清除旧模型避免加载错误)
rm -rf acl_drawbbox/run/out/op_models
atc --singleop=acl_drawbbox/run/out/test_data/config/drawbbox_op.json --soc_version=Ascend310 --output=acl_drawbbox/run/out/op_models
# 3. 编译并执行验证工程
cd acl_drawbbox/src && mkdir -p build && cd build
cmake .. && make && ./execute_custom_drawbbox_op
总结
-
昇腾AICPU自定义算子核心是通过张量传参直接在算力卡执行代码,避免图像数据往返传输;
-
新建画框算子需复刻ReshapeCust样例的文件结构,重点修改算子名、张量配置、GE注册;
-
集成OpenCV时需使用昇腾专用静态库,且需保证JSON配置、验证代码、算子实现的张量定义一致。