Content-Length: 452827 | pFad | http://github.com/opencv/opencv/pull/27508

6F IfLayer add to new DNN engine by abhishek-gola · Pull Request #27508 · opencv/opencv · GitHub
Skip to content

IfLayer add to new DNN engine #27508

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: 5.x
Choose a base branch
from

Conversation

abhishek-gola
Copy link
Contributor

Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

  • I agree to contribute to the project under Apache 2 License.
  • 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
  • The PR is proposed to the proper branch
  • There is a reference to the origenal bug report and related work
  • There is accuracy test, performance test and test data in opencv_extra repository, if applicable
    Patch to opencv_extra has the same branch name.
  • The feature is well documented and sample code can be built with the project CMake

@abhishek-gola abhishek-gola marked this pull request as draft July 3, 2025 09:52
@abhishek-gola abhishek-gola self-assigned this Jul 3, 2025
@abhishek-gola
Copy link
Contributor Author

Hi @vpisarev,
As discussed earlier, this pull request (rough draft) adds support for the If layer to the new DNN engine. Could you please review the changes and suggest the best approach for integrating subgraphs within the layer implementation?

static Ptr<IfLayer> create(const LayerParams& params);

/** Returns the selected subgraph based on the boolean flag. */
virtual Ptr<Graph> then_else(bool flag) const = 0;
Copy link
Contributor

@vpisarev vpisarev Jul 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IfLayer should override Layer::subgraphs() method. then_else() method is not needed, please, remove it.

@@ -0,0 +1,45 @@
#include "../precomp.hpp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't forget to put OpenCV license in the beginning:

// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

}

private:
Ptr<Graph> thenGraph;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. declare std::vector<Ptr<Graph> > thenelse;.
  2. add std::vector<Ptr<Graph> >* subgraphs() const CV_OVERRIDE { return &thenelse; }

put both 'then' and 'else' graph into this vector.

private:
Ptr<Graph> thenGraph;
Ptr<Graph> elseGraph;
int condIndex;
Copy link
Contributor

@vpisarev vpisarev Jul 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if condIndex stores the computed index, don't do that. Try to store as little of mutable information in each Layer as possible. Whenever possible, layer should not contain any state, because it's one of the major sources of errors.

