1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

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
This commit is contained in:
Yuantao Feng
2023-03-14 02:46:33 +08:00
committed by GitHub
parent e03e2e7f94
commit b94e13c8ae
23 changed files with 317 additions and 202 deletions
+34 -9
View File
@@ -124,6 +124,30 @@ void NetImplCann::initBackend(const std::vector<LayerPin>& 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<CannBackendWrapper>();
// 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<CannBackendWrapper>();
// 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<LayerPin>& 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<ge::op::Data>(inputName);
// retrieve tensor description
auto wrapper = ld.outputBlobsWrappers[i];
graphInputWrappers.push_back(wrapper);
auto cannWrapper = wrapper.dynamicCast<CannBackendWrapper>();
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<ge::op::Data>(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<LayerPin>& 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<LayerPin>& 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<ge::Graph> graph = std::make_shared<ge::Graph>(graphName.c_str());
(void)graph->SetInputs(graphInputOps);
(void)graph->SetOutputs(graphOutputOps);
@@ -292,9 +317,9 @@ std::shared_ptr<ge::ModelBufferData> compileCannGraph(std::shared_ptr<ge::Graph>
#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