From b94e13c8aefedfd9c0ed73da278b7df4c30c0e24 Mon Sep 17 00:00:00 2001 From: Yuantao Feng Date: Tue, 14 Mar 2023 02:46:33 +0800 Subject: [PATCH] Merge pull request #23319 from fengyuentau:fix_zoo_issue_136 Related issue: https://github.com/opencv/opencv_zoo/issues/136 Features added: - Support operators with multiple output: ONNX Split. - Support Slice without steps. Bugs fixed: - Wrong settings in ClipByValue (Relu6). - Wrong calculation of pads in convolution layer (It is wrong generally but only fixed specifically for CANN for now). ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- modules/dnn/include/opencv2/dnn/dnn.hpp | 8 +- modules/dnn/src/layer.cpp | 3 +- modules/dnn/src/layers/batch_norm_layer.cpp | 16 +-- modules/dnn/src/layers/blank_layer.cpp | 8 +- modules/dnn/src/layers/concat_layer.cpp | 8 +- modules/dnn/src/layers/const_layer.cpp | 6 +- modules/dnn/src/layers/convolution_layer.cpp | 34 +++-- modules/dnn/src/layers/elementwise_layers.cpp | 136 ++++++++++-------- modules/dnn/src/layers/eltwise_layer.cpp | 33 ++--- modules/dnn/src/layers/flatten_layer.cpp | 8 +- .../dnn/src/layers/fully_connected_layer.cpp | 12 +- modules/dnn/src/layers/lrn_layer.cpp | 8 +- .../dnn/src/layers/nary_eltwise_layers.cpp | 33 ++--- modules/dnn/src/layers/padding_layer.cpp | 12 +- modules/dnn/src/layers/permute_layer.cpp | 8 +- modules/dnn/src/layers/pooling_layer.cpp | 14 +- modules/dnn/src/layers/reshape_layer.cpp | 10 +- modules/dnn/src/layers/resize_layer.cpp | 23 ++- modules/dnn/src/layers/slice_layer.cpp | 85 +++++++++-- modules/dnn/src/layers/softmax_layer.cpp | 8 +- modules/dnn/src/net_cann.cpp | 43 ++++-- modules/dnn/src/op_cann.cpp | 2 +- modules/dnn/src/op_cann.hpp | 1 + 23 files changed, 317 insertions(+), 202 deletions(-) diff --git a/modules/dnn/include/opencv2/dnn/dnn.hpp b/modules/dnn/include/opencv2/dnn/dnn.hpp index 11ad69b8d9..dca20adb27 100644 --- a/modules/dnn/include/opencv2/dnn/dnn.hpp +++ b/modules/dnn/include/opencv2/dnn/dnn.hpp @@ -347,11 +347,11 @@ CV__DNN_INLINE_NS_BEGIN /** * @brief Returns a CANN backend node * - * @param inputsWrapper layer inputs - * @param index layer id for op name - * @param nodes inputs of this node + * @param inputsWrapper input tensors of this CANN operator + * @param nodes nodes of input tensors */ - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes); + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes); /** * @brief Automatic Halide scheduling based on layer hyper-parameters. diff --git a/modules/dnn/src/layer.cpp b/modules/dnn/src/layer.cpp index 5305a5221d..730fae4cb8 100644 --- a/modules/dnn/src/layer.cpp +++ b/modules/dnn/src/layer.cpp @@ -84,7 +84,8 @@ Ptr Layer::initTimVX(void* timVxInfo, return Ptr(); } -Ptr Layer::initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) +Ptr Layer::initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) { CV_Error(Error::StsNotImplemented, "CANN pipeline of " + type + " layers is not defined."); return Ptr(); diff --git a/modules/dnn/src/layers/batch_norm_layer.cpp b/modules/dnn/src/layers/batch_norm_layer.cpp index e112ba0746..40d8054251 100644 --- a/modules/dnn/src/layers/batch_norm_layer.cpp +++ b/modules/dnn/src/layers/batch_norm_layer.cpp @@ -392,7 +392,8 @@ public: #endif // HAVE_HALIDE #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { CV_Assert(nodes.size() == 1); CV_Assert(blobs.size() == 4); // must have scale, offset, mean and variance @@ -401,8 +402,7 @@ public: auto channel = x->host->size[1]; // create operator - std::string op_name = cv::format("bn_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes op->set_attr_epsilon(epsilon); @@ -412,24 +412,24 @@ public: // set inputs // set inputs : x auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); // set inputs : scale (blobs[2]) std::vector shape_{channel}; - auto op_const_scale = std::make_shared(blobs[2].data, blobs[2].type(), shape_, cv::format("%s_scale", op_name.c_str())); + auto op_const_scale = std::make_shared(blobs[2].data, blobs[2].type(), shape_, cv::format("%s_scale", name.c_str())); op->set_input_scale(*(op_const_scale->getOp())); op->update_input_desc_scale(*(op_const_scale->getTensorDesc())); // set inputs : offset (blobs[3]) - auto op_const_offset = std::make_shared(blobs[3].data, blobs[3].type(), shape_, cv::format("%s_offset", op_name.c_str())); + auto op_const_offset = std::make_shared(blobs[3].data, blobs[3].type(), shape_, cv::format("%s_offset", name.c_str())); op->set_input_offset(*(op_const_offset->getOp())); op->update_input_desc_offset(*(op_const_offset->getTensorDesc())); // set inputs : mean (blobs[0]) - auto op_const_mean = std::make_shared(blobs[0].data, blobs[0].type(), shape_, cv::format("%s_mean", op_name.c_str())); + auto op_const_mean = std::make_shared(blobs[0].data, blobs[0].type(), shape_, cv::format("%s_mean", name.c_str())); op->set_input_mean(*(op_const_mean->getOp())); op->update_input_desc_mean(*(op_const_mean->getTensorDesc())); // set inputs : variance (blobs[1]) - auto op_const_var = std::make_shared(blobs[1].data, blobs[1].type(), shape_, cv::format("%s_var", op_name.c_str())); + auto op_const_var = std::make_shared(blobs[1].data, blobs[1].type(), shape_, cv::format("%s_var", name.c_str())); op->set_input_variance(*(op_const_var->getOp())); op->update_input_desc_variance(*(op_const_var->getTensorDesc())); diff --git a/modules/dnn/src/layers/blank_layer.cpp b/modules/dnn/src/layers/blank_layer.cpp index 972aa7c9c8..0aa65f62a3 100644 --- a/modules/dnn/src/layers/blank_layer.cpp +++ b/modules/dnn/src/layers/blank_layer.cpp @@ -121,7 +121,8 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { auto x = inputsWrapper[0].dynamicCast(); auto x_desc = x->getTensorDesc(); @@ -129,11 +130,10 @@ public: auto output_desc = std::make_shared(ge::Shape(), ge::FORMAT_NCHW, ge::DT_FLOAT); // create operator - std::string op_name = cv::format("identity_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set inputs - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); op->update_input_desc_x(*x_desc); // set output diff --git a/modules/dnn/src/layers/concat_layer.cpp b/modules/dnn/src/layers/concat_layer.cpp index 52330a8e42..44ccfc02e8 100644 --- a/modules/dnn/src/layers/concat_layer.cpp +++ b/modules/dnn/src/layers/concat_layer.cpp @@ -367,13 +367,13 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { CV_Assert(inputsWrapper.size() == nodes.size()); // create operator - std::string op_name = cv::format("concat_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes int N = inputsWrapper.size(); @@ -387,7 +387,7 @@ public: auto x_i = inputsWrapper[i].dynamicCast(); auto x_i_desc = x_i->getTensorDesc(); auto op_x_i = nodes[i].dynamicCast()->getOp(); - op->set_dynamic_input_x(i, *op_x_i, "y"); + op->set_dynamic_input_x(i, *op_x_i, x_i->name.c_str()); op->update_dynamic_input_desc_x(i, *x_i_desc); } diff --git a/modules/dnn/src/layers/const_layer.cpp b/modules/dnn/src/layers/const_layer.cpp index 2141ad987a..58cccbd552 100644 --- a/modules/dnn/src/layers/const_layer.cpp +++ b/modules/dnn/src/layers/const_layer.cpp @@ -84,7 +84,8 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { auto mat_shape = shape(blobs[0]); std::vector mat_shape_{mat_shape.begin(), mat_shape.end()}; @@ -110,8 +111,7 @@ public: ge_tensor->SetTensorDesc(*desc); ge_tensor->SetData(blobs[0].data, ge_shape.GetShapeSize() * size_of_type); - std::string op_name = cv::format("const_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); op->set_attr_value(*ge_tensor); return Ptr(new CannBackendNode(op)); diff --git a/modules/dnn/src/layers/convolution_layer.cpp b/modules/dnn/src/layers/convolution_layer.cpp index 3e62887bd7..0dcff60072 100644 --- a/modules/dnn/src/layers/convolution_layer.cpp +++ b/modules/dnn/src/layers/convolution_layer.cpp @@ -782,7 +782,8 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { CV_Assert(!blobs.empty()); CV_Assert(inputsWrapper.size() == 1); @@ -791,18 +792,35 @@ public: bool has_bias = hasBias() || fusedBias; auto x = inputsWrapper[0].dynamicCast(); - const int x_in_channel = x->host->size[1]; + const auto shape_x = x->host->size; // [b, c, h, w] const int filter_out_channel = blobs[0].size[1]; - const int groups = x_in_channel / filter_out_channel; + const int groups = shape_x[1] / filter_out_channel; // create operator - std::string op_name = cv::format("conv2d_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes op->set_attr_strides(ge::Operator::OpListInt( {1, 1, (int64_t)strides[0], (int64_t)strides[1]} )); + // recalculate pads in case of "SAME" padMode with odd pads + // since in 'getConvPoolPaddings' pads are divided equally + // leading to the loss of one pad + if (padMode == "SAME") + { + for (int i = 0; i < pads_begin.size(); i++) { + if (strides[i] <= kernel_size[i]) + { + int pads_at_i = kernel_size[i] - 1 - (shape_x[i+2] - 1 + strides[i]) % strides[i]; + pads_begin[i] = pads_at_i / 2; + // if odd, add extra padding to the end for SAME_UPPER + // or to the beginning for SAME_LOWER. Since here we cannot + // identity SAME_UPPER and SAME_LOWER, extra padding is always + // added to the end. + pads_end[i] = pads_at_i - pads_begin[i]; + } + } + } op->set_attr_pads(ge::Operator::OpListInt( {(int64_t)pads_begin[1], (int64_t)pads_end[1], (int64_t)pads_begin[0], (int64_t)pads_end[0]} )); @@ -815,12 +833,12 @@ public: // set inputs // set inputs : x auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); // set inputs : weight const Mat& w_mat = blobs[0]; - auto op_const_weight = std::make_shared(w_mat.data, w_mat.type(), shape(w_mat), cv::format("%s_w", op_name.c_str())); + auto op_const_weight = std::make_shared(w_mat.data, w_mat.type(), shape(w_mat), cv::format("%s_w", name.c_str())); op->set_input_filter(*(op_const_weight->getOp())); op->update_input_desc_filter(*(op_const_weight->getTensorDesc())); // set inputs : bias @@ -830,7 +848,7 @@ public: Mat b_mat({out_channel}, CV_32F, &biasvec[0]); std::vector bias_shape{out_channel}; - auto op_const_bias = std::make_shared(b_mat.data, b_mat.type(), bias_shape, cv::format("%s_b", op_name.c_str())); + auto op_const_bias = std::make_shared(b_mat.data, b_mat.type(), bias_shape, cv::format("%s_b", name.c_str())); op->set_input_bias(*(op_const_bias->getOp())); op->update_input_desc_bias(*(op_const_bias->getTensorDesc())); } diff --git a/modules/dnn/src/layers/elementwise_layers.cpp b/modules/dnn/src/layers/elementwise_layers.cpp index 9819073bc6..bb60410038 100644 --- a/modules/dnn/src/layers/elementwise_layers.cpp +++ b/modules/dnn/src/layers/elementwise_layers.cpp @@ -188,9 +188,10 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { - return func.initCannOp(inputsWrapper, index, nodes); + return func.initCannOp(Layer::name, inputsWrapper, nodes); } #endif // HAVE_CANN @@ -459,7 +460,9 @@ struct ReLUFunctor : public BaseFunctor #endif // HAVE_HALIDE #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); auto op_x = nodes[0].dynamicCast()->getOp(); @@ -469,10 +472,9 @@ struct ReLUFunctor : public BaseFunctor if (slope) { - std::string op_name = cv::format("leakyrelu_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); op->update_input_desc_x(*x_desc); op->set_attr_negative_slope(slope); @@ -482,10 +484,9 @@ struct ReLUFunctor : public BaseFunctor return Ptr(new CannBackendNode(op)); } - std::string op_name = cv::format("relu_%d", index); - auto op = std::make_shared(op_name); // FIXIT: Relu6? + auto op = std::make_shared(name); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); op->update_input_desc_x(*x_desc); op->update_output_desc_y(*output_desc); @@ -653,28 +654,29 @@ struct ReLU6Functor : public BaseFunctor #endif // HAVE_HALIDE #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); - std::string op_name = cv::format("clip_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); Mat min_value_mat(1, 1, CV_32F, Scalar(minValue)); std::vector shape_{1}; - auto op_const_minv = std::make_shared(min_value_mat.data, min_value_mat.type(), shape_, cv::format("%s_min_value", op_name.c_str())); + auto op_const_minv = std::make_shared(min_value_mat.data, min_value_mat.type(), shape_, cv::format("%s_min_value", name.c_str())); op->set_input_clip_value_min(*(op_const_minv->getOp())); op->update_input_desc_clip_value_min(*(op_const_minv->getTensorDesc())); Mat max_value_mat(1, 1, CV_32F, Scalar(maxValue)); - auto op_const_maxv = std::make_shared(max_value_mat.data, max_value_mat.type(), shape_, cv::format("%s_max_value", op_name.c_str())); - op->set_input_clip_value_min(*(op_const_maxv->getOp())); - op->update_input_desc_clip_value_min(*(op_const_maxv->getTensorDesc())); + auto op_const_maxv = std::make_shared(max_value_mat.data, max_value_mat.type(), shape_, cv::format("%s_max_value", name.c_str())); + op->set_input_clip_value_max(*(op_const_maxv->getOp())); + op->update_input_desc_clip_value_max(*(op_const_maxv->getTensorDesc())); auto output_desc = std::make_shared(ge::Shape(), ge::FORMAT_NCHW, ge::DT_FLOAT); op->update_output_desc_y(*output_desc); @@ -805,7 +807,9 @@ struct BaseDefaultFunctor : public BaseFunctor #endif // HAVE_HALIDE #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { CV_Error(Error::StsNotImplemented, ""); } @@ -925,15 +929,16 @@ struct TanHFunctor : public BaseDefaultFunctor #endif // HAVE_HALIDE #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); - std::string op_name = cv::format("tanh_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); @@ -991,17 +996,18 @@ struct SwishFunctor : public BaseDefaultFunctor #endif // HAVE_HALIDE #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); - std::string op_name = cv::format("swish_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); op->set_attr_scale(1.0f); auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); @@ -1068,15 +1074,16 @@ struct MishFunctor : public BaseDefaultFunctor #endif // HAVE_HALIDE #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); - std::string op_name = cv::format("mish_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); @@ -1143,15 +1150,16 @@ struct SigmoidFunctor : public BaseDefaultFunctor #endif // HAVE_HALIDE #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); - std::string op_name = cv::format("sigmoid_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); @@ -1220,17 +1228,18 @@ struct ELUFunctor : public BaseDefaultFunctor #endif // HAVE_HALIDE #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); - std::string op_name = cv::format("elu_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); op->set_attr_alpha(alpha); auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); @@ -1291,15 +1300,16 @@ struct AbsValFunctor : public BaseDefaultFunctor #endif // HAVE_HALIDE #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); - std::string op_name = cv::format("abs_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); @@ -1352,15 +1362,16 @@ struct BNLLFunctor : public BaseDefaultFunctor #endif #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); - std::string op_name = cv::format("bnll_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); @@ -1408,15 +1419,16 @@ struct CeilFunctor : public BaseDefaultFunctor #endif #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); - std::string op_name = cv::format("bnll_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); @@ -1466,15 +1478,16 @@ struct FloorFunctor : public BaseDefaultFunctor #endif #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); - std::string op_name = cv::format("floor_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); @@ -2320,7 +2333,9 @@ struct PowerFunctor : public BaseFunctor #endif // HAVE_HALIDE #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { CV_Error(Error::StsNotImplemented, ""); } @@ -2574,7 +2589,9 @@ struct ChannelsPReLUFunctor : public BaseFunctor #endif // HAVE_HALIDE #ifdef HAVE_CANN - Ptr initCannOp(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) + Ptr initCannOp(const std::string& name, + const std::vector > &inputsWrapper, + const std::vector >& nodes) { auto x = inputsWrapper[0].dynamicCast(); auto op_x = nodes[0].dynamicCast()->getOp(); @@ -2582,14 +2599,13 @@ struct ChannelsPReLUFunctor : public BaseFunctor auto output_desc = std::make_shared(ge::Shape(), ge::FORMAT_NCHW, ge::DT_FLOAT); - std::string op_name = cv::format("prelu_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); op->update_input_desc_x(*x_desc); std::vector shape_{scale.size[0]}; // scale should be a 1d of shape [n] tensor, and it is a 2d mat of shape [n, 1] in opencv - auto op_const_slope = std::make_shared(scale.data, scale.type(), shape_, cv::format("%s_weight", op_name.c_str())); + auto op_const_slope = std::make_shared(scale.data, scale.type(), shape_, cv::format("%s_weight", name.c_str())); op->set_input_weight(*(op_const_slope->getOp())); op->update_input_desc_weight(*(op_const_slope->getTensorDesc())); diff --git a/modules/dnn/src/layers/eltwise_layer.cpp b/modules/dnn/src/layers/eltwise_layer.cpp index 24a87bcc17..5052bd1823 100644 --- a/modules/dnn/src/layers/eltwise_layer.cpp +++ b/modules/dnn/src/layers/eltwise_layer.cpp @@ -849,7 +849,8 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { CV_Assert(inputsWrapper.size() == 2); CV_Assert(nodes.size() == 2); @@ -866,22 +867,22 @@ public: // add, mul, div, max, min switch (op) { -#define BUILD_CANN_ELTWISE_OP(op_type, class_name, op_name) \ - case op_type: { \ - auto eltwise_op = \ - std::make_shared(op_name); \ - eltwise_op->set_input_x1_by_name(*op_x1, "y"); \ - eltwise_op->set_input_x2_by_name(*op_x2, "y"); \ - eltwise_op->update_input_desc_x1(*x1_desc); \ - eltwise_op->update_input_desc_x2(*x2_desc); \ - eltwise_op->update_output_desc_y(*output_desc); \ - eltwise_operator = eltwise_op; \ +#define BUILD_CANN_ELTWISE_OP(op_type, class_name, op_name) \ + case op_type: { \ + auto eltwise_op = \ + std::make_shared(op_name); \ + eltwise_op->set_input_x1_by_name(*op_x1, x1->name.c_str()); \ + eltwise_op->set_input_x2_by_name(*op_x2, x2->name.c_str()); \ + eltwise_op->update_input_desc_x1(*x1_desc); \ + eltwise_op->update_input_desc_x2(*x2_desc); \ + eltwise_op->update_output_desc_y(*output_desc); \ + eltwise_operator = eltwise_op; \ } break; - BUILD_CANN_ELTWISE_OP(SUM, Add, cv::format("add_%d", index)); - BUILD_CANN_ELTWISE_OP(PROD, Mul, cv::format("mul_%d", index)); - BUILD_CANN_ELTWISE_OP(DIV, Xdivy, cv::format("div_%d", index)); - BUILD_CANN_ELTWISE_OP(MAX, Maximum, cv::format("max_%d", index)); - BUILD_CANN_ELTWISE_OP(MIN, Minimum, cv::format("min_%d", index)); + BUILD_CANN_ELTWISE_OP(SUM, Add, name); + BUILD_CANN_ELTWISE_OP(PROD, Mul, name); + BUILD_CANN_ELTWISE_OP(DIV, Xdivy, name); + BUILD_CANN_ELTWISE_OP(MAX, Maximum, name); + BUILD_CANN_ELTWISE_OP(MIN, Minimum, name); #undef BUILD_CANN_ELTWISE_OP default: CV_Error(Error::StsNotImplemented, "Unsupported eltwise operation"); } diff --git a/modules/dnn/src/layers/flatten_layer.cpp b/modules/dnn/src/layers/flatten_layer.cpp index ff30da3a11..226863fd3e 100644 --- a/modules/dnn/src/layers/flatten_layer.cpp +++ b/modules/dnn/src/layers/flatten_layer.cpp @@ -176,15 +176,15 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { auto x = inputsWrapper[0].dynamicCast(); auto x_desc = x->getTensorDesc(); auto op_x = nodes[0].dynamicCast()->getOp(); auto output_desc = std::make_shared(ge::Shape(), ge::FORMAT_NCHW, ge::DT_FLOAT); - std::string op_name = cv::format("flatten_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes int num_axes = x->host->dims; @@ -194,7 +194,7 @@ public: op->set_attr_end_axis(end_axis); // set inputs - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); op->update_input_desc_x(*x_desc); // set outputs op->update_output_desc_y(*output_desc); diff --git a/modules/dnn/src/layers/fully_connected_layer.cpp b/modules/dnn/src/layers/fully_connected_layer.cpp index 34c8b33515..d33ebb6515 100644 --- a/modules/dnn/src/layers/fully_connected_layer.cpp +++ b/modules/dnn/src/layers/fully_connected_layer.cpp @@ -662,15 +662,15 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { auto x1 = inputsWrapper[0].dynamicCast(); auto x1_desc = x1->getTensorDesc(); auto op_x1 = nodes[0].dynamicCast()->getOp(); auto output_desc = std::make_shared(ge::Shape(), ge::FORMAT_NCHW, ge::DT_FLOAT); - std::string op_name = cv::format("matmul_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); if (!blobs.empty()) // if B is const { @@ -682,7 +682,7 @@ public: // set inputs // set inputs : x2 (weight) - auto op_const_weight = std::make_shared(weightsMat.data, weightsMat.type(), shape(weightsMat), cv::format("%s_w", op_name.c_str())); + auto op_const_weight = std::make_shared(weightsMat.data, weightsMat.type(), shape(weightsMat), cv::format("%s_w", name.c_str())); op->set_input_x2_by_name(*(op_const_weight->getOp()), "y"); op->update_input_desc_x2(*(op_const_weight->getTensorDesc())); } @@ -705,12 +705,12 @@ public: // set inputs // set inputs : x1 (input) - op->set_input_x1_by_name(*op_x1, "y"); + op->set_input_x1_by_name(*op_x1, x1->name.c_str()); op->update_input_desc_x1(*x1_desc); // set inputs : bias (bias) auto bias_mat = bias ? biasMat : Mat::zeros(1, weightsMat.size[0], weightsMat.type()); std::vector bias_shape{weightsMat.size[0]}; - auto op_const_bias = std::make_shared(bias_mat.data, bias_mat.type(), bias_shape, cv::format("%s_b", op_name.c_str())); + auto op_const_bias = std::make_shared(bias_mat.data, bias_mat.type(), bias_shape, cv::format("%s_b", name.c_str())); op->set_input_bias(*(op_const_bias->getOp())); op->update_input_desc_bias(*(op_const_bias->getTensorDesc())); diff --git a/modules/dnn/src/layers/lrn_layer.cpp b/modules/dnn/src/layers/lrn_layer.cpp index f012a91730..95599afdc1 100644 --- a/modules/dnn/src/layers/lrn_layer.cpp +++ b/modules/dnn/src/layers/lrn_layer.cpp @@ -445,13 +445,13 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { auto x = inputsWrapper[0].dynamicCast(); // create operator - std::string op_name = cv::format("lrn_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes op->set_attr_depth_radius(size); @@ -465,7 +465,7 @@ public: // set inputs // set inputs : x auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); diff --git a/modules/dnn/src/layers/nary_eltwise_layers.cpp b/modules/dnn/src/layers/nary_eltwise_layers.cpp index 3232f0ae5c..280920af35 100644 --- a/modules/dnn/src/layers/nary_eltwise_layers.cpp +++ b/modules/dnn/src/layers/nary_eltwise_layers.cpp @@ -709,7 +709,8 @@ public: #endif #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { CV_Assert(inputsWrapper.size() == 2); CV_Assert(nodes.size() == 2); @@ -726,22 +727,22 @@ public: // add, mul, div, max, min switch (op) { -#define BUILD_CANN_ELTWISE_OP(op_type, class_name, op_name) \ - case op_type: { \ - auto eltwise_op = \ - std::make_shared(op_name); \ - eltwise_op->set_input_x1_by_name(*op_x1, "y"); \ - eltwise_op->set_input_x2_by_name(*op_x2, "y"); \ - eltwise_op->update_input_desc_x1(*x1_desc); \ - eltwise_op->update_input_desc_x2(*x2_desc); \ - eltwise_op->update_output_desc_y(*output_desc); \ - eltwise_operator = eltwise_op; \ +#define BUILD_CANN_ELTWISE_OP(op_type, class_name, op_name) \ + case op_type: { \ + auto eltwise_op = \ + std::make_shared(op_name); \ + eltwise_op->set_input_x1_by_name(*op_x1, x1->name.c_str()); \ + eltwise_op->set_input_x2_by_name(*op_x2, x2->name.c_str()); \ + eltwise_op->update_input_desc_x1(*x1_desc); \ + eltwise_op->update_input_desc_x2(*x2_desc); \ + eltwise_op->update_output_desc_y(*output_desc); \ + eltwise_operator = eltwise_op; \ } break; - BUILD_CANN_ELTWISE_OP(OPERATION::ADD, Add, cv::format("add_%d", index)); - BUILD_CANN_ELTWISE_OP(OPERATION::PROD, Mul, cv::format("mul_%d", index)); - BUILD_CANN_ELTWISE_OP(OPERATION::DIV, Xdivy, cv::format("div_%d", index)); - BUILD_CANN_ELTWISE_OP(OPERATION::MAX, Maximum, cv::format("max_%d", index)); - BUILD_CANN_ELTWISE_OP(OPERATION::MIN, Minimum, cv::format("min_%d", index)); + BUILD_CANN_ELTWISE_OP(OPERATION::ADD, Add, name); + BUILD_CANN_ELTWISE_OP(OPERATION::PROD, Mul, name); + BUILD_CANN_ELTWISE_OP(OPERATION::DIV, Xdivy, name); + BUILD_CANN_ELTWISE_OP(OPERATION::MAX, Maximum, name); + BUILD_CANN_ELTWISE_OP(OPERATION::MIN, Minimum, name); #undef BUILD_CANN_ELTWISE_OP default: CV_Error(Error::StsNotImplemented, "Unsupported eltwise operation"); } diff --git a/modules/dnn/src/layers/padding_layer.cpp b/modules/dnn/src/layers/padding_layer.cpp index 359c82a1a3..9cbac98e74 100644 --- a/modules/dnn/src/layers/padding_layer.cpp +++ b/modules/dnn/src/layers/padding_layer.cpp @@ -222,13 +222,13 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { auto x = inputsWrapper[0].dynamicCast(); // create operator - std::string op_name = cv::format("pad_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes op->set_attr_mode(paddingType.c_str()); @@ -236,7 +236,7 @@ public: // set inputs // set inputs : x auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); // set inputs : paddings @@ -248,13 +248,13 @@ public: } std::vector pads_shape{(int)pads.size()}; Mat paddings_mat(pads_shape, CV_32S, &pads[0]); - auto op_const_paddings = std::make_shared(paddings_mat.data, paddings_mat.type(), pads_shape, cv::format("%s_paddings", op_name.c_str())); + auto op_const_paddings = std::make_shared(paddings_mat.data, paddings_mat.type(), pads_shape, cv::format("%s_paddings", name.c_str())); op->set_input_paddings(*(op_const_paddings->getOp())); op->update_input_desc_paddings(*(op_const_paddings->getTensorDesc())); // set inputs : constant_values std::vector constant_values_shape{1}; Mat constant_values_mat(1, 1, CV_32F, Scalar(paddingValue)); - auto op_const_constant_values = std::make_shared(constant_values_mat.data, constant_values_mat.type(), constant_values_shape, cv::format("%s_constant_values", op_name.c_str())); + auto op_const_constant_values = std::make_shared(constant_values_mat.data, constant_values_mat.type(), constant_values_shape, cv::format("%s_constant_values", name.c_str())); op->set_input_constant_values(*(op_const_constant_values->getOp())); op->update_input_desc_constant_values(*(op_const_constant_values->getTensorDesc())); diff --git a/modules/dnn/src/layers/permute_layer.cpp b/modules/dnn/src/layers/permute_layer.cpp index 1aee12d7ae..c2b20af350 100644 --- a/modules/dnn/src/layers/permute_layer.cpp +++ b/modules/dnn/src/layers/permute_layer.cpp @@ -441,13 +441,13 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { auto x = inputsWrapper[0].dynamicCast(); // create operator - std::string op_name = cv::format("permute_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes op->set_attr_order(ge::Operator::OpListInt( @@ -457,7 +457,7 @@ public: // set inputs // set inputs : x auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); diff --git a/modules/dnn/src/layers/pooling_layer.cpp b/modules/dnn/src/layers/pooling_layer.cpp index 9b9ced468f..415887b411 100644 --- a/modules/dnn/src/layers/pooling_layer.cpp +++ b/modules/dnn/src/layers/pooling_layer.cpp @@ -548,18 +548,17 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { auto x = inputsWrapper[0].dynamicCast(); auto op_x = nodes[0].dynamicCast()->getOp(); auto x_desc = x->getTensorDesc(); auto output_desc = std::make_shared(ge::Shape(), ge::FORMAT_NCHW, ge::DT_FLOAT); - std::string op_name_base = cv::format("pooling_%d", index); if (type == MAX) { - std::string op_name = cv::format("max_%s", op_name_base.c_str()); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes op->set_attr_ksize(ge::Operator::OpListInt( @@ -580,7 +579,7 @@ public: op->set_attr_ceil_mode(ceilMode); // set inputs - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); op->update_input_desc_x(*x_desc); // set outputs op->update_output_desc_y(*output_desc); @@ -589,8 +588,7 @@ public: } else if (type == AVE) { - std::string op_name = cv::format("avg_%s", op_name_base.c_str()); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes op->set_attr_ksize(ge::Operator::OpListInt( @@ -612,7 +610,7 @@ public: op->set_attr_exclusive(cann_exclusive); // set inputs - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); op->update_input_desc_x(*x_desc); // set outputs op->update_output_desc_y(*output_desc); diff --git a/modules/dnn/src/layers/reshape_layer.cpp b/modules/dnn/src/layers/reshape_layer.cpp index 3ff8a225b7..e433ee1787 100644 --- a/modules/dnn/src/layers/reshape_layer.cpp +++ b/modules/dnn/src/layers/reshape_layer.cpp @@ -327,13 +327,13 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { auto x = inputsWrapper[0].dynamicCast(); // create operator - std::string op_name = cv::format("reshape_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes op->set_attr_axis(axis); @@ -342,13 +342,13 @@ public: // set inputs // set inputs : x auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); // set inputs : shape std::vector shape_of_shape{(int)newShapeDesc.size()}; Mat shape_mat(shape_of_shape, CV_32S, newShapeDesc.data()); - auto op_const_shape = std::make_shared(shape_mat.data, shape_mat.type(), shape_of_shape, cv::format("%s_shape", op_name.c_str())); + auto op_const_shape = std::make_shared(shape_mat.data, shape_mat.type(), shape_of_shape, cv::format("%s_shape", name.c_str())); op->set_input_shape(*(op_const_shape->getOp())); op->update_input_desc_shape(*(op_const_shape->getTensorDesc())); diff --git a/modules/dnn/src/layers/resize_layer.cpp b/modules/dnn/src/layers/resize_layer.cpp index 4342b51b78..8f21266e57 100644 --- a/modules/dnn/src/layers/resize_layer.cpp +++ b/modules/dnn/src/layers/resize_layer.cpp @@ -312,7 +312,8 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { auto x = inputsWrapper[0].dynamicCast(); auto x_desc = x->getTensorDesc(); @@ -320,23 +321,21 @@ public: auto output_y_desc = std::make_shared(ge::Shape(), ge::FORMAT_NCHW, ge::DT_FLOAT); // create operator - std::string op_name = cv::format("resize_%d", index); - if (interpolation == "nearest") { - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes op->set_attr_align_corners(alignCorners); op->set_attr_half_pixel_centers(halfPixelCenters); // set inputs : x - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); op->update_input_desc_x(*x_desc); // set inputs : size std::vector shape_of_size_mat{2}; Mat size_mat(2, 1, CV_32S, Scalar(outHeight, outWidth)); - auto op_const_size = std::make_shared(size_mat.data, size_mat.type(), shape_of_size_mat, cv::format("%s_size", op_name.c_str())); + auto op_const_size = std::make_shared(size_mat.data, size_mat.type(), shape_of_size_mat, cv::format("%s_size", name.c_str())); op->set_input_size(*(op_const_size->getOp())); op->update_input_desc_size(*(op_const_size->getTensorDesc())); @@ -347,21 +346,17 @@ public: } else if (interpolation == "opencv_linear" || interpolation == "bilinear") { - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes op->set_attr_align_corners(alignCorners); op->set_attr_half_pixel_centers(halfPixelCenters); + std::vector taget_size{(int64_t)outHeight, (int64_t)outWidth}; + op->set_attr_size(taget_size); // set inputs : x - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); op->update_input_desc_x(*x_desc); - // set inputs : size - std::vector shape_of_size_mat{2}; - Mat size_mat(2, 1, CV_32S, Scalar(outHeight, outWidth)); - auto op_const_size = std::make_shared(size_mat.data, size_mat.type(), shape_of_size_mat, cv::format("%s_size", op_name.c_str())); - op->set_input_size(*(op_const_size->getOp())); - op->update_input_desc_size(*(op_const_size->getTensorDesc())); // set outputs op->update_output_desc_y(*output_y_desc); diff --git a/modules/dnn/src/layers/slice_layer.cpp b/modules/dnn/src/layers/slice_layer.cpp index bea497badd..2bf86995f6 100644 --- a/modules/dnn/src/layers/slice_layer.cpp +++ b/modules/dnn/src/layers/slice_layer.cpp @@ -634,18 +634,74 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { - CV_Assert(sliceRanges.size() == 1); - CV_Assert(sliceSteps.size() == 1); - CV_Assert(sliceRanges[0].size() == sliceSteps[0].size()); - + bool isSplit = sliceRanges.size() > 1; auto x = inputsWrapper[0].dynamicCast(); + + if (isSplit) + { + // create operator + auto op = std::make_shared(name); + + // set attr + int n_split = static_cast(sliceRanges[0].size()); + op->set_attr_num_split(n_split); + + // set inputs + // set inputs : x + auto op_x = nodes[0].dynamicCast()->getOp(); + op->set_input_x_by_name(*op_x, x->name.c_str()); + auto desc_x = x->getTensorDesc(); + op->update_input_desc_x(*desc_x); + // set inputs : size_splits + std::vector size_splits(n_split); + int cnt_split = 0; + for (size_t i = 0; i < sliceRanges.size() - 1; ++i) + { + auto target_range = sliceRanges[i].back(); + size_splits[i] = target_range.end - target_range.start; + cnt_split += size_splits[i]; + } + auto shape_x = desc_x->GetShape().GetDims(); + CV_CheckGT(shape_x[axis], cnt_split, "DNN/CANN: invalid splits"); + size_splits[n_split - 1] = shape_x[axis] - cnt_split; + std::vector shape_size_splits{(int)size_splits.size()}; + Mat size_splits_mat(shape_size_splits, CV_32S, size_splits.data()); + auto op_const_size_splits = std::make_shared(size_splits_mat.data, size_splits_mat.type(), shape_size_splits, cv::format("%s_size_splits", name.c_str())); + op->set_input_size_splits(*(op_const_size_splits->getOp())); + op->update_input_desc_size_splits(*(op_const_size_splits->getTensorDesc())); + // set inputs : split_dim + Mat split_dim_mat(1, 1, CV_32S, Scalar(axis)); + std::vector split_dim_shape{1}; + auto op_const_split_dim = std::make_shared(split_dim_mat.data, split_dim_mat.type(), split_dim_shape, cv::format("%s_split_dim", name.c_str())); + op->set_input_split_dim(*(op_const_split_dim->getOp())); + op->update_input_desc_split_dim(*(op_const_split_dim->getTensorDesc())); + + // set outputs + op->create_dynamic_output_y(n_split); + for (uint32_t i = 0; i < n_split; ++i) + { + auto desc_output_y_i = std::make_shared(ge::Shape(), ge::FORMAT_NCHW, ge::DT_FLOAT); + op->update_dynamic_output_desc_y(i, *desc_output_y_i); + } + + return Ptr(new CannBackendNode(op)); + } + + // ONNX-Slice + CV_CheckEQ(sliceRanges.size(), (size_t)1, ""); + if (hasSteps) + { + CV_CheckEQ(sliceSteps.size(), (size_t)1, "DNN/CANN/Slice: no support to multiple slices"); + CV_CheckEQ(sliceRanges[0].size(), sliceSteps[0].size(), "DNN/CANN/Slice: number of slice ranges does not match number of slice steps"); + } + const int dims = x->host->dims; // create operator - std::string op_name = cv::format("slice_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // retrieve begins, ends, axes and steps std::vector begins, ends, axes, steps; @@ -654,34 +710,37 @@ public: begins.push_back(sliceRanges[0][i].start); ends.push_back(sliceRanges[0][i].end); axes.push_back(i); - steps.push_back(sliceSteps[0][i]); + if (hasSteps) + steps.push_back(sliceSteps[0][i]); + else + steps.push_back(1); // put 1 by default } std::vector shape_{dims}; // set inputs // set inputs : x auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); // set inputs : begin Mat begin_mat(shape_, CV_32S, &begins[0]); - auto op_const_begin = std::make_shared(begin_mat.data, begin_mat.type(), shape_, cv::format("%s_begin", op_name.c_str())); + auto op_const_begin = std::make_shared(begin_mat.data, begin_mat.type(), shape_, cv::format("%s_begin", name.c_str())); op->set_input_begin(*(op_const_begin->getOp())); op->update_input_desc_begin(*(op_const_begin->getTensorDesc())); // set inputs : end Mat end_mat(shape_, CV_32S, &ends[0]); - auto op_const_end = std::make_shared(end_mat.data, end_mat.type(), shape_, cv::format("%s_end", op_name.c_str())); + auto op_const_end = std::make_shared(end_mat.data, end_mat.type(), shape_, cv::format("%s_end", name.c_str())); op->set_input_end(*(op_const_end->getOp())); op->update_input_desc_end(*(op_const_end->getTensorDesc())); // set inputs : axes Mat axes_mat(shape_, CV_32S, &axes[0]); - auto op_const_axes = std::make_shared(axes_mat.data, axes_mat.type(), shape_, cv::format("%s_axes", op_name.c_str())); + auto op_const_axes = std::make_shared(axes_mat.data, axes_mat.type(), shape_, cv::format("%s_axes", name.c_str())); op->set_input_axes(*(op_const_axes->getOp())); op->update_input_desc_axes(*(op_const_axes->getTensorDesc())); // set inputs : strides Mat strides_mat(shape_, CV_32S, &steps[0]); - auto op_const_strides = std::make_shared(strides_mat.data, strides_mat.type(), shape_, cv::format("%s_strides", op_name.c_str())); + auto op_const_strides = std::make_shared(strides_mat.data, strides_mat.type(), shape_, cv::format("%s_strides", name.c_str())); op->set_input_strides(*(op_const_strides->getOp())); op->update_input_desc_strides(*(op_const_strides->getTensorDesc())); diff --git a/modules/dnn/src/layers/softmax_layer.cpp b/modules/dnn/src/layers/softmax_layer.cpp index c1ea4d2297..57afe4dbfa 100644 --- a/modules/dnn/src/layers/softmax_layer.cpp +++ b/modules/dnn/src/layers/softmax_layer.cpp @@ -365,13 +365,13 @@ public: } #ifdef HAVE_CANN - virtual Ptr initCann(const std::vector > &inputsWrapper, const int index, const std::vector >& nodes) CV_OVERRIDE + virtual Ptr initCann(const std::vector > &inputsWrapper, + const std::vector >& nodes) CV_OVERRIDE { auto x = inputsWrapper[0].dynamicCast(); // create operator - std::string op_name = cv::format("softmax_%d", index); - auto op = std::make_shared(op_name); + auto op = std::make_shared(name); // set attributes op->set_attr_axes(ge::Operator::OpListInt( @@ -381,7 +381,7 @@ public: // set inputs // set inputs : x auto op_x = nodes[0].dynamicCast()->getOp(); - op->set_input_x_by_name(*op_x, "y"); + op->set_input_x_by_name(*op_x, x->name.c_str()); auto x_desc = x->getTensorDesc(); op->update_input_desc_x(*x_desc); diff --git a/modules/dnn/src/net_cann.cpp b/modules/dnn/src/net_cann.cpp index 62d45d85c5..0b73427e40 100644 --- a/modules/dnn/src/net_cann.cpp +++ b/modules/dnn/src/net_cann.cpp @@ -124,6 +124,30 @@ void NetImplCann::initBackend(const std::vector& blobsToKeep_) if (!newWasSupported) return ; + // initialize each blob wrappers' names + for (MapIdToLayerData::const_iterator it = layers.begin(); it != layers.end(); ++it) + { + const LayerData& ld = it->second; + if (ld.id == 0) + { + for (int i = 0; i < ld.outputBlobsWrappers.size(); ++i) + { + auto cannWrapper = ld.outputBlobsWrappers[i].dynamicCast(); + // cannWrapper->name = netInputLayer->outNames.empty() ? cv::format("%s_%d", ld.name.c_str(), i) : netInputLayer->outNames[i]; + cannWrapper->name = std::string("y"); + } + } + else + { + for (int i = 0; i < ld.outputBlobsWrappers.size(); ++i) + { + auto cannWrapper = ld.outputBlobsWrappers[i].dynamicCast(); + // cannWrapper->name = ld.outputBlobsWrappers.size() > 1 ? (ld.name + ":" + std::to_string(i)) : ld.name; + cannWrapper->name = ld.outputBlobsWrappers.size() > 1 ? (std::string("y") + std::to_string(i)) : std::string("y"); + } + } + } + // convert layers to CANN operators, // collect graph input and output operators, // collect and input and output wrappers @@ -141,15 +165,16 @@ void NetImplCann::initBackend(const std::vector& blobsToKeep_) { for (int i = 0; i < ld.outputBlobsWrappers.size(); i++) { - std::string inputName = netInputLayer->outNames.empty() ? cv::format("%s_%d", ld.name.c_str(), i) : netInputLayer->outNames[i]; - auto inputOp = std::make_shared(inputName); - // retrieve tensor description auto wrapper = ld.outputBlobsWrappers[i]; graphInputWrappers.push_back(wrapper); auto cannWrapper = wrapper.dynamicCast(); CV_Assert(!cannWrapper.empty()); + // create graph input op + std::string inputOpName = netInputLayer->outNames.empty() ? cv::format("%s_%d", ld.name.c_str(), i) : netInputLayer->outNames[i]; + auto inputOp = std::make_shared(inputOpName); + inputOp->update_input_desc_x(*(cannWrapper->desc_)); inputOp->update_output_desc_y(*(cannWrapper->desc_)); @@ -170,14 +195,14 @@ void NetImplCann::initBackend(const std::vector& blobsToKeep_) { layerInputNodes.push_back(netInputNodes[layerInputOid]); } - else // here we do not consider an op with multiple outputs + else { layerInputNodes.push_back(layers[layerInputLid].backendNodes[preferableBackend]); } } CV_LOG_INFO(NULL, "DNN/CANN: converting layer " << ld.name << "@" << ld.type << "@" << ld.id << " to CANN operator"); - auto backendNode = layer->initCann(ld.inputBlobsWrappers, ld.id, layerInputNodes); + auto backendNode = layer->initCann(ld.inputBlobsWrappers, layerInputNodes); // it's ok if ld.name is empty // collect outputs bool isOutputNode = ld.consumers.size() == 0 ? true : false; @@ -201,7 +226,7 @@ void NetImplCann::initBackend(const std::vector& blobsToKeep_) // build graph from collected graph inputs and outputs CV_LOG_INFO(NULL, "DNN/CANN: building ge::Graph"); - std::string graphName = cv::format("graph_%d", 0); + std::string graphName = cv::format("graph_%d", networkId); std::shared_ptr graph = std::make_shared(graphName.c_str()); (void)graph->SetInputs(graphInputOps); (void)graph->SetOutputs(graphOutputOps); @@ -292,9 +317,9 @@ std::shared_ptr compileCannGraph(std::shared_ptr #if 0 // (optional). Dump model - AscendString graph_name; - graph.GetName(graph_name); - aclgrphDumpGraph(graph, graph_name.GetString(), 7); + ge::AscendString graph_name; + graph->GetName(graph_name); + aclgrphDumpGraph(*graph, graph_name.GetString(), 7); // (optional). Save model aclgrphSaveModel(graph_name.GetString(), *om_model); #endif diff --git a/modules/dnn/src/op_cann.cpp b/modules/dnn/src/op_cann.cpp index 6d8a57446b..5894aef337 100644 --- a/modules/dnn/src/op_cann.cpp +++ b/modules/dnn/src/op_cann.cpp @@ -177,7 +177,7 @@ void CannNet::bindInputWrappers(const std::vector>& inputWra void CannNet::bindOutputWrappers(const std::vector>& outputWrappers) { - CV_Assert(outputWrappers.size() == getOutputNum()); + CV_CheckEQ(outputWrappers.size(), getOutputNum(), "DNN/CANN: Built graph does not have the same number of outputs of model description"); for (int i = 0; i < outputWrappers.size(); ++i) { auto wrapper = outputWrappers[i].dynamicCast(); diff --git a/modules/dnn/src/op_cann.hpp b/modules/dnn/src/op_cann.hpp index 2237dd4855..c60c311b7f 100644 --- a/modules/dnn/src/op_cann.hpp +++ b/modules/dnn/src/op_cann.hpp @@ -106,6 +106,7 @@ CV__DNN_INLINE_NS_END Mat* host; std::shared_ptr desc_; + std::string name; }; class CannNet