已合并
feat: 迁移Yolo系列和TransArgb ONNX插件 #1122
tianqiguang创建于 7月14日
feat: 迁移Yolo系列和TransArgb ONNX插件 #1122
已合并
tianqiguang创建于 7月14日
9 个文件变更+968-229
M.clang-format+4-0
@@ -47,6 +47,10 @@ AllowAllParametersOfDeclarationOnNextLine: true
47AlwaysBreakBeforeMultilineStrings: false47AlwaysBreakBeforeMultilineStrings: false
48AlwaysBreakTemplateDeclarations: true48AlwaysBreakTemplateDeclarations: true
49 49 
50+# 宏语句定义
51+StatementMacros:
52+ - OP_END_FACTORY_REG
53+ 
50BinPackArguments: true54BinPackArguments: true
51BreakBeforeTernaryOperators: false55BreakBeforeTernaryOperators: false
52SpacesBeforeTrailingComments: 156SpacesBeforeTrailingComments: 1
Mcommon/inc/op_graph/op_cv_proto_extend.h+469-229
@@ -1,230 +1,470 @@
1-/**1+/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3- * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3+ * 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").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.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,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.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.8+ * See LICENSE in the root of the software repository for the full text of the License.
9- */9+ */
10- 10+ 
11-/*!11+/*!
12- * \file op_cv_proto_extend.h12+ * \file op_cv_proto_extend.h
13- * \brief13+ * \brief
14- */14+ */
15-#ifndef OPS_OP_CV_PROTO_EXTEND_H_15+#ifndef OPS_OP_CV_PROTO_EXTEND_H_
16-#define OPS_OP_CV_PROTO_EXTEND_H_16+#define OPS_OP_CV_PROTO_EXTEND_H_
17- 17+ 
18-#include "graph/operator_reg.h"18+#include "graph/operator_reg.h"
19- 19+ 
20-namespace ge {20+namespace ge {
21-/**21+/**
22-* @brief Performs Col2ImV2 for each batch entry. \n22+* @brief Performs Col2ImV2 for each batch entry. \n
23- 23+ 
24-* @par Inputs:24+* @par Inputs:
25-* @li x: The Col Tensor. 3-D, shape: `(n, c*kernel_h*kernel_w, ho*wo)`.25+* @li x: The Col Tensor. 3-D, shape: `(n, c*kernel_h*kernel_w, ho*wo)`.
26-where ho/wo is do = (output_d + 2*padding_d - dilation_d*(kernel_d - 1) - 1)//stride_d + 1.26+where ho/wo is do = (output_d + 2*padding_d - dilation_d*(kernel_d - 1) - 1)//stride_d + 1.
27-* @li output_size: The img shape Tensor. 1-D, shape:`(2)`, value: (output_h, output_w).27+* @li output_size: The img shape Tensor. 1-D, shape:`(2)`, value: (output_h, output_w).
28-* @li kernel_shape: The kernel size Tensor. 1-D , value: `(kernel_h, kernel_w)`, the shape of kernel in convolution. \n28+* @li kernel_shape: The kernel size Tensor. 1-D , value: `(kernel_h, kernel_w)`, the shape of kernel in convolution. \n
29- 29+ 
30-* @par Outputs:30+* @par Outputs:
31-* y: The img Tensor. 4-D, shape: `(n, c, output_h, output_w)`. \n31+* y: The img Tensor. 4-D, shape: `(n, c, output_h, output_w)`. \n
32- 32+ 
33-* @par Attributes:33+* @par Attributes:
34- 34+ 
35-* @li dilation: ListInt, value: `(dilation_h, dilation_w)`, the dilation in convolution.35+* @li dilation: ListInt, value: `(dilation_h, dilation_w)`, the dilation in convolution.
36-* @li padding: ListInt, value: `(padding_h, padding_w)`, the dilation in convolution.36+* @li padding: ListInt, value: `(padding_h, padding_w)`, the dilation in convolution.
37-* @li stride: ListInt, value: `(stride_h, stride_w)`, the dilation in convolution. \n37+* @li stride: ListInt, value: `(stride_h, stride_w)`, the dilation in convolution. \n
38- 38+ 
39-* @par Third-party framework compatibility39+* @par Third-party framework compatibility
40-* Compatible with ONNX Col2Im operator.40+* Compatible with ONNX Col2Im operator.
41-*/41+*/
42-REG_OP(Col2ImV2)42+REG_OP(Col2ImV2)
43- .INPUT(x, TensorType({DT_FLOAT, DT_FLOAT16}))43+ .INPUT(x, TensorType({DT_FLOAT, DT_FLOAT16}))
44- .INPUT(output_size, TensorType({DT_INT32, DT_INT32}))44+ .INPUT(output_size, TensorType({DT_INT32, DT_INT32}))
45- .INPUT(kernel_size, TensorType({DT_INT32, DT_INT32}))45+ .INPUT(kernel_size, TensorType({DT_INT32, DT_INT32}))
46- .OUTPUT(y, TensorType({DT_FLOAT, DT_FLOAT16}))46+ .OUTPUT(y, TensorType({DT_FLOAT, DT_FLOAT16}))
47- .REQUIRED_ATTR(dilation, ListInt)47+ .REQUIRED_ATTR(dilation, ListInt)
48- .REQUIRED_ATTR(padding, ListInt)48+ .REQUIRED_ATTR(padding, ListInt)
49- .REQUIRED_ATTR(stride, ListInt)49+ .REQUIRED_ATTR(stride, ListInt)
50- .OP_END_FACTORY_REG(Col2ImV2)50+ .OP_END_FACTORY_REG(Col2ImV2)
51- 51+ 
52- /**52+/**
53- * @brief First calculate the minimum closure area of the two boxes, IoU,53+* @brief First calculate the minimum closure area of the two boxes, IoU,
54- * the proportion of the closed area that does not belong to the two boxes in the closure area,54+* the proportion of the closed area that does not belong to the two boxes in the closure area,
55- * and finally subtract this proportion from IoU to get GIoU . \n55+* and finally subtract this proportion from IoU to get GIoU . \n
56- 56+ 
57- * @par Inputs:57+* @par Inputs:
58- * Two inputs, including:58+* Two inputs, including:
59- * @li bboxes: Bounding boxes, a 2D Tensor of type float16 or float32 with59+* @li bboxes: Bounding boxes, a 2D Tensor of type float16 or float32 with
60- * shape (N, 4). "N" indicates the number of bounding boxes, and the value60+* shape (N, 4). "N" indicates the number of bounding boxes, and the value
61- * "4" refers to [x1, y1, x2, y2] or [x, y, w, h].61+* "4" refers to [x1, y1, x2, y2] or [x, y, w, h].
62- * @li gtboxes: Ground-truth boxes, a 2D Tensor of type float16 or float3262+* @li gtboxes: Ground-truth boxes, a 2D Tensor of type float16 or float32
63- * with shape (M, 4). "M" indicates the number of ground truth boxes, and63+* with shape (M, 4). "M" indicates the number of ground truth boxes, and
64- * the value "4" refers to [x1, y1, x2, y2] or [x, y, w, h] . \n64+* the value "4" refers to [x1, y1, x2, y2] or [x, y, w, h] . \n
65- 65+ 
66- * @par Attributes:66+* @par Attributes:
67- * @li trans: An optional bool, true for 'xywh', false for 'xyxy'.67+* @li trans: An optional bool, true for 'xywh', false for 'xyxy'.
68- * @li is_cross: An optional bool, control whether the output shape is [M, N] or [1, N]68+* @li is_cross: An optional bool, control whether the output shape is [M, N] or [1, N]
69- * @li mode: Computation mode, a character string with the value range of [iou, iof] . \n69+* @li mode: Computation mode, a character string with the value range of [iou, iof] . \n
70- 70+ 
71- * @par Outputs:71+* @par Outputs:
72- * overlap: A 2D Tensor of type float16 or float32 with shape [M, N] or [1, N],72+* overlap: A 2D Tensor of type float16 or float32 with shape [M, N] or [1, N],
73- * specifying the IoU or IoF ratio . \n73+* specifying the IoU or IoF ratio . \n
74- 74+ 
75- * @attention Constraints:75+* @attention Constraints:
76- * Only computation of float16 data is supported. To avoid overflow, the input76+* Only computation of float16 data is supported. To avoid overflow, the input
77- * length and width are scaled by 0.2 internally.77+* length and width are scaled by 0.2 internally.
78- */78+*/
79- REG_OP(GIoU)79+REG_OP(GIoU)
80- .INPUT(bboxes, TensorType({DT_FLOAT16, DT_FLOAT}))80+ .INPUT(bboxes, TensorType({DT_FLOAT16, DT_FLOAT}))
81- .INPUT(gtboxes, TensorType({DT_FLOAT16, DT_FLOAT}))81+ .INPUT(gtboxes, TensorType({DT_FLOAT16, DT_FLOAT}))
82- .OUTPUT(overlap, TensorType({DT_FLOAT16, DT_FLOAT}))82+ .OUTPUT(overlap, TensorType({DT_FLOAT16, DT_FLOAT}))
83- .ATTR(trans, Bool, false)83+ .ATTR(trans, Bool, false)
84- .ATTR(is_cross, Bool, true)84+ .ATTR(is_cross, Bool, true)
85- .ATTR(mode, String, "iou")85+ .ATTR(mode, String, "iou")
86- .OP_END_FACTORY_REG(GIoU)86+ .OP_END_FACTORY_REG(GIoU)
87- 87+ 
88- /**88+/**
89- *@brief RotatedIou . \n89+*@brief RotatedIou . \n
90- 90+ 
91- * @par Inputs:91+* @par Inputs:
92- *@li boxes : data of grad increment, a 3D Tensor of type float32 with92+*@li boxes : data of grad increment, a 3D Tensor of type float32 with
93- * shape (B, 5, N). "N" indicates the number of boxes, and the value93+* shape (B, 5, N). "N" indicates the number of boxes, and the value
94- * "5" refers to [x1, y1, x2, y2, theta] or [x, y, w, h, theta].94+* "5" refers to [x1, y1, x2, y2, theta] or [x, y, w, h, theta].
95- * @li query_boxes: Bounding boxes, a 3D Tensor of type float32 with95+* @li query_boxes: Bounding boxes, a 3D Tensor of type float32 with
96- * shape (B, 5, K). "K" indicates the number of boxes, and the value96+* shape (B, 5, K). "K" indicates the number of boxes, and the value
97- * "5" refers to [x1, y1, x2, y2, theta] or [x, y, w, h, theta].97+* "5" refers to [x1, y1, x2, y2, theta] or [x, y, w, h, theta].
98- 98+ 
99- * @par Attributes:99+* @par Attributes:
100- *@li trans: An optional attr, true for 'xyxyt', false for 'xywht'.100+*@li trans: An optional attr, true for 'xyxyt', false for 'xywht'.
101- * @li mode: An optional attr, a character string with the value range of ['iou', 'iof'],101+* @li mode: An optional attr, a character string with the value range of ['iou', 'iof'],
102- * only support 'iou' now.102+* only support 'iou' now.
103- *@li is_cross: Cross calculation when it is True, and one-to-one calculation when it is False.103+*@li is_cross: Cross calculation when it is True, and one-to-one calculation when it is False.
104- *@li v_threshold: An optional attr, provide condition relaxation for intersection calculation.104+*@li v_threshold: An optional attr, provide condition relaxation for intersection calculation.
105- * @li e_threshold: An optional attr, provide condition relaxation for intersection calculation.105+* @li e_threshold: An optional attr, provide condition relaxation for intersection calculation.
106- 106+ 
107- *@par Outputs:107+*@par Outputs:
108- * iou: A 3D Tensor of float32 with shape [B, N, K].108+* iou: A 3D Tensor of float32 with shape [B, N, K].
109- 109+ 
110- *@attention Constraints:110+*@attention Constraints:
111- * In each batch, the invalid box cannot appear before the valid box.111+* In each batch, the invalid box cannot appear before the valid box.
112- */112+*/
113- REG_OP(RotatedIou)113+REG_OP(RotatedIou)
114- .INPUT(boxes, TensorType({DT_FLOAT}))114+ .INPUT(boxes, TensorType({DT_FLOAT}))
115- .INPUT(query_boxes, TensorType({DT_FLOAT}))115+ .INPUT(query_boxes, TensorType({DT_FLOAT}))
116- .OUTPUT(iou, TensorType({DT_FLOAT}))116+ .OUTPUT(iou, TensorType({DT_FLOAT}))
117- .ATTR(trans, Bool, false)117+ .ATTR(trans, Bool, false)
118- .ATTR(mode, String, "iou")118+ .ATTR(mode, String, "iou")
119- .ATTR(is_cross, Bool, true)119+ .ATTR(is_cross, Bool, true)
120- .ATTR(v_threshold, Float, 0)120+ .ATTR(v_threshold, Float, 0)
121- .ATTR(e_threshold, Float, 0)121+ .ATTR(e_threshold, Float, 0)
122- .OP_END_FACTORY_REG(RotatedIou)122+ .OP_END_FACTORY_REG(RotatedIou)
123- 123+ 
124- /**124+/**
125- * @brief Resize the input tensor. \n125+* @brief Resize the input tensor. \n
126- currently, only support resize image tensor using nearest neighbor and linear interpolation.126+currently, only support resize image tensor using nearest neighbor and linear interpolation.
127- 127+ 
128- * @par Inputs:128+* @par Inputs:
129- * Input x must be a 4-D tensor. Inputs include: \n129+* Input x must be a 4-D tensor. Inputs include: \n
130- * @li x: A Tensor. Must be one of the following types: uint8, int8, int16, \n130+* @li x: A Tensor. Must be one of the following types: uint8, int8, int16, \n
131- int32, int64, float16, float, double. 4-D with shape [batch, height, width, channels] \n131+int32, int64, float16, float, double. 4-D with shape [batch, height, width, channels] \n
132- or shape [batch, channels, height, width].132+or shape [batch, channels, height, width].
133- * @li roi: A 1-D float Tensor. Only takes effect when attr coordinate_transformation_mode \n133+* @li roi: A 1-D float Tensor. Only takes effect when attr coordinate_transformation_mode \n
134- is "tf_crop_and_resize". Must be one of the following types: float16, float, double.134+is "tf_crop_and_resize". Must be one of the following types: float16, float, double.
135- * @li scales: A 1-D float Tensor, the scale array along each dimension, Only one of \n135+* @li scales: A 1-D float Tensor, the scale array along each dimension, Only one of \n
136- 'scales' and 'sizes' can be specified. Must be float type.136+'scales' and 'sizes' can be specified. Must be float type.
137- * @li sizes: A 1-D int64 Tensor, The size of the output tensor. Only one of \n137+* @li sizes: A 1-D int64 Tensor, The size of the output tensor. Only one of \n
138- 'scales' and 'sizes' can be specified. If 'size' is specified, then set scales \n138+'scales' and 'sizes' can be specified. If 'size' is specified, then set scales \n
139- to empty data (zero shape) in this operator's input list. Must be one of \n139+to empty data (zero shape) in this operator's input list. Must be one of \n
140- the following types: int32, int64.140+the following types: int32, int64.
141- 141+ 
142- * @par Attributes:142+* @par Attributes:
143- * @li coordinate_transformation_mode: An optional String. how to transform \n143+* @li coordinate_transformation_mode: An optional String. how to transform \n
144- the coordinate in the resized tensor to the coordinate in the original tensor. \n144+the coordinate in the resized tensor to the coordinate in the original tensor. \n
145- options: pytorch_half_pixel, align_corners, asymmetric, \n145+options: pytorch_half_pixel, align_corners, asymmetric, \n
146- tf_crop_and_resize.146+tf_crop_and_resize.
147- * @li cubic_coeff_a: An optional Float. Defaults to -0.75, only used in cubic interpolation. \n147+* @li cubic_coeff_a: An optional Float. Defaults to -0.75, only used in cubic interpolation. \n
148- other optional: -0.5148+other optional: -0.5
149- * @li exclude_outside: An optional Int. Defaults to 0, If set to 1, the weight of sampling \n149+* @li exclude_outside: An optional Int. Defaults to 0, If set to 1, the weight of sampling \n
150- locations outside the tensor will be set to 0 and the weight will be renormalized \n150+locations outside the tensor will be set to 0 and the weight will be renormalized \n
151- so that their sum is 1.0.151+so that their sum is 1.0.
152- * @li extrapolation_value: An optional Float. Defaults to 0.0f. When coordinate_transformation_mode \n152+* @li extrapolation_value: An optional Float. Defaults to 0.0f. When coordinate_transformation_mode \n
153- is "tf_crop_and_resize" and x_original is outside the range [0, length_original - 1], \n153+is "tf_crop_and_resize" and x_original is outside the range [0, length_original - 1], \n
154- this value is used as the corresponding output value.154+this value is used as the corresponding output value.
155- * @li mode: An optional String. Defaults to nearest. Three interpolation modes: nearest (default), \n155+* @li mode: An optional String. Defaults to nearest. Three interpolation modes: nearest (default), \n
156- linear and cubic.156+linear and cubic.
157- * @li nearest_mode: An optional String. Defaults to round_prefer_floor. Four modes: round_prefer_floor, \n157+* @li nearest_mode: An optional String. Defaults to round_prefer_floor. Four modes: round_prefer_floor, \n
158- round_prefer_ceil, floor, ceil. Only used by nearest interpolation.158+round_prefer_ceil, floor, ceil. Only used by nearest interpolation.
159- 159+ 
160- * @par Outputs:160+* @par Outputs:
161- * y: A Tensor. Has the same type as x.161+* y: A Tensor. Has the same type as x.
162- 162+ 
163- * @attention Constraints: \n163+* @attention Constraints: \n
164- * Input x must be a 4-D tensor.164+* Input x must be a 4-D tensor.
165- 165+ 
166- * @par Third-party framework compatibility166+* @par Third-party framework compatibility
167- * Compatible with tensorflow ResizeNearestNeighborV2 operator.167+* Compatible with tensorflow ResizeNearestNeighborV2 operator.
168- */168+*/
169- 169+ 
170- REG_OP(Resize)170+REG_OP(Resize)
171- .INPUT(x, TensorType({DT_INT8, DT_UINT8, DT_INT16, DT_UINT16, DT_INT32, DT_INT64, DT_FLOAT16, DT_FLOAT, DT_DOUBLE}))171+ .INPUT(x, TensorType({DT_INT8, DT_UINT8, DT_INT16, DT_UINT16, DT_INT32, DT_INT64, DT_FLOAT16, DT_FLOAT, DT_DOUBLE}))
172- .OPTIONAL_INPUT(roi, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE}))172+ .OPTIONAL_INPUT(roi, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE}))
173- .OPTIONAL_INPUT(scales, TensorType({DT_FLOAT}))173+ .OPTIONAL_INPUT(scales, TensorType({DT_FLOAT}))
174- .OPTIONAL_INPUT(sizes, TensorType({DT_INT64, DT_INT32}))174+ .OPTIONAL_INPUT(sizes, TensorType({DT_INT64, DT_INT32}))
175- .OUTPUT(y,175+ .OUTPUT(y,
176- TensorType({DT_INT8, DT_UINT8, DT_INT16, DT_UINT16, DT_INT32, DT_INT64, DT_FLOAT16, DT_FLOAT, DT_DOUBLE}))176+ TensorType({DT_INT8, DT_UINT8, DT_INT16, DT_UINT16, DT_INT32, DT_INT64, DT_FLOAT16, DT_FLOAT, DT_DOUBLE}))
177- .ATTR(coordinate_transformation_mode, String, "half_pixel")177+ .ATTR(coordinate_transformation_mode, String, "half_pixel")
178- .ATTR(cubic_coeff_a, Float, -0.75)178+ .ATTR(cubic_coeff_a, Float, -0.75)
179- .ATTR(exclude_outside, Int, 0)179+ .ATTR(exclude_outside, Int, 0)
180- .ATTR(extrapolation_value, Float, 0.0)180+ .ATTR(extrapolation_value, Float, 0.0)
181- .ATTR(mode, String, "nearest")181+ .ATTR(mode, String, "nearest")
182- .ATTR(nearest_mode, String, "round_prefer_floor")182+ .ATTR(nearest_mode, String, "round_prefer_floor")
183- .OP_END_FACTORY_REG(Resize)183+ .OP_END_FACTORY_REG(Resize)
184- 184+ 
185- /**185+/**
186- *@brief Greedily selects a subset of bounding boxes in descending order of186+*@brief Greedily selects a subset of bounding boxes in descending order of
187- score . \n187+score . \n
188- 188+ 
189- *@par Inputs:189+*@par Inputs:
190- *Input boxes and scores must be float type. Inputs include:190+*Input boxes and scores must be float type. Inputs include:
191- *@li boxes: A 2-D float tensor of shape [num_boxes, 4].191+*@li boxes: A 2-D float tensor of shape [num_boxes, 4].
192- *@li scores: A 1-D float tensor of shape [num_boxes] representing a single192+*@li scores: A 1-D float tensor of shape [num_boxes] representing a single
193- score corresponding to each box (each row of boxes).193+score corresponding to each box (each row of boxes).
194- *@li max_output_size: A scalar integer tensor representing the maximum number194+*@li max_output_size: A scalar integer tensor representing the maximum number
195- of boxes to be selected by non max suppression.195+of boxes to be selected by non max suppression.
196- *@li iou_threshold: A 0-D float tensor representing the threshold for deciding196+*@li iou_threshold: A 0-D float tensor representing the threshold for deciding
197- whether boxes overlap too much with respect to IOU.197+whether boxes overlap too much with respect to IOU.
198- *@li score_threshold: A 0-D float tensor representing the threshold for198+*@li score_threshold: A 0-D float tensor representing the threshold for
199- deciding when to remove boxes based on score . \n199+deciding when to remove boxes based on score . \n
200- 200+ 
201- *@par Attributes:201+*@par Attributes:
202- *pad_to_max_output_size: If true, the output selected_indices is padded202+*pad_to_max_output_size: If true, the output selected_indices is padded
203- to be of length max_output_size. Defaults to false . \n203+to be of length max_output_size. Defaults to false . \n
204- 204+ 
205- *@par Outputs:205+*@par Outputs:
206- *@li selected_indices: A 1-D integer tensor of shape [M] representing the206+*@li selected_indices: A 1-D integer tensor of shape [M] representing the
207- selected indices from the boxes tensor, where M <= max_output_size.207+selected indices from the boxes tensor, where M <= max_output_size.
208- *@li valid_outputs: A 0-D integer tensor representing the number of valid208+*@li valid_outputs: A 0-D integer tensor representing the number of valid
209- elements in selected_indices, with the valid elements appearing first . \n209+elements in selected_indices, with the valid elements appearing first . \n
210- 210+ 
211- *@attention Constraints:211+*@attention Constraints:
212- *Input boxes and scores must be float type . \n212+*Input boxes and scores must be float type . \n
213- 213+ 
214- *@par Third-party framework compatibility214+*@par Third-party framework compatibility
215- *Compatible with tensorflow NonMaxSuppressionV4 operator.215+*Compatible with tensorflow NonMaxSuppressionV4 operator.
216- */216+*/
217- 217+ 
218- REG_OP(NonMaxSuppressionV4)218+REG_OP(NonMaxSuppressionV4)
219- .INPUT(boxes, TensorType({DT_FLOAT16, DT_FLOAT}))219+ .INPUT(boxes, TensorType({DT_FLOAT16, DT_FLOAT}))
220- .INPUT(scores, TensorType({DT_FLOAT16, DT_FLOAT}))220+ .INPUT(scores, TensorType({DT_FLOAT16, DT_FLOAT}))
221- .INPUT(max_output_size, TensorType({DT_INT32}))221+ .INPUT(max_output_size, TensorType({DT_INT32}))
222- .INPUT(iou_threshold, TensorType({DT_FLOAT16, DT_FLOAT}))222+ .INPUT(iou_threshold, TensorType({DT_FLOAT16, DT_FLOAT}))
223- .INPUT(score_threshold, TensorType({DT_FLOAT16, DT_FLOAT}))223+ .INPUT(score_threshold, TensorType({DT_FLOAT16, DT_FLOAT}))
224- .OUTPUT(selected_indices, TensorType({DT_INT32}))224+ .OUTPUT(selected_indices, TensorType({DT_INT32}))
225- .OUTPUT(valid_outputs, TensorType({DT_INT32}))225+ .OUTPUT(valid_outputs, TensorType({DT_INT32}))
226- .ATTR(pad_to_max_output_size, Bool, false)226+ .ATTR(pad_to_max_output_size, Bool, false)
227- .OP_END_FACTORY_REG(NonMaxSuppressionV4)227+ .OP_END_FACTORY_REG(NonMaxSuppressionV4)
228-} // namespace ge228+ 
229- 229+/**
230+*@brief Normalizes data. It is called Region on YOLO v2 and Yolo on YOLO v3 . \n
231+ 
232+*@par Inputs:
233+*x: An NCHW tensor of type float16 or float32. The data is with shape (N,
234+* boxes*(coords+obj+classes), H, W) . \n
235+ 
236+*@par Attributes:
237+*@li boxes: An optional int32, specifying the number of anchor boxes. Defaults to "3".
238+*@li coords: An int32, specifying the number of parameters required for locating an object. Defaults to "4".
239+*@li classes: An int32, specifying the number of prediction classes. Defaults to "80".
240+*@li yolo_version: A string, specifying the YOLO version, either "V2" or "V3". Defaults to "V3"
241+*@li softmax: A bool, specifying whether to perform softmax. Defaults to "false".
242+*@li background: A bool. Defaults to "false".
243+*@li softmaxtree: A bool. Defaults to "false" . \n
244+ 
245+*@par Outputs:
246+*@li coord_data: Specifies the coordinates of a detected box.
247+*@li obj_prob: Specifies the confidence.
248+*@li classes_prob: Specifies the prediction classes . \n
249+*/
250+#ifndef OPS_PROTO_DEF_YOLO
251+#define OPS_PROTO_DEF_YOLO
252+REG_OP(Yolo)
253+ .INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT}))
254+ .OUTPUT(coord_data, TensorType({DT_FLOAT16, DT_FLOAT}))
255+ .OUTPUT(obj_prob, TensorType({DT_FLOAT16, DT_FLOAT}))
256+ .OUTPUT(classes_prob, TensorType({DT_FLOAT16, DT_FLOAT}))
257+ .ATTR(boxes, Int, 3)
258+ .ATTR(coords, Int, 4)
259+ .ATTR(classes, Int, 80)
260+ .ATTR(yolo_version, String, "V3")
261+ .ATTR(softmax, Bool, false)
262+ .ATTR(background, Bool, false)
263+ .ATTR(softmaxtree, Bool, false)
264+ .OP_END_FACTORY_REG(Yolo)
265+#endif
266+ 
267+/**
268+*@brief Normalizes data. It is called Region on YOLO v2 and Yolo on YOLO v3 . \n
269+ 
270+*@par Inputs:
271+*x: An NCHW tensor of type float16 or float32 . \n
272+ 
273+*@par Attributes:
274+*@li boxes: An optional int32, specifying the number of anchor boxes. Defaults to "3".
275+*@li coords: An int32, specifying the number of parameters required for locating an object. Defaults to "4".
276+*@li classes: An int32, specifying the number of prediction classes. Defaults to "80".
277+*@li yolo_version: A string, specifying the YOLO version. Defaults to "V5"
278+*@li softmax: A bool, specifying whether to perform softmax. Defaults to "false".
279+*@li background: A bool. Defaults to "false".
280+*@li softmaxtree: A bool. Defaults to "false" . \n
281+ 
282+*@par Outputs:
283+*@li coord_data: Specifies the coordinates of a detected box.
284+*@li obj_prob: Specifies the confidence.
285+*@li classes_prob: Specifies the prediction classes . \n
286+*/
287+#ifndef OPS_PROTO_DEF_YOLOPREDETECTION
288+#define OPS_PROTO_DEF_YOLOPREDETECTION
289+REG_OP(YoloPreDetection)
290+ .INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT}))
291+ .OUTPUT(coord_data, TensorType({DT_FLOAT16, DT_FLOAT}))
292+ .OUTPUT(obj_prob, TensorType({DT_FLOAT16, DT_FLOAT}))
293+ .OUTPUT(classes_prob, TensorType({DT_FLOAT16, DT_FLOAT}))
294+ .ATTR(boxes, Int, 3)
295+ .ATTR(coords, Int, 4)
296+ .ATTR(classes, Int, 80)
297+ .ATTR(yolo_version, String, "V5")
298+ .ATTR(softmax, Bool, false)
299+ .ATTR(background, Bool, false)
300+ .ATTR(softmaxtree, Bool, false)
301+ .OP_END_FACTORY_REG(YoloPreDetection)
302+#endif
303+ 
304+/**
305+*@brief Performs YOLO V5 detection . \n
306+ 
307+*@par Inputs:
308+*@li x: Dynamic inputs, the outputs of operator Yolo at the preceding layer.
309+*@li img_info: A float16 or float32, describing the image information . \n
310+ 
311+*@par Attributes:
312+*@li biases: A required float. "biases = Number of Yolo operators at the preceding layer x 2 x boxes"
313+*@li boxes: A required int32, specifying the number of anchor boxes predicted for each Yolo layer.
314+*@li coords: Specifies the number of coordinate parameters. Must be 4.
315+*@li classes: A required int32, specifying the number of classes to be predicted.
316+*@li relative: An optional bool. Defaults to and must be "true".
317+*@li obj_threshold: A required float, specifying the confidence threshold for box filtering.
318+*@li post_nms_topn: An optional int32. This attribute is reserved.
319+*@li score_threshold: A required float, specifying the class score threshold for box filtering.
320+*@li iou_threshold: A required float, specifying the intersection-over-union (IOU) threshold for box filtering.\n
321+*@li pre_nms_topn: An optional int, specifying the number of boxes for non-maximum suppression (NMS). Defaults to "512".
322+*@li N: An optional int. Defaults to "10".
323+*@li resize_origin_img_to_net: An optional bool. Defaults to "false".
324+*@li out_box_dim: An optional int. Defaults to "3".
325+*@li alpha: An optional float. Defaults to "2.0".
326+ 
327+*@par Outputs:
328+*@li box_out: A tensor of type float16 or float32, describing the information of each output box.
329+*@li box_out_num: A tensor of type int32, specifying the number of output boxes . \n
330+*/
331+#ifndef OPS_PROTO_DEF_YOLOV5DETECTIONOUTPUT
332+#define OPS_PROTO_DEF_YOLOV5DETECTIONOUTPUT
333+REG_OP(YoloV5DetectionOutput)
334+ .DYNAMIC_INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT}))
335+ .REQUIRED_ATTR(biases, ListFloat)
336+ .ATTR(boxes, Int, 3)
337+ .ATTR(coords, Int, 4)
338+ .ATTR(classes, Int, 80)
339+ .ATTR(relative, Bool, true)
340+ .ATTR(obj_threshold, Float, 0.5)
341+ .ATTR(post_nms_topn, Int, 512)
342+ .ATTR(score_threshold, Float, 0.5)
343+ .ATTR(iou_threshold, Float, 0.45f)
344+ .ATTR(pre_nms_topn, Int, 512)
345+ .ATTR(N, Int, 10)
346+ .ATTR(resize_origin_img_to_net, Bool, false)
347+ .ATTR(out_box_dim, Int, 3)
348+ .ATTR(alpha, Float, 2.0)
349+ .OUTPUT(box_out, TensorType({DT_FLOAT16, DT_FLOAT}))
350+ .OUTPUT(box_out_num, TensorType({DT_INT32}))
351+ .OP_END_FACTORY_REG(YoloV5DetectionOutput)
352+#endif
353+ 
354+/**
355+*@brief Performs YOLO V3 detection output V2 . \n
356+ 
357+*@par Inputs:
358+*@li x: Dynamic inputs, the outputs of operator Yolo at the preceding layer . \n
359+ 
360+*@par Attributes:
361+*@li biases: A float list. "biases = Number of Yolo operators at the preceding layer x 2 x boxes"
362+*@li boxes: A required int, specifying the number of anchor boxes predicted for each Yolo layer.
363+*@li coords: Specifies the number of coordinate parameters. Must be 4.
364+*@li classes: A required int, specifying the number of classes to be predicted.
365+*@li relative: An optional bool. Defaults to and must be "true".
366+*@li obj_threshold: A required float, specifying the confidence threshold for box filtering.
367+*@li post_nms_topn: An optional int. This attribute is reserved.
368+*@li score_threshold: A required float, specifying the class score threshold for box filtering.
369+*@li iou_threshold: A required float, specifying the intersection-over-union (IOU) threshold for box filtering.
370+*@li pre_nms_topn: An optional int, specifying the number of boxes for non-maximum suppression (NMS). Defaults to "512".
371+*@li N: An optional int. Defaults to "10".
372+*@li resize_origin_img_to_net: An optional bool. Defaults to "false".
373+*@li out_box_dim: An optional int. Defaults to "3".
374+ 
375+*@par Outputs:
376+*@li box_out: A tensor of type float16 or float32, describing the information of each output box.
377+*@li box_out_num: A tensor of type int32, specifying the number of output boxes . \n
378+*/
379+#ifndef OPS_PROTO_DEF_YOLOV3DETECTIONOUTPUTV2
380+#define OPS_PROTO_DEF_YOLOV3DETECTIONOUTPUTV2
381+REG_OP(YoloV3DetectionOutputV2)
382+ .DYNAMIC_INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT}))
383+ .REQUIRED_ATTR(biases, ListFloat)
384+ .ATTR(boxes, Int, 3)
385+ .ATTR(coords, Int, 4)
386+ .ATTR(classes, Int, 80)
387+ .ATTR(relative, Bool, true)
388+ .ATTR(obj_threshold, Float, 0.5)
389+ .ATTR(post_nms_topn, Int, 512)
390+ .ATTR(score_threshold, Float, 0.5)
391+ .ATTR(iou_threshold, Float, 0.45f)
392+ .ATTR(pre_nms_topn, Int, 512)
393+ .ATTR(N, Int, 10)
394+ .ATTR(resize_origin_img_to_net, Bool, false)
395+ .ATTR(out_box_dim, Int, 3)
396+ .OUTPUT(box_out, TensorType({DT_FLOAT16, DT_FLOAT}))
397+ .OUTPUT(box_out_num, TensorType({DT_INT32}))
398+ .OP_END_FACTORY_REG(YoloV3DetectionOutputV2)
399+#endif
400+ 
401+/**
402+*@brief Generates bounding boxes based on "anchor_boxes" and "gt_bboxes" . \n
403+ 
404+*@par Inputs:
405+*@li anchor_boxes: anchor sample boxes of origin image
406+*@li gt_bboxes: ground truth boxes
407+*@li stride: stride . \n
408+ 
409+*@par Attributes:
410+*performance_mode: select performance mode, "high_precision" or "high_performance".
411+ 
412+*@par Outputs:
413+*encoded_bboxes: Bboxes generated based on "anchor_boxes" and "gt_bboxes". Have the
414+* same format and type as "anchor_boxes".
415+*/
416+#ifndef OPS_PROTO_DEF_YOLOBOXESENCODE
417+#define OPS_PROTO_DEF_YOLOBOXESENCODE
418+REG_OP(YoloBoxesEncode)
419+ .INPUT(anchor_boxes, TensorType({DT_FLOAT16, DT_FLOAT}))
420+ .INPUT(gt_bboxes, TensorType({DT_FLOAT16, DT_FLOAT}))
421+ .INPUT(stride, TensorType({DT_INT32}))
422+ .ATTR(performance_mode, String, "high_precision")
423+ .OUTPUT(encoded_bboxes, TensorType({DT_FLOAT16, DT_FLOAT}))
424+ .OP_END_FACTORY_REG(YoloBoxesEncode)
425+#endif
426+ 
427+/**
428+* @brief Generates bounding boxes based on "priors" and "bboxes".
429+* It is a customized yolox operator . \n
430+ 
431+* @par Inputs:
432+* Two inputs, including:
433+* @li priors: prior sample boxes of origin image
434+* A 2D Tensor of type float32 or float16 with shape (N, 4).
435+* @li bboxes_input: bboxes predicted by the model. A 2D Tensor of type float32 or float16 with shape (B, N, 4) . \n
436+ 
437+* @par Outputs:
438+* bboxes_output: Bboxes generated based on "priors" and "bboxes_input". Have the same format
439+* and type as "bboxes_input".
440+*/
441+#ifndef OPS_PROTO_DEF_YOLOXBOUNDINGBOXDECODE
442+#define OPS_PROTO_DEF_YOLOXBOUNDINGBOXDECODE
443+REG_OP(YoloxBoundingBoxDecode)
444+ .INPUT(priors, TensorType({DT_FLOAT16, DT_FLOAT}))
445+ .INPUT(bboxes, TensorType({DT_FLOAT16, DT_FLOAT}))
446+ .OUTPUT(decoded_bboxes, TensorType({DT_FLOAT16, DT_FLOAT}))
447+ .OP_END_FACTORY_REG(YoloxBoundingBoxDecode)
448+#endif
449+ 
450+/**
451+*@brief Converts ARGB channel . \n
452+ 
453+*@par Inputs:
454+*@li x: A Tensor. Must be one of the following types: float16.
455+ 
456+*@par Outputs:
457+*y: A Tensor. Must be one of the following types: int16. \n
458+*/
459+#ifndef OPS_PROTO_DEF_TRANSARGB
460+#define OPS_PROTO_DEF_TRANSARGB
461+REG_OP(TransArgb)
462+ .INPUT(x, "T1")
463+ .OUTPUT(y, "T2")
464+ .DATATYPE(T1, TensorType({DT_FLOAT16}))
465+ .DATATYPE(T2, TensorType({DT_INT16}))
466+ .OP_END_FACTORY_REG(TransArgb)
467+#endif
468+} // namespace ge
469+ 
230#endif470#endif
Acommon/src/framework/trans_argb_onnx_plugin.cpp+43-0
@@ -0,0 +1,43 @@
1+/**
2+ * Copyright (c) 2025 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 trans_argb_onnx_plugin.cpp
13+ * \brief
14+ */
15+ 
16+#include "onnx_common.h"
17+ 
18+namespace domi {
19+using NodeProto = ge::onnx::NodeProto;
20+ 
21+static Status ParseParamsTransArgb(const Message* op_src, ge::Operator& op_dest)
22+{
23+ const NodeProto* node = dynamic_cast<const NodeProto*>(op_src);
24+ if (node == nullptr) {
25+ OP_LOGE(GetOpName(op_dest).c_str(), "Dynamic cast op_src to NodeProto failed.");
26+ return FAILED;
27+ }
28+ 
29+ return SUCCESS;
30+}
31+ 
32+// register TransArgb op info to GE
33+REGISTER_CUSTOM_OP("TransArgb")
34+ .FrameworkType(ONNX)
35+ .OriginOpType({ge::AscendString("ai.onnx::8::TransArgb"), ge::AscendString("ai.onnx::9::TransArgb"),
36+ ge::AscendString("ai.onnx::10::TransArgb"), ge::AscendString("ai.onnx::11::TransArgb"),
37+ ge::AscendString("ai.onnx::12::TransArgb"), ge::AscendString("ai.onnx::13::TransArgb"),
38+ ge::AscendString("ai.onnx::14::TransArgb"), ge::AscendString("ai.onnx::15::TransArgb"),
39+ ge::AscendString("ai.onnx::16::TransArgb"), ge::AscendString("ai.onnx::17::TransArgb"),
40+ ge::AscendString("ai.onnx::18::TransArgb")})
41+ .ParseParamsFn(ParseParamsTransArgb)
42+ .ImplyType(ImplyType::TVM);
43+} // namespace domi
Acommon/src/framework/yolo_boxes_encode_onnx_plugin.cpp+51-0
@@ -0,0 +1,51 @@
1+/**
2+ * Copyright (c) 2025 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 yolo_boxes_encode_onnx_plugin.cpp
13+ * \brief
14+ */
15+ 
16+#include "onnx_common.h"
17+ 
18+namespace domi {
19+using NodeProto = ge::onnx::NodeProto;
20+ 
21+static Status ParseParamsYoloBoxesEncode(const Message* op_src, ge::Operator& op_dest)
22+{
23+ const NodeProto* node = dynamic_cast<const NodeProto*>(op_src);
24+ if (node == nullptr) {
25+ OP_LOGE(GetOpName(op_dest).c_str(), "Dynamic cast op_src to NodeProto failed.");
26+ return FAILED;
27+ }
28+ 
29+ std::string performance_mode = "high_precision";
30+ for (const auto& attr : node->attribute()) {
31+ if (attr.name() == "performance_mode" && attr.type() == ge::onnx::AttributeProto::STRING) {
32+ performance_mode = attr.s();
33+ }
34+ }
35+ 
36+ op_dest.SetAttr("performance_mode", performance_mode);
37+ return SUCCESS;
38+}
39+ 
40+// register YoloBoxesEncode op info to GE
41+REGISTER_CUSTOM_OP("YoloBoxesEncode")
42+ .FrameworkType(ONNX)
43+ .OriginOpType(
44+ {ge::AscendString("ai.onnx::11::NPUYoloBoxesEncode"), ge::AscendString("ai.onnx::12::NPUYoloBoxesEncode"),
45+ ge::AscendString("ai.onnx::13::NPUYoloBoxesEncode"), ge::AscendString("ai.onnx::14::NPUYoloBoxesEncode"),
46+ ge::AscendString("ai.onnx::15::NPUYoloBoxesEncode"), ge::AscendString("ai.onnx::16::NPUYoloBoxesEncode"),
47+ ge::AscendString("ai.onnx::17::NPUYoloBoxesEncode"), ge::AscendString("ai.onnx::18::NPUYoloBoxesEncode"),
48+ ge::AscendString("npu::1::NPUYoloBoxesEncode")})
49+ .ParseParamsFn(ParseParamsYoloBoxesEncode)
50+ .ImplyType(ImplyType::TVM);
51+} // namespace domi
Acommon/src/framework/yolo_onnx_plugin.cpp+69-0
@@ -0,0 +1,69 @@
1+/**
2+ * Copyright (c) 2025 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 yolo_onnx_plugin.cpp
13+ * \brief
14+ */
15+ 
16+#include "onnx_common.h"
17+ 
18+namespace domi {
19+using NodeProto = ge::onnx::NodeProto;
20+ 
21+static Status ParseParamsYolo(const Message* op_src, ge::Operator& op_dest)
22+{
23+ const NodeProto* node = dynamic_cast<const NodeProto*>(op_src);
24+ if (node == nullptr) {
25+ OP_LOGE(GetOpName(op_dest).c_str(), "Dynamic cast op_src to NodeProto failed.");
26+ return FAILED;
27+ }
28+ 
29+ int boxes = 3;
30+ int coords = 4;
31+ int classes = 80;
32+ std::string yolo_version = "V3";
33+ bool softmax = false;
34+ bool background = false;
35+ bool softmaxtree = false;
36+ for (const auto& attr : node->attribute()) {
37+ if (attr.name() == "boxes" && attr.type() == ge::onnx::AttributeProto::INT) {
38+ boxes = attr.i();
39+ } else if (attr.name() == "coords" && attr.type() == ge::onnx::AttributeProto::INT) {
40+ coords = attr.i();
41+ } else if (attr.name() == "classes" && attr.type() == ge::onnx::AttributeProto::INT) {
42+ classes = attr.i();
43+ } else if (attr.name() == "yolo_version" && attr.type() == ge::onnx::AttributeProto::STRING) {
44+ yolo_version = attr.s();
45+ }
46+ }
atomgit-bot
atomgit-botatomgit-bot7月14日

🟡 Medium Priority

yolo_onnx_plugin.cppParseParamsYolo 函数(第36-46行)仅解析了 boxescoordsclassesyolo_version 四个属性,但 op_cv_proto_extend.hYolo 算子的 proto 注册(第261-263行)还定义了 softmaxbackgroundsoftmaxtree 三个 bool 属性。ONNX 模型中若对这些属性设置了非默认值(如 softmax=true),将被静默忽略,导致算子行为与 ONNX 模型语义不一致。

对照同批新增的 yolo_predetection_onnx_plugin.cpp(第36-51行),其 ParseParamsYoloPreDetection 正确解析了全部 7 个属性,进一步表明 yolo_onnx_plugin.cpp 漏解析这三个属性是遗漏而非有意为之。

改动建议
46
+ for (const auto& attr : node->attribute()) {
47
+ if (attr.name() == "boxes" && attr.type() == ge::onnx::AttributeProto::INT) {
48
+ boxes = attr.i();
49
+ } else if (attr.name() == "coords" && attr.type() == ge::onnx::AttributeProto::INT) {
50
+ coords = attr.i();
51
+ } else if (attr.name() == "classes" && attr.type() == ge::onnx::AttributeProto::INT) {
52
+ classes = attr.i();
53
+ } else if (attr.name() == "yolo_version" && attr.type() == ge::onnx::AttributeProto::STRING) {
54
+ yolo_version = attr.s();
55
+ } else if (attr.name() == "softmax" && attr.type() == ge::onnx::AttributeProto::INT) {
56
+ softmax = (attr.i() == 1);
57
+ } else if (attr.name() == "background" && attr.type() == ge::onnx::AttributeProto::INT) {
58
+ background = (attr.i() == 1);
59
+ } else if (attr.name() == "softmaxtree" && attr.type() == ge::onnx::AttributeProto::INT) {
60
+ softmaxtree = (attr.i() == 1);
61
+ }
46
62
  }
应用建议
likedislike
47+ 
48+ op_dest.SetAttr("boxes", boxes);
49+ op_dest.SetAttr("coords", coords);
50+ op_dest.SetAttr("classes", classes);
51+ op_dest.SetAttr("yolo_version", yolo_version);
52+ op_dest.SetAttr("softmax", softmax);
53+ op_dest.SetAttr("background", background);
54+ op_dest.SetAttr("softmaxtree", softmaxtree);
55+ 
56+ return SUCCESS;
57+}
58+ 
59+// register Yolo op info to GE
60+REGISTER_CUSTOM_OP("Yolo")
61+ .FrameworkType(ONNX)
62+ .OriginOpType({ge::AscendString("ai.onnx::8::Yolo"), ge::AscendString("ai.onnx::9::Yolo"),
63+ ge::AscendString("ai.onnx::10::Yolo"), ge::AscendString("ai.onnx::11::Yolo"),
64+ ge::AscendString("ai.onnx::12::Yolo"), ge::AscendString("ai.onnx::13::Yolo"),
65+ ge::AscendString("ai.onnx::14::Yolo"), ge::AscendString("ai.onnx::15::Yolo"),
66+ ge::AscendString("ai.onnx::16::Yolo")})
67+ .ParseParamsFn(ParseParamsYolo)
68+ .ImplyType(ImplyType::TVM);
69+} // namespace domi
Acommon/src/framework/yolo_predetection_onnx_plugin.cpp+75-0
@@ -0,0 +1,75 @@
1+/**
2+ * Copyright (c) 2025 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 yolo_predetection_onnx_plugin.cpp
13+ * \brief
14+ */
15+ 
16+#include "onnx_common.h"
17+ 
18+namespace domi {
19+using NodeProto = ge::onnx::NodeProto;
20+ 
21+static Status ParseParamsYoloPreDetection(const Message* op_src, ge::Operator& op_dest)
22+{
23+ const NodeProto* node = dynamic_cast<const NodeProto*>(op_src);
24+ if (node == nullptr) {
25+ OP_LOGE(GetOpName(op_dest).c_str(), "Dynamic cast op_src to NodeProto failed.");
26+ return FAILED;
27+ }
28+ 
29+ int boxes = 3;
30+ int coords = 4;
31+ int classes = 80;
32+ std::string yolo_version = "V5";
33+ bool softmax = false;
34+ bool background = false;
35+ bool softmaxtree = false;
36+ for (const auto& attr : node->attribute()) {
37+ if (attr.name() == "boxes") {
38+ boxes = attr.i();
39+ } else if (attr.name() == "coords") {
40+ coords = attr.i();
41+ } else if (attr.name() == "classes") {
42+ classes = attr.i();
43+ } else if (attr.name() == "yolo_version") {
44+ yolo_version = attr.s();
45+ } else if (attr.name() == "softmax") {
46+ softmax = attr.i();
47+ } else if (attr.name() == "background") {
48+ background = attr.i();
49+ } else if (attr.name() == "softmaxtree") {
50+ softmaxtree = attr.i();
51+ }
52+ }
53+ 
54+ op_dest.SetAttr("boxes", boxes);
55+ op_dest.SetAttr("coords", coords);
56+ op_dest.SetAttr("classes", classes);
57+ op_dest.SetAttr("yolo_version", yolo_version);
58+ op_dest.SetAttr("softmax", softmax);
59+ op_dest.SetAttr("background", background);
60+ op_dest.SetAttr("softmaxtree", softmaxtree);
61+ 
62+ return SUCCESS;
63+}
64+ 
65+// register YoloPreDetection op info to GE
66+REGISTER_CUSTOM_OP("YoloPreDetection")
67+ .FrameworkType(ONNX)
68+ .OriginOpType({ge::AscendString("ai.onnx::8::YoloPreDetection"), ge::AscendString("ai.onnx::9::YoloPreDetection"),
69+ ge::AscendString("ai.onnx::10::YoloPreDetection"), ge::AscendString("ai.onnx::11::YoloPreDetection"),
70+ ge::AscendString("ai.onnx::12::YoloPreDetection"), ge::AscendString("ai.onnx::13::YoloPreDetection"),
71+ ge::AscendString("ai.onnx::14::YoloPreDetection"), ge::AscendString("ai.onnx::15::YoloPreDetection"),
72+ ge::AscendString("ai.onnx::16::YoloPreDetection")})
73+ .ParseParamsFn(ParseParamsYoloPreDetection)
74+ .ImplyType(ImplyType::TVM);
75+} // namespace domi
Acommon/src/framework/yolov3_detection_output_v2_onnx_plugin.cpp+108-0
@@ -0,0 +1,108 @@
1+/**
2+ * Copyright (c) 2025 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 yolov3_detection_output_v2_onnx_plugin.cpp
13+ * \brief
14+ */
15+ 
16+#include "onnx_common.h"
17+ 
18+namespace domi {
19+using NodeProto = ge::onnx::NodeProto;
20+ 
21+static Status ParseParamsYolov3detectionoutputv2(const Message* op_src, ge::Operator& op_dest)
22+{
23+ const NodeProto* node = dynamic_cast<const NodeProto*>(op_src);
24+ if (node == nullptr) {
25+ OP_LOGE(GetOpName(op_dest).c_str(), "Dynamic cast op_src to NodeProto failed.");
26+ return FAILED;
27+ }
28+ int n = node->input_size();
29+ op_dest.DynamicInputRegister("x", n);
30+ 
31+ int N = 10;
32+ int boxes = 3;
33+ int coords = 4;
34+ int classes = 80;
35+ int post_nms_topn = 512;
36+ int pre_nms_topn = 512;
37+ int out_box_dim = 3;
38+ float obj_threshold = 0.5;
39+ float score_threshold = 0.5;
40+ float iou_threshold = 0.45;
41+ bool relative = true;
42+ bool resize_origin_img_to_net = false;
43+ std::vector<float> v_biases = {};
44+ 
45+ for (const auto& attr : node->attribute()) {
46+ if (attr.name() == "boxes" && attr.type() == ge::onnx::AttributeProto::INT) {
47+ boxes = attr.i();
48+ } else if (attr.name() == "coords" && attr.type() == ge::onnx::AttributeProto::INT) {
49+ coords = attr.i();
50+ } else if (attr.name() == "classes" && attr.type() == ge::onnx::AttributeProto::INT) {
51+ classes = attr.i();
52+ } else if (attr.name() == "N" && attr.type() == ge::onnx::AttributeProto::INT) {
53+ N = attr.i();
54+ } else if (attr.name() == "post_nms_topn" && attr.type() == ge::onnx::AttributeProto::INT) {
55+ post_nms_topn = attr.i();
56+ } else if (attr.name() == "pre_nms_topn" && attr.type() == ge::onnx::AttributeProto::INT) {
57+ pre_nms_topn = attr.i();
58+ } else if (attr.name() == "out_box_dim" && attr.type() == ge::onnx::AttributeProto::INT) {
59+ out_box_dim = attr.i();
60+ } else if (attr.name() == "obj_threshold" && attr.type() == ge::onnx::AttributeProto::FLOAT) {
61+ obj_threshold = attr.f();
62+ } else if (attr.name() == "score_threshold" && attr.type() == ge::onnx::AttributeProto::FLOAT) {
63+ score_threshold = attr.f();
64+ } else if (attr.name() == "iou_threshold" && attr.type() == ge::onnx::AttributeProto::FLOAT) {
65+ iou_threshold = attr.f();
66+ } else if (attr.name() == "biases" && attr.type() == ge::onnx::AttributeProto::FLOATS) {
67+ for (auto biases_f : attr.floats()) {
68+ v_biases.push_back(biases_f);
69+ }
70+ }
71+ }
atomgit-bot
atomgit-botatomgit-bot7月14日

🟡 Medium Priority

yolov3_detection_output_v2_onnx_plugin.cppParseParamsYolov3detectionoutputv2 函数(第45-71行)的属性解析循环中缺少对 relativeresize_origin_img_to_net 两个 bool 属性的处理。proto 注册(op_cv_proto_extend.h 第387行和第394行)定义了这两个属性(默认值分别为 true 和 false),但插件始终使用本地硬编码的默认值,ONNX 模型中的实际值被静默忽略。

对照同批新增的 yolov5_detection_output_onnx_plugin.cpp(第71-74行),其 ParseParamsYoloV5DetectionOutput 正确解析了 relativeresize_origin_img_to_net,进一步表明此处为遗漏。

改动建议
71
+ for (const auto& attr : node->attribute()) {
72
+ if (attr.name() == "boxes" && attr.type() == ge::onnx::AttributeProto::INT) {
73
+ boxes = attr.i();
74
+ } else if (attr.name() == "coords" && attr.type() == ge::onnx::AttributeProto::INT) {
75
+ coords = attr.i();
76
+ } else if (attr.name() == "classes" && attr.type() == ge::onnx::AttributeProto::INT) {
77
+ classes = attr.i();
78
+ } else if (attr.name() == "N" && attr.type() == ge::onnx::AttributeProto::INT) {
79
+ N = attr.i();
80
+ } else if (attr.name() == "post_nms_topn" && attr.type() == ge::onnx::AttributeProto::INT) {
81
+ post_nms_topn = attr.i();
82
+ } else if (attr.name() == "pre_nms_topn" && attr.type() == ge::onnx::AttributeProto::INT) {
83
+ pre_nms_topn = attr.i();
84
+ } else if (attr.name() == "out_box_dim" && attr.type() == ge::onnx::AttributeProto::INT) {
85
+ out_box_dim = attr.i();
86
+ } else if (attr.name() == "obj_threshold" && attr.type() == ge::onnx::AttributeProto::FLOAT) {
87
+ obj_threshold = attr.f();
88
+ } else if (attr.name() == "score_threshold" && attr.type() == ge::onnx::AttributeProto::FLOAT) {
89
+ score_threshold = attr.f();
90
+ } else if (attr.name() == "iou_threshold" && attr.type() == ge::onnx::AttributeProto::FLOAT) {
91
+ iou_threshold = attr.f();
92
+ } else if (attr.name() == "biases" && attr.type() == ge::onnx::AttributeProto::FLOATS) {
93
+ for (auto biases_f : attr.floats()) {
94
+ v_biases.push_back(biases_f);
95
+ }
96
+ } else if (attr.name() == "relative" && attr.type() == ge::onnx::AttributeProto::INT) {
97
+ relative = (attr.i() == 1);
98
+ } else if (attr.name() == "resize_origin_img_to_net" && attr.type() == ge::onnx::AttributeProto::INT) {
99
+ resize_origin_img_to_net = (attr.i() == 1);
100
+ }
71
101
  }
应用建议
likedislike
72+ 
73+ if (v_biases.empty()) {
74+ OP_LOGE(GetOpName(op_dest).c_str(), "The attr of biases is required.");
75+ return FAILED;
76+ }
77+ 
78+ op_dest.SetAttr("N", N);
79+ op_dest.SetAttr("biases", v_biases);
80+ op_dest.SetAttr("boxes", boxes);
81+ op_dest.SetAttr("coords", coords);
82+ op_dest.SetAttr("classes", classes);
83+ op_dest.SetAttr("relative", relative);
84+ op_dest.SetAttr("post_nms_topn", post_nms_topn);
85+ op_dest.SetAttr("pre_nms_topn", pre_nms_topn);
86+ op_dest.SetAttr("out_box_dim", out_box_dim);
87+ op_dest.SetAttr("obj_threshold", obj_threshold);
88+ op_dest.SetAttr("score_threshold", score_threshold);
89+ op_dest.SetAttr("iou_threshold", iou_threshold);
90+ op_dest.SetAttr("resize_origin_img_to_net", resize_origin_img_to_net);
91+ return SUCCESS;
92+}
93+ 
94+// register YoloV3DetectionOutputV2 op info to GE
95+REGISTER_CUSTOM_OP("YoloV3DetectionOutputV2")
96+ .FrameworkType(ONNX)
97+ .OriginOpType({ge::AscendString("ai.onnx::8::YoloV3DetectionOutputV2"),
98+ ge::AscendString("ai.onnx::9::YoloV3DetectionOutputV2"),
99+ ge::AscendString("ai.onnx::10::YoloV3DetectionOutputV2"),
100+ ge::AscendString("ai.onnx::11::YoloV3DetectionOutputV2"),
101+ ge::AscendString("ai.onnx::12::YoloV3DetectionOutputV2"),
102+ ge::AscendString("ai.onnx::13::YoloV3DetectionOutputV2"),
103+ ge::AscendString("ai.onnx::14::YoloV3DetectionOutputV2"),
104+ ge::AscendString("ai.onnx::15::YoloV3DetectionOutputV2"),
105+ ge::AscendString("ai.onnx::16::YoloV3DetectionOutputV2")})
106+ .ParseParamsFn(ParseParamsYolov3detectionoutputv2)
107+ .ImplyType(ImplyType::TVM);
108+} // namespace domi
Acommon/src/framework/yolov5_detection_output_onnx_plugin.cpp+114-0
@@ -0,0 +1,114 @@
1+/**
2+ * Copyright (c) 2025 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 yolov5_detection_output_onnx_plugin.cpp
13+ * \brief
14+ */
15+ 
16+#include "onnx_common.h"
17+ 
18+namespace domi {
19+using NodeProto = ge::onnx::NodeProto;
20+ 
21+static Status ParseParamsYoloV5DetectionOutput(const Message* op_src, ge::Operator& op_dest)
22+{
23+ const NodeProto* node = dynamic_cast<const NodeProto*>(op_src);
24+ if (node == nullptr) {
25+ OP_LOGE(GetOpName(op_dest).c_str(), "Dynamic cast op_src to NodeProto failed.");
26+ return FAILED;
27+ }
28+ int n = node->input_size();
29+ op_dest.DynamicInputRegister("x", n);
30+ 
31+ int N = 10;
32+ int boxes = 3;
33+ int coords = 4;
34+ int classes = 80;
35+ int post_nms_topn = 512;
36+ int pre_nms_topn = 512;
37+ int out_box_dim = 3;
38+ float obj_threshold = 0.5;
39+ float score_threshold = 0.5;
40+ float iou_threshold = 0.45;
41+ float alpha = 2.0;
42+ bool relative = true;
43+ bool resize_origin_img_to_net = false;
44+ std::vector<float> v_biases = {};
45+ 
46+ for (const auto& attr : node->attribute()) {
47+ if (attr.name() == "boxes") {
48+ boxes = attr.i();
49+ } else if (attr.name() == "coords") {
50+ coords = attr.i();
51+ } else if (attr.name() == "classes") {
52+ classes = attr.i();
53+ } else if (attr.name() == "N") {
54+ N = attr.i();
55+ } else if (attr.name() == "post_nms_topn") {
56+ post_nms_topn = attr.i();
57+ } else if (attr.name() == "pre_nms_topn") {
58+ pre_nms_topn = attr.i();
59+ } else if (attr.name() == "out_box_dim") {
60+ out_box_dim = attr.i();
61+ } else if (attr.name() == "obj_threshold") {
62+ obj_threshold = attr.f();
63+ } else if (attr.name() == "score_threshold") {
64+ score_threshold = attr.f();
65+ } else if (attr.name() == "iou_threshold") {
66+ iou_threshold = attr.f();
67+ } else if (attr.name() == "biases") {
68+ for (auto biases_f : attr.floats()) {
69+ v_biases.push_back(biases_f);
70+ }
71+ } else if (attr.name() == "relative") {
72+ relative = attr.i();
73+ } else if (attr.name() == "resize_origin_img_to_net") {
74+ resize_origin_img_to_net = attr.i();
75+ } else if (attr.name() == "alpha") {
76+ alpha = attr.f();
77+ }
78+ }
atomgit-bot
atomgit-botatomgit-bot7月14日

🟡 Medium Priority

文件 yolov5_detection_output_onnx_plugin.cpp 中的属性解析循环(第46-78行)在读取所有 14 个属性时均缺少类型检查(即 attr.type() == ge::onnx::AttributeProto::XXX 守卫)。

这与同一代码库中现有的插件不一致:yolo_onnx_plugin.cpp(第37行)和 yolov3_detection_output_v2_onnx_plugin.cpp(第46行)对所有属性读取都进行了类型检查。yolov5_detection_output_onnx_plugin.cpp 中受影响的属性包括:

后果:如果 ONNX 模型包含名称匹配但类型错误的属性(例如,将 "boxes" 作为 FLOAT 而非 INT 传递),protobuf 的 attr.i() 返回 0(即非整数类型的默认值),attr.f() 返回 0.0f。这会导致算子使用错误的值静默运行,输出结果不正确,且无任何错误或警告。对于 relative/resize_origin_img_to_net,这些是 bool 变量,但通过 attr.i()(返回 int64)读取并隐式转换为 bool,如果模型传递了非预期的属性类型,会产生错误结果。

likedislike
79+ 
80+ if (v_biases.empty()) {
81+ OP_LOGE(GetOpName(op_dest).c_str(), "The attr of biases is required.");
82+ return FAILED;
83+ }
84+ 
85+ op_dest.SetAttr("N", N);
86+ op_dest.SetAttr("biases", v_biases);
87+ op_dest.SetAttr("boxes", boxes);
88+ op_dest.SetAttr("coords", coords);
89+ op_dest.SetAttr("classes", classes);
90+ op_dest.SetAttr("relative", relative);
91+ op_dest.SetAttr("post_nms_topn", post_nms_topn);
92+ op_dest.SetAttr("pre_nms_topn", pre_nms_topn);
93+ op_dest.SetAttr("out_box_dim", out_box_dim);
94+ op_dest.SetAttr("obj_threshold", obj_threshold);
95+ op_dest.SetAttr("score_threshold", score_threshold);
96+ op_dest.SetAttr("iou_threshold", iou_threshold);
97+ op_dest.SetAttr("resize_origin_img_to_net", resize_origin_img_to_net);
98+ op_dest.SetAttr("alpha", alpha);
99+ 
100+ return SUCCESS;
101+}
102+ 
103+// register YoloV5DetectionOutput op info to GE
104+REGISTER_CUSTOM_OP("YoloV5DetectionOutput")
105+ .FrameworkType(ONNX)
106+ .OriginOpType(
107+ {ge::AscendString("ai.onnx::8::YoloV5DetectionOutput"), ge::AscendString("ai.onnx::9::YoloV5DetectionOutput"),
108+ ge::AscendString("ai.onnx::10::YoloV5DetectionOutput"), ge::AscendString("ai.onnx::11::YoloV5DetectionOutput"),
109+ ge::AscendString("ai.onnx::12::YoloV5DetectionOutput"), ge::AscendString("ai.onnx::13::YoloV5DetectionOutput"),
110+ ge::AscendString("ai.onnx::14::YoloV5DetectionOutput"), ge::AscendString("ai.onnx::15::YoloV5DetectionOutput"),
111+ ge::AscendString("ai.onnx::16::YoloV5DetectionOutput")})
112+ .ParseParamsFn(ParseParamsYoloV5DetectionOutput)
113+ .ImplyType(ImplyType::TVM);
114+} // namespace domi
Acommon/src/framework/yolox_bounding_box_decode_onnx_plugin.cpp+35-0
@@ -0,0 +1,35 @@
1+/**
2+ * Copyright (c) 2025 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 yolox_bounding_box_decode_onnx_plugin.cpp
13+ * \brief
14+ */
15+ 
16+#include "onnx_common.h"
17+ 
18+namespace domi {
19+static Status ParseParamsYoloxBoundingBoxDecode(const Message* op_src, ge::Operator& op_dest) { return SUCCESS; }
atomgit-bot
atomgit-botatomgit-bot7月14日

🟡 Medium Priority

ParseParamsYoloxBoundingBoxDecode 函数(第19行)直接返回 SUCCESS,未通过 dynamic_cast<const NodeProto*>(op_src) 验证 op_src 参数,也未进行空指针检查。这与代码库中所有其他 ONNX 插件不一致,包括那些无属性需要解析的插件。例如,trans_argb_onnx_plugin.cpp(第21-27行)虽然没有任何属性需要提取,但仍然执行了 dynamic_cast 和空指针检查。affine_grid_onnx_plugin.cpp 也遵循此模式。

后果:如果 GE 框架向 ParseParamsFn 回调传递了损坏的或非 NodeProto 消息,该函数会静默返回 SUCCESS,而其他所有插件都会捕获此错误并记录日志。如果该算子后续增加了属性,这种缺失的验证将成为一个潜在缺陷——未来的维护者可能不会意识到需要添加此检查,因为函数签名已经接受了 op_src,而其内容却从未被验证。

建议:在 ParseParamsYoloxBoundingBoxDecode 内添加 dynamic_cast 和空指针检查,与所有其他插件保持一致。具体为:将函数体替换为与 ParseParamsTransArgb 等效的三行代码:对 op_src 执行 dynamic_cast<const NodeProto*>(op_src)、空指针检查并记录日志、最后返回 SUCCESS

likedislike
20+ 
21+// register YoloxBoundingBoxDecode op info to GE
22+REGISTER_CUSTOM_OP("YoloxBoundingBoxDecode")
23+ .FrameworkType(ONNX)
24+ .OriginOpType({ge::AscendString("ai.onnx::8::YoloxBoundingBoxDecode"),
25+ ge::AscendString("ai.onnx::9::YoloxBoundingBoxDecode"),
26+ ge::AscendString("ai.onnx::10::YoloxBoundingBoxDecode"),
27+ ge::AscendString("ai.onnx::11::YoloxBoundingBoxDecode"),
28+ ge::AscendString("ai.onnx::12::YoloxBoundingBoxDecode"),
29+ ge::AscendString("ai.onnx::13::YoloxBoundingBoxDecode"),
30+ ge::AscendString("ai.onnx::14::YoloxBoundingBoxDecode"),
31+ ge::AscendString("ai.onnx::15::YoloxBoundingBoxDecode"),
32+ ge::AscendString("ai.onnx::16::YoloxBoundingBoxDecode")})
33+ .ParseParamsFn(ParseParamsYoloxBoundingBoxDecode)
34+ .ImplyType(ImplyType::TVM);
35+} // namespace domi