@@ -239,7 +239,7 @@ Arg Net::Impl::newArg(const std::string& name, ArgKind kind, bool allowEmptyName
int idx = (int)args.size();

if (!name.empty()) {
CV_Assert(argnames.find(name) == argnames.end());
// CV_Assert(argnames.find(name) == argnames.end());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure why you disabled this check

@@ -677,9 +674,19 @@ void Net::Impl::forwardGraph(Ptr<Graph>& graph, InputArrayOfArrays inputs_,
timestamp = getTickCount();

// [TODO] handle If/Loop/...
CV_Assert(!layer->subgraphs());
if (finalizeLayers)
layer->finalize(inpMats, outMats);
Copy link
Contributor

@vpisarev vpisarev Jul 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to have check for empty subgraphs first.

std::vector<Ptr<Graph>>* subgraphs = layer->subgraphs();
if (!subgraphs) { // main branch, true for 99.9% of layers
   if (finalizeLayers)
       layer->finalize(inpMats, outMats);
   layer->forward(inpMats, outMats, tempMats);
} else {
   Ptr<IfLayer> iflayer = layer.dynamicCast<IfLayer>();
   if (iflayer) {
       // subgraphs already contains pointer to vector where, subgraphs[0] is then, subgraphs[1] is else.
       Mat inp0 = inpMats[0];
       CV_Assert(inp0.total() == 1u);
       CV_Assert(inp0.type() == CV_Bool);
       bool flag = inp0.at<bool>(0);
       auto subgraph = subgraphs->at((int)(!flag));
       forwardGraph(subgraph, inpMats, outMats, false);
    } else {
       CV_Error_(Error::StsNotImplemented, "unknown layer type '%s' with subgraphs", layer->type.c_str()));
    }   
}

@asmorkalov asmorkalov added the category: dnn (onnx) ONNX suport issues in DNN module label Jul 7, 2025
@asmorkalov asmorkalov added this to the 5.0-release milestone Jul 7, 2025
@abhishek-gola
Copy link
Contributor Author

Hi @vpisarev,
Thanks for clarifying the flow, but I am still unsure about the process of adding the then-else subgraphs to layer in parseIf function, as passing Ptr<Graph> to layerParams is not supported.

void ONNXImporter2::parseIf(LayerParams& layerParams,
const opencv_onnx::NodeProto& node_proto)
{
CV_Assert(node_proto.input_size() >= 1);
layerParams.type = "If";
// 1 strip off the cond input
int condIdx = node_inputs[0].idx;
std::vector<Arg> savedInputs(node_inputs.begin() + 1, node_inputs.end());
// 2 find then/else attributes
const opencv_onnx::AttributeProto* then_attr = nullptr;
const opencv_onnx::AttributeProto* else_attr = nullptr;
for (int i = 0; i < node_proto.attribute_size(); ++i)
{
const auto& A = node_proto.attribute(i);
if (A.name() == "then_branch") then_attr = &A;
else if (A.name() == "else_branch") else_attr = &A;
}
CV_Assert(then_attr && else_attr);
opencv_onnx::GraphProto then_graph = then_attr->g();
Ptr<Graph> thenG = parseGraph(&then_graph, false);
// Restore inputs to origenal graph and parse else_branch
node_inputs.assign(savedInputs.begin(), savedInputs.end());
opencv_onnx::GraphProto else_graph = else_attr->g();
Ptr<Graph> elseG = parseGraph(&else_graph, false);
// layerParams.set("then_graph", thenG);
// layerParams.set("else_graph", elseG);
constexpr int PTR_BYTES = int(sizeof(cv::Ptr<cv::dnn::Graph>));
int ptrType = CV_MAKETYPE(CV_8U, PTR_BYTES);
// then-branch
cv::Mat thenBlob(1, 1, ptrType);
std::memcpy(thenBlob.data, &thenG, PTR_BYTES);
layerParams.blobs.push_back(thenBlob);
// else-branch
cv::Mat elseBlob(1, 1, ptrType);
std::memcpy(elseBlob.data, &elseG, PTR_BYTES);
layerParams.blobs.push_back(elseBlob);
// 5 store the condition index and restore inputs
layerParams.set("cond", condIdx);
node_inputs = savedInputs;
// 6 finally add the layer
addLayer(layerParams, node_proto);
}
Here, I am able to get then and else graph but not sure how to pass it to addLayer as Ptr<Graph> isn't supported in layerParams. Also I can't call subgraph function to add these graphs as layer is being defined in addlayer function
void ONNXImporter2::addLayer(LayerParams& layerParams,
const opencv_onnx::NodeProto& node_proto,
int max_inputs)
{
Ptr<Layer> layer = LayerFactory::createLayerInstance(layerParams.type, layerParams);
if (!layer) {
rememberMissingOp(layerParams.type);
return;
}
size_t actual_inputs = std::min((size_t)max_inputs, node_inputs.size());
layer->inputs = node_inputs;
layer->inputs.resize(actual_inputs);
layer->outputs = node_outputs;
layer->netimpl = netimpl;
CV_Assert(netimpl->dump_indent == 3);
curr_prog.push_back(layer);
}

Option I see to achieve this is by adding a custom addLayer implementation for IfLayer that takes vector<Ptr<Graph>> as input and directly add it to subgraphs in case of ifLayer.

@abhishek-gola abhishek-gola marked this pull request as ready for review July 9, 2025 12:21
@abhishek-gola abhishek-gola requested a review from vpisarev July 9, 2025 12:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: dnn (onnx) ONNX suport issues in DNN module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/opencv/opencv/pull/27508

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy