Merged
feat:将cv仓的aicpu算子从merge每个文件夹下的json配置算子信息更改到def文件配置算子信息自动生成json #622
zhaowenruiAdd on Mar 28
feat:将cv仓的aicpu算子从merge每个文件夹下的json配置算子信息更改到def文件配置算子信息自动生成json #622
Merged
zhaowenruiAdd on Mar 28
Total: 14 files changed+389-144
@@ -379,7 +379,7 @@ macro(add_modules_sources)
379 target_sources(${OPHOST_NAME}_tiling_obj PRIVATE ${OPTILING_SRCS})379 target_sources(${OPHOST_NAME}_tiling_obj PRIVATE ${OPTILING_SRCS})
380 endif()380 endif()
381 381 
382- file(GLOB AICPU_SRCS ${SOURCE_DIR}/*_aicpu*.cpp)382+ file(GLOB AICPU_SRCS ${SOURCE_DIR}/*_aicpu.cpp)
383 if(AICPU_SRCS)383 if(AICPU_SRCS)
384 add_aicpu_kernel_modules()384 add_aicpu_kernel_modules()
385 target_sources(${OPHOST_NAME}_aicpu_obj PRIVATE ${AICPU_SRCS})385 target_sources(${OPHOST_NAME}_aicpu_obj PRIVATE ${AICPU_SRCS})
@@ -192,3 +192,42 @@ function(gen_aclnn_with_opdef)
192 target_include_directories(opbuild_gen_aclnn_all PRIVATE ${OPAPI_INCLUDE})192 target_include_directories(opbuild_gen_aclnn_all PRIVATE ${OPAPI_INCLUDE})
193 endif()193 endif()
194endfunction()194endfunction()
195+ 
196+function(opbuild_aicpu_ini)
197+ message(STATUS "Opbuild generating sources")
liu-wei
liu-weiliu-weiApr 1

message太多了,保留点必要的,非必要的删除了。

likedislike
198+ message("ARGN: ${ARGN}")
199+ cmake_parse_arguments(OPBUILD "" "OUT_DIR;PROJECT_NAME;ACCESS_PREFIX;ENABLE_SOURCE" "OPS_SRC" ${ARGN})
200+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} -g -fPIC -shared -std=c++11 ${OPBUILD_OPS_SRC} -D_GLIBCXX_USE_CXX11_ABI=0
liu-weiliu-wei
liu-weiliu-weiApr 1

缩进不对

likedislike
zhaowenrui
zhaowenrui
Apr 1 Comments:
liu-weiliu-weiApr 1

C++11标准是否还适用,看看库上intf_pub里面的版本

likedislike
zhaowenrui
zhaowenrui
Apr 1 Comments:
201+ -I ${ASCEND_CANN_PACKAGE_PATH}/include -I ${CMAKE_CURRENT_SOURCE_DIR}/op_kernel -L ${ASCEND_CANN_PACKAGE_PATH}/lib64 -lexe_graph -lregister -ltiling_api
202+ -o ${OPBUILD_OUT_DIR}/libaicpu_ops.so
203+ RESULT_VARIABLE EXEC_RESULT
204+ OUTPUT_VARIABLE EXEC_INFO
205+ ERROR_VARIABLE EXEC_ERROR
206+ )
207+ if (${EXEC_RESULT})
208+ message("build ops lib info: ${EXEC_INFO}")
209+ message("build ops lib error: ${EXEC_ERROR}")
210+ message(FATAL_ERROR "opbuild run failed!")
211+ endif()
212+ set(proj_env "")
213+ set(prefix_env "")
214+ if (NOT "${OPBUILD_PROJECT_NAME}x" STREQUAL "x")
215+ set(proj_env "OPS_PROJECT_NAME=${OPBUILD_PROJECT_NAME}")
216+ endif()
217+ if (NOT "${OPBUILD_ACCESS_PREFIX}x" STREQUAL "x")
218+ set(prefix_env "OPS_DIRECT_ACCESS_PREFIX=${OPBUILD_ACCESS_PREFIX}")
219+ endif()
220+ set(ENV{ENABLE_SOURCE_PACKAGE} ${OPBUILD_ENABLE_SOURCE})
221+ execute_process(COMMAND ${proj_env} ${prefix_env} ${ASCEND_CANN_PACKAGE_PATH}/toolkit/tools/opbuild/op_build
222+ ${OPBUILD_OUT_DIR}/libaicpu_ops.so ${OPBUILD_OUT_DIR} --aicpu
liu-wei
liu-weiliu-weiApr 1

这个中间的空格是不是有问题,两个?

likedislike
223+ RESULT_VARIABLE EXEC_RESULT
224+ OUTPUT_VARIABLE EXEC_INFO
225+ ERROR_VARIABLE EXEC_ERROR
226+ )
227+ unset(ENV{ENABLE_SOURCE_PACKAGE})
228+ if (${EXEC_RESULT})
229+ message("opbuild ops info: ${EXEC_INFO}")
230+ message("opbuild ops error: ${EXEC_ERROR}")
231+ endif()
232+ message(STATUS "Opbuild generating sources - done")
233+endfunction()
@@ -380,30 +380,44 @@ function(gen_cust_proto_symbol)
380 )380 )
381endfunction()381endfunction()
382 382 
383-function(gen_aicpu_json_symbol enable_built_in)383+function(gen_aicpu_op_def_symbol)
384- get_property(ALL_AICPU_JSON_FILES GLOBAL PROPERTY AICPU_JSON_FILES)384+ message(STATUS "enter gen_aicpu_op_def_symbol")
385- if(NOT ALL_AICPU_JSON_FILES)385+ get_property(ALL_AICPU_OP_DEF_FILES GLOBAL PROPERTY AICPU_OP_DEF_FILES)
386- message(STATUS "No aicpu json files to merge, skipping.")386+ if(NOT ALL_AICPU_OP_DEF_FILES)
387+ message(STATUS "No aicpu op def files, skipping.")
387 return()388 return()
388 endif()389 endif()
390+ message(STATUS "ALL_AICPU_OP_DEF_FILES:${ALL_AICPU_OP_DEF_FILES}")
391+ # 调用opbuild命令生成固定文件 aicpu_kernel.ini
392+ opbuild_aicpu_ini(OPS_SRC ${ALL_AICPU_OP_DEF_FILES}
393+ OUT_DIR ${ASCEND_AUTOGEN_PATH}
394+ )
395+endfunction()
389 396 
397+function(gen_aicpu_json_symbol enable_built_in)
398+ gen_aicpu_op_def_symbol()
390 set(MERGED_JSON ${CMAKE_BINARY_DIR}/cust_aicpu_kernel.json)399 set(MERGED_JSON ${CMAKE_BINARY_DIR}/cust_aicpu_kernel.json)
391 if(enable_built_in)400 if(enable_built_in)
392 set(MERGED_JSON ${CMAKE_BINARY_DIR}/aicpu_cv.json)401 set(MERGED_JSON ${CMAKE_BINARY_DIR}/aicpu_cv.json)
393 endif()402 endif()
394 403 
395- add_custom_command(404+ set(cmd "python3 ${CMAKE_SOURCE_DIR}/scripts/kernel/binary_script/parser_ini.py ${ASCEND_AUTOGEN_PATH}/aicpu_kernel.ini ${MERGED_JSON}")
396- OUTPUT ${MERGED_JSON}405+ message("cmd: ${cmd}")
397- COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/util/merge_aicpu_info_json.sh ${CMAKE_SOURCE_DIR} ${MERGED_JSON} ${ALL_AICPU_JSON_FILES}406+ 
398- DEPENDS ${ALL_AICPU_JSON_FILES}407+ execute_process(
399- COMMENT "Merging Json files into ${MERGED_JSON}"408+ COMMAND bash -c "${cmd}"
400- VERBATIM409+ WORKING_DIRECTORY ${ASCEND_AUTOGEN_PATH}
410+ OUTPUT_VARIABLE result
411+ ERROR_VARIABLE error
412+ RESULT_VARIABLE code
413+ OUTPUT_STRIP_TRAILING_WHITESPACE
401 )414 )
402- add_custom_target(merge_aicpu_json ALL DEPENDS ${MERGED_JSON})415+ message("convert ini to json finish.")
416+ 
403 install(417 install(
404- FILES ${MERGED_JSON}418+ FILES ${MERGED_JSON}
405- DESTINATION ${AICPU_JSON_CONFIG}419+ DESTINATION ${AICPU_JSON_CONFIG}
406- OPTIONAL420+ OPTIONAL
407 )421 )
408endfunction()422endfunction()
409 423 
@@ -0,0 +1,46 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file aicpu_op_def.h
13+ * \brief
14+ */
15+#ifndef CV_COMMON_AICPU_OP_DEF_H
16+#define CV_COMMON_AICPU_OP_DEF_H
17+namespace ops {
18+ const std::string CV_AICPU_KERNEL_SO = "libcv_aicpu_kernels.so";
19+ const std::string OP_INFO_WORKSPACESIZE = "opInfo.workspaceSize";
20+ const std::string DEFAULT_WORKSPACE_SIZE = "100"; // 记录AICPU算子日志信息内存大小,单位 KB
21+ const std::string OP_INFO_FORMAT_AGNOSTIC = "opInfo.formatAgnostic";// 是否格式敏感,默认不敏感
22+ const std::string FALSE_FORMAT_AGNOSTIC = "False";
23+ const std::string TRUE_FORMAT_AGNOSTIC = "True";
24+ const std::string OP_INFO_OPS_FLAG = "opInfo.opsFlag"; // 是否支持常量折叠,默认不支持
25+ const std::string CLOSE_OPS_FLAG = "OPS_FLAG_CLOSE";
26+ const std::string OPEN_OPS_FLAG = "OPS_FLAG_OPEN";
27+ const std::string OP_INFO_SUB_TYPE_OF_INFERSHAPE = "opInfo.subTypeOfInferShape"; // 算子类型,默认是1类算子
28+ const std::string DEFAULT_SUB_TYPE_OF_INFERSHAPE_1 = "1";
29+ const std::string DEFAULT_SUB_TYPE_OF_INFERSHAPE_2 = "2";
30+ const std::string DEFAULT_SUB_TYPE_OF_INFERSHAPE_3 = "3";
31+ const std::string DEFAULT_SUB_TYPE_OF_INFERSHAPE_4 = "4";
32+ 
33+ 
34+ template <typename TOpDef>
35+ inline void ApplyCvAicpuDefaultCfg(TOpDef &opDef)
36+ {
37+ opDef.AICPU().OpKernelLib("CUSTAICPUKernel");
38+ opDef.AICPU().KernelSo(CV_AICPU_KERNEL_SO.c_str());
39+ opDef.AICPU().UserDefined(true);
40+ opDef.AICPU().ExtendCfgInfo(OP_INFO_WORKSPACESIZE.c_str(), DEFAULT_WORKSPACE_SIZE.c_str());
41+ opDef.AICPU().ExtendCfgInfo(OP_INFO_FORMAT_AGNOSTIC.c_str(), FALSE_FORMAT_AGNOSTIC.c_str());
42+ opDef.AICPU().ExtendCfgInfo(OP_INFO_OPS_FLAG.c_str(), CLOSE_OPS_FLAG.c_str());
43+ opDef.AICPU().ExtendCfgInfo(OP_INFO_SUB_TYPE_OF_INFERSHAPE.c_str(), DEFAULT_SUB_TYPE_OF_INFERSHAPE_1.c_str());
44+ }
45+} // namespace op
46+#endif
@@ -14,12 +14,12 @@ if (BUILD_WITH_INSTALLED_DEPENDENCY_CANN_PKG)
14 set(CMAKE_CXX_COMPILER ${ASCEND_DIR}/toolkit/toolchain/hcc/bin/aarch64-target-linux-gnu-g++)14 set(CMAKE_CXX_COMPILER ${ASCEND_DIR}/toolkit/toolchain/hcc/bin/aarch64-target-linux-gnu-g++)
15 endif()15 endif()
16 16 
17- # aicpu json17+ # aicpu op_def
18- file(GLOB_RECURSE JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/*.json)18+ file(GLOB_RECURSE OP_DEF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/*_aicpu_def.cpp)
19- set_property(GLOBAL APPEND PROPERTY AICPU_JSON_FILES ${JSON_FILE})19+ set_property(GLOBAL APPEND PROPERTY AICPU_OP_DEF_FILES ${OP_DEF_FILE})
20 20 
21 # aicpu cust kernel21 # aicpu cust kernel
22- file(GLOB AICPU_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*_aicpu*.cpp)22+ file(GLOB AICPU_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*_aicpu.cpp)
23 message(STATUS "[crop_and_resize] Found aicpu sources: ${AICPU_SRC}, ascend dir: ${ASCEND_DIR}, ophsot name: ${OPHOST_NAME}")23 message(STATUS "[crop_and_resize] Found aicpu sources: ${AICPU_SRC}, ascend dir: ${ASCEND_DIR}, ophsot name: ${OPHOST_NAME}")
24 24 
25 set(OBJ_NAME crop_and_resize_cust_obj)25 set(OBJ_NAME crop_and_resize_cust_obj)
@@ -1,35 +0,0 @@
1-{
2- "CropAndResize":{
3- "opInfo":{
4- "computeCost":"100",
5- "engine":"DNN_VM_AICPU",
6- "flagAsync":"False",
7- "flagPartial":"False",
8- "functionName":"RunCpuKernel",
9- "kernelSo":"libcv_aicpu_kernels.so",
10- "opKernelLib":"CUSTAICPUKernel",
11- "userDefined":"True",
12- "workspaceSize":"100"
13- },
14- "input0":{
15- "name":"x",
16- "type":"DT_FLOAT,DT_FLOAT16,DT_DOUBLE,DT_UINT8,DT_INT8,DT_UINT16,DT_INT16,DT_INT32,DT_INT64"
17- },
18- "input1":{
19- "name":"boxes",
20- "type":"DT_FLOAT"
21- },
22- "input2":{
23- "name":"box_index",
24- "type":"DT_INT32"
25- },
26- "input3":{
27- "name":"crop_size",
28- "type":"DT_INT32"
29- },
30- "output0":{
31- "name":"y",
32- "type":"DT_FLOAT"
33- }
34- }
35-}
@@ -0,0 +1,46 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file crop_and_resize_aicpu_def.cpp
13+ * \brief crop_and_resize def
14+ */
15+ 
16+#include "register/op_def_registry.h"
17+#include "../../../common/inc/aicpu/aicpu_op_def.h"
18+ 
19+namespace ops {
20+/*
21+此配置项针对动态shape的场景,配置AI CPU的infershape方式,有以下几种取值:
22+1:根据inputshape可直接推导outputshape。
23+2:部分计算的infershape,根据tensorData的值做简单的计算。
24+3:全部计算的infershape,但最大shape可预估,按照算子最大的shape申请内存。
25+4:无法由inputshape推导出算子的输出shape,也无法推导出输出range,此种情况需要在算子实现时进行内存的申请,计算完成后,返回output和输出shape。
26+默认值为1。
27+*/
28+class CropAndResize : public OpDef {
zhaowenrui

李伟:构造函数中使this指针会不会抛异常

likedislike
zhaowenrui
zhaowenrui
Apr 1 Comments:
29+public:
30+ explicit CropAndResize(const char* name) : OpDef(name)
31+ {
32+ ApplyCvAicpuDefaultCfg(*this);
33+ this->Input("x").DataType(
34+ {ge::DT_FLOAT, ge::DT_FLOAT16, ge::DT_DOUBLE, ge::DT_UINT8, ge::DT_INT8, ge::DT_UINT16, ge::DT_INT16, ge::DT_INT32, ge::DT_INT64});
35+ this->Input("boxes").DataType({ge::DT_FLOAT});
36+ this->Input("box_index").DataType({ge::DT_INT32});
37+ this->Input("crop_size").DataType({ge::DT_INT32});
38+ this->Output("y").DataType({ge::DT_FLOAT});
39+ this->Attr("extrapolation_value").AttrType(OPTIONAL).Float(0);
40+ this->Attr("method").AttrType(OPTIONAL).String("bilinear");
D

构造函数里面放这么多函数调用是否合适?如果出现异常如何处理

likedislike
zhaowenrui
zhaowenrui
Apr 1 Comments:
41+ this->AICPU().ExtendCfgInfo(OP_INFO_OPS_FLAG.c_str(), OPEN_OPS_FLAG.c_str());
42+ }
43+};
44+ 
45+OP_ADD(CropAndResize);
46+} // namespace ops
@@ -15,12 +15,12 @@ if (BUILD_WITH_INSTALLED_DEPENDENCY_CANN_PKG)
15 set(CMAKE_CXX_COMPILER ${ASCEND_DIR}/toolkit/toolchain/hcc/bin/aarch64-target-linux-gnu-g++)15 set(CMAKE_CXX_COMPILER ${ASCEND_DIR}/toolkit/toolchain/hcc/bin/aarch64-target-linux-gnu-g++)
16 endif()16 endif()
17 17 
18- # aicpu json18+ # aicpu op_def
19- file(GLOB_RECURSE JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/*.json)19+ file(GLOB_RECURSE OP_DEF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/*_aicpu_def.cpp)
20- set_property(GLOBAL APPEND PROPERTY AICPU_JSON_FILES ${JSON_FILE})20+ set_property(GLOBAL APPEND PROPERTY AICPU_OP_DEF_FILES ${OP_DEF_FILE})
21 21 
22 # aicpu cust kernel22 # aicpu cust kernel
23- file(GLOB AICPU_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*_aicpu*.cpp)23+ file(GLOB AICPU_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*_aicpu.cpp)
24 message(STATUS "[image_warp_offsets] Found aicpu sources: ${AICPU_SRC}, ascend dir: ${ASCEND_DIR}, ophsot name: ${OPHOST_NAME}")24 message(STATUS "[image_warp_offsets] Found aicpu sources: ${AICPU_SRC}, ascend dir: ${ASCEND_DIR}, ophsot name: ${OPHOST_NAME}")
25 25 
26 set(OBJ_NAME image_warp_offsets_cust_obj)26 set(OBJ_NAME image_warp_offsets_cust_obj)
@@ -1,15 +0,0 @@
1-{
2- "IMGWarpOffsets":{
3- "opInfo":{
4- "computeCost":"100",
5- "engine":"DNN_VM_AICPU",
6- "flagAsync":"False",
7- "flagPartial":"False",
8- "functionName":"RunCpuKernel",
9- "kernelSo":"libcv_aicpu_kernels.so",
10- "opKernelLib":"CUSTAICPUKernel",
11- "userDefined":"True",
12- "workspaceSize":"100"
13- }
14- }
15-}
@@ -0,0 +1,34 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file image_warp_offsets_aicpu_def.cpp
13+ * \brief image_warp_offsets def
14+ */
15+ 
16+#include "register/op_def_registry.h"
17+#include "../../../common/inc/aicpu/aicpu_op_def.h"
18+ 
19+namespace ops {
20+class IMGWarpOffsets : public OpDef {
21+public:
22+ explicit IMGWarpOffsets(const char* name) : OpDef(name)
23+ {
24+ ApplyCvAicpuDefaultCfg(*this);
25+ this->Input("images").DataType({ge::DT_UINT8, ge::DT_FLOAT16, ge::DT_FLOAT});
26+ this->Input("offsets").DataType({ge::DT_FLOAT, ge::DT_INT32});
27+ this->Output("warp_images").DataType({ge::DT_UINT8, ge::DT_FLOAT16, ge::DT_FLOAT});
28+ this->AICPU().ExtendCfgInfo(OP_INFO_OPS_FLAG.c_str(), OPEN_OPS_FLAG.c_str());
29+ 
30+ }
31+};
32+ 
33+OP_ADD(IMGWarpOffsets);
34+} // namespace ops
@@ -14,12 +14,12 @@ if (BUILD_WITH_INSTALLED_DEPENDENCY_CANN_PKG)
14 set(CMAKE_CXX_COMPILER ${ASCEND_DIR}/toolkit/toolchain/hcc/bin/aarch64-target-linux-gnu-g++)14 set(CMAKE_CXX_COMPILER ${ASCEND_DIR}/toolkit/toolchain/hcc/bin/aarch64-target-linux-gnu-g++)
15 endif()15 endif()
16 16 
17- # aicpu json17+ # aicpu op_def
18- file(GLOB_RECURSE JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/*.json)18+ file(GLOB_RECURSE OP_DEF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/*_aicpu_def.cpp)
19- set_property(GLOBAL APPEND PROPERTY AICPU_JSON_FILES ${JSON_FILE})19+ set_property(GLOBAL APPEND PROPERTY AICPU_OP_DEF_FILES ${OP_DEF_FILE})
20 20 
21 # aicpu cust kernel21 # aicpu cust kernel
22- file(GLOB AICPU_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*_aicpu*.cpp)22+ file(GLOB AICPU_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*_aicpu.cpp)
23 message(STATUS "[non_max_suppression_v3] Found aicpu sources: ${AICPU_SRC}, ascend dir: ${ASCEND_DIR}, ophsot name: ${OPHOST_NAME}")23 message(STATUS "[non_max_suppression_v3] Found aicpu sources: ${AICPU_SRC}, ascend dir: ${ASCEND_DIR}, ophsot name: ${OPHOST_NAME}")
24 24 
25 set(OBJ_NAME non_max_suppression_v3_cust_obj)25 set(OBJ_NAME non_max_suppression_v3_cust_obj)
@@ -1,15 +0,0 @@
1-{
2- "NonMaxSuppressionV3":{
3- "opInfo":{
4- "computeCost":"100",
5- "engine":"DNN_VM_AICPU",
6- "flagAsync":"False",
7- "flagPartial":"False",
8- "functionName":"RunCpuKernel",
9- "kernelSo":"libcv_aicpu_kernels.so",
10- "opKernelLib":"CUSTAICPUKernel",
11- "userDefined":"True",
12- "workspaceSize":"100"
13- }
14- }
15-}
@@ -0,0 +1,36 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file non_max_suppression_v3_aicpu_def.cpp
13+ * \brief non_max_suppression_v3 def
14+ */
15+ 
16+#include "register/op_def_registry.h"
17+#include "../../../common/inc/aicpu/aicpu_op_def.h"
18+ 
19+namespace ops {
20+class NonMaxSuppressionV3 : public OpDef {
21+public:
22+ explicit NonMaxSuppressionV3(const char* name) : OpDef(name)
23+ {
24+ ApplyCvAicpuDefaultCfg(*this);
25+ this->Input("boxes").DataType({ge::DT_FLOAT, ge::DT_FLOAT16});
26+ this->Input("scores").DataType({ge::DT_FLOAT, ge::DT_FLOAT16});
27+ this->Input("max_output_size").DataType({ge::DT_INT32});
28+ this->Input("iou_threshold").DataType({ge::DT_FLOAT, ge::DT_FLOAT16});
29+ this->Input("score_threshold").DataType({ge::DT_FLOAT, ge::DT_FLOAT16});
30+ this->Output("selected_indices").DataType({ge::DT_INT32});
31+ this->AICPU().ExtendCfgInfo(OP_INFO_SUB_TYPE_OF_INFERSHAPE.c_str(), DEFAULT_SUB_TYPE_OF_INFERSHAPE_4.c_str());
32+ }
33+};
34+ 
35+OP_ADD(NonMaxSuppressionV3);
36+} // namespace ops
@@ -1,26 +1,36 @@
1#!/usr/bin/env python31#!/usr/bin/env python3
2# -*- coding: utf-8 -*-2# -*- coding: utf-8 -*-
3-# ---------------------------------------------------------------------------------------------------------3+# ----------------------------------------------------------------------------
4-# Copyright (c) 2025 Huawei Technologies Co., Ltd.4+# Copyright (c) 2025-2026 Huawei Technologies Co., Ltd.
5-# This program is free software, you can redistribute it and/or modify it under the terms and conditions of 5+# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
6# CANN Open Software License Agreement Version 2.0 (the "License").6# CANN Open Software License Agreement Version 2.0 (the "License").
7# Please refer to the License for details. You may not use this file except in compliance with the License.7# Please refer to the License for details. You may not use this file except in compliance with the License.
8-# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 8+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
9-# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. 9+# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
10# See LICENSE in the root of the software repository for the full text of the License.10# See LICENSE in the root of the software repository for the full text of the License.
11- 
12-# The code snippet comes from Huawei's open-source Ascend project.
13-# Copyright 2020 Huawei Technologies Co., Ltd
14-# Licensed under the Apache License, Version 2.0 (the "License");
15-# You may obtain a copy of the License at
16-# http://www.apache.org/licenses/LICENSE-2.0
17-#
18# ----------------------------------------------------------------------------11# ----------------------------------------------------------------------------
19 12 
20import json13import json
21import os14import os
22import stat15import stat
23import sys16import sys
17+from operator import truediv
18+ 
19+required_op_input_info_keys = ["paramType", "name"]
20+required_op_output_info_keys = ["paramType", "name"]
21+param_type_valid_value = ["dynamic", "optional", "required"]
22+required_attr_key = ["type", "value", "paramType"]
23+aicpu_infershape_subtype_valid_value = ["1", "2", "3", "4"]
24+aicpu_ops_flag_valid_value = ["OPS_FLAG_OPEN", "OPS_FLAG_CLOSE"]
25+# workspaceSize is valid when it is within the inclusive range [100, 500]
26+AICPU_WORKSPACE_SIZE_MIN = 100
27+AICPU_WORKSPACE_SIZE_MAX = 500
28+aicpu_kernel_so_valid_value = [
29+ "libmath_aicpu_kernels.so",
30+ "libcv_aicpu_kernels.so",
31+ "libnn_aicpu_kernels.so",
32+ "libtransformer_aicpu_kernels.so",
33+]
24 34 
25 35 
26def parse_ini_files(ini_files):36def parse_ini_files(ini_files):
@@ -63,61 +73,146 @@ def parse_ini_to_obj(ini_file, tbe_ops_info):
63 op = {}73 op = {}
64 tbe_ops_info[op_name] = op74 tbe_ops_info[op_name] = op
65 else:75 else:
66- key1 = line[:line.index("=")].strip()76+ key1 = line[: line.index("=")].strip()
67- key2 = line[line.index("=")+1:].strip()77+ key2 = line[line.index("=") + 1:].strip()
68 key1_0, key1_1 = key1.split(".")78 key1_0, key1_1 = key1.split(".")
69 if not key1_0 in op:79 if not key1_0 in op:
70 op[key1_0] = {}80 op[key1_0] = {}
71 if key1_1 in op[key1_0]:81 if key1_1 in op[key1_0]:
72- raise RuntimeError("Op:" + op_name + " " + key1_0 + " " + key1_1 + " is repeated!")82+ raise RuntimeError(
83+ "Op:" + op_name + " " + key1_0 + " " + key1_1 + " is repeated!"
84+ )
73 op[key1_0][key1_1] = key285 op[key1_0][key1_1] = key2
74 86 
75 87 
88+def is_cpu_engine(op_engine):
89+ """判断是否为 AICPU 引擎"""
90+ return op_engine == "DNN_VM_AICPU"
91+ 
92+ 
93+def check_required_keys(op_info, required_keys, op_engine):
94+ """检查必需字段是否存在,AICPU 算子跳过 paramType 检查"""
95+ missing_keys = []
96+ for required_key in required_keys:
97+ # AICPU 算子不需要 paramType 字段
98+ if is_cpu_engine(op_engine) and required_key == "paramType":
99+ continue
100+ if required_key not in op_info:
101+ missing_keys.append(required_key)
102+ return missing_keys
103+ 
104+ 
105+def check_param_type(op_info, op_engine, error_message):
106+ """检查 paramType 是否合法,AICPU 算子跳过检查"""
107+ if is_cpu_engine(op_engine):
108+ return True
109+ if op_info.get("paramType") not in param_type_valid_value:
110+ print(error_message)
111+ return False
112+ return True
113+ 
114+ 
115+def check_infershape_subtype(op_info):
116+ """检查 AICPU 的 subTypeOfInferShape 字段是否合法"""
117+ if op_info.get("subTypeOfInferShape") not in aicpu_infershape_subtype_valid_value:
118+ return False
119+ return True
120+ 
121+ 
122+def check_ops_flag(op_info):
123+ """检查 AICPU 的 opsFlag 字段是否合法"""
124+ if op_info.get("opsFlag") not in aicpu_ops_flag_valid_value:
125+ return False
126+ return True
127+ 
128+ 
129+def check_workspace_size(op_info):
130+ """检查 AICPU 的 workspaceSize 是否在 [100, 500] 范围内"""
131+ workspace_size = op_info.get("workspaceSize")
132+ try:
133+ workspace_size = int(workspace_size)
134+ except (TypeError, ValueError):
135+ return False
136+ return AICPU_WORKSPACE_SIZE_MIN <= workspace_size <= AICPU_WORKSPACE_SIZE_MAX
137+ 
138+ 
139+def check_opkernel_so(op_info):
140+ """检查 kernelSo 是否在白名单中"""
141+ if op_info.get("kernelSo") not in aicpu_kernel_so_valid_value:
142+ return False
143+ return True
144+ 
145+ 
146+def validate_io_info(op_key, op_info_key, op_info, op_engine, required_keys):
147+ """校验输入或输出信息"""
148+ is_valid = True
149+ missing_keys = check_required_keys(op_info, required_keys, op_engine)
150+ if missing_keys:
151+ print(f"op: {op_key} {op_info_key} missing: {','.join(missing_keys)}")
152+ is_valid = False
153+ 
154+ error_message = f"op: {op_key} {op_info_key} paramType not valid, valid key:{param_type_valid_value}"
155+ if not check_param_type(op_info, op_engine, error_message):
156+ is_valid = False
157+ 
158+ return is_valid
159+ 
160+ 
161+def validate_optional_info(op_key, op_info_key, op_info):
162+ """校验 AICPU 的可选字段"""
163+ is_valid = True
164+ if "subTypeOfInferShape" in op_info and not check_infershape_subtype(op_info):
liu-wei
liu-weiliu-weiApr 1

必选参数不全,应该是有8个参数的。没有的补齐一下。

likedislike
165+ print(f"op: {op_key} {op_info_key} infershape_subtype not valid"
166+ f" valid key: {aicpu_infershape_subtype_valid_value}")
167+ is_valid = False
168+ if "opsFlag" in op_info and not check_ops_flag(op_info):
169+ print(f"op: {op_key} {op_info_key} opsFlag not valid"
170+ f" valid key: {aicpu_ops_flag_valid_value}")
171+ is_valid = False
172+ if "workspaceSize" in op_info and not check_workspace_size(op_info):
173+ print(f"op: {op_key} {op_info_key} workspaceSize not valid"
174+ f" valid range: [{AICPU_WORKSPACE_SIZE_MIN}, {AICPU_WORKSPACE_SIZE_MAX}]")
175+ is_valid = False
176+ if "kernelSo" in op_info and not check_opkernel_so(op_info):
177+ print(f"op: {op_key} {op_info_key} kernelSo not valid"
178+ f" valid key: {aicpu_kernel_so_valid_value}")
179+ is_valid = False
180+ return is_valid
181+ 
182+ 
76def check_op_info(tbe_ops):183def check_op_info(tbe_ops):
77- """184+ """校验算子信息"""
liu-wei
liu-weiliu-weiApr 1

公共流程修改,上库前编译下check.sh看看aicore算子产物,不要影响了已有流程。

likedislike
78- Check info info
79- """
80 print("\n\n==============check valid for ops info start==============")185 print("\n\n==============check valid for ops info start==============")
81- not_valid_op = []186+ 
82- required_op_input_info_keys = ["paramType", "name"]187+ io_required_keys_map = {
83- required_op_output_info_keys = ["paramType", "name"]188+ "input": required_op_input_info_keys,
84- shape_type_valid_value = ["fix", "range", "list"]189+ "output": required_op_output_info_keys,
85- need_compile_valid_value = ["true", "false"]190+ }
86- param_type_valid_value = ["dynamic", "optional", "required"]
87- required_attr_key = ["type", "value", "paramType"]
88 is_valid = True191 is_valid = True
89 for op_key in tbe_ops:192 for op_key in tbe_ops:
90 op = tbe_ops[op_key]193 op = tbe_ops[op_key]
194+ op_engine = op.get("opInfo", {}).get("engine", "") if isinstance(op, dict) else ""
91 195 
92 for op_info_key in op:196 for op_info_key in op:
197+ op_info_flag = False
198+ io_prefix = ""
93 if op_info_key.startswith("input"):199 if op_info_key.startswith("input"):
94- op_input_info = op[op_info_key]200+ io_prefix = "input"
95- missing_keys = []201+ elif op_info_key.startswith("output"):
96- for required_op_input_info_key in required_op_input_info_keys:202+ io_prefix = "output"
97- if not required_op_input_info_key in op_input_info:203+ elif op_info_key.startswith("opInfo"):
98- missing_keys.append(required_op_input_info_key)204+ op_info_flag = True
99- if len(missing_keys) > 0:205+ else:
100- print("op: " + op_key + " " + op_info_key + " missing: " + ",".join(missing_keys))206+ continue
101- is_valid = False207+ 
102- else:208+ op_info = op[op_info_key]
103- if not op_input_info["paramType"] in param_type_valid_value:209+ if io_prefix != "" and not validate_io_info(
104- print("op: " + op_key + " " + op_info_key + \210+ op_key, op_info_key, op_info, op_engine, io_required_keys_map.get(io_prefix)
105- " paramType not valid, valid key:[dynamic, optional, required]")211+ ):
106- is_valid = False212+ is_valid = False
107- if op_info_key.startswith("output"):213+ if is_cpu_engine(op_engine) and op_info_flag and not validate_optional_info(op_key, op_info_key, op_info):
108- op_input_info = op[op_info_key]214+ is_valid = False
109- missing_keys = []215+ 
110- for required_op_input_info_key in required_op_output_info_keys:
111- if not required_op_input_info_key in op_input_info:
112- missing_keys.append(required_op_input_info_key)
113- if len(missing_keys) > 0:
114- print("op: " + op_key + " " + op_info_key + " missing: " + ",".join(missing_keys))
115- is_valid = False
116- else:
117- if not op_input_info["paramType"] in param_type_valid_value:
118- print("op: " + op_key + " " + op_info_key + \
119- " paramType not valid, valid key:[fix, range, list]")
120- is_valid = False
121 print("==============check valid for ops info end================\n\n")216 print("==============check valid for ops info end================\n\n")
122 return is_valid217 return is_valid
123 218