Skip to content

dnn onnx: fix for multiple Gather operators with shared constants.#24334

Merged
asmorkalov merged 1 commit intoopencv:4.xfrom
fengyuentau:fix_24319
Sep 28, 2023
Merged

dnn onnx: fix for multiple Gather operators with shared constants.#24334
asmorkalov merged 1 commit intoopencv:4.xfrom
fengyuentau:fix_24319

Conversation

@fengyuentau
Copy link
Copy Markdown
Member

@fengyuentau fengyuentau commented Sep 28, 2023

Resolves #24319
Merge with opencv/opencv_extra#1101

Problem

The model in the issue above has several Gather operators which have shared constant indices (same name, same category Constant, same type, same value). The following piece of code in onnx importer adds an attribute real_ndims if indices is not a layer

if (layer_id.find(node_proto.input(1)) == layer_id.end())
{
int real_ndims = getBlobExtraInfo(node_proto.input(1)).real_ndims;
layerParams.set("real_ndims", real_ndims);
if (layer_id.find(node_proto.input(0)) == layer_id.end())
{
std::vector<Mat> inputs, output;
Mat input = getBlob(node_proto, 0);
int input_real_ndims = input.dims;
int type = input.type();
input.convertTo(input, CV_32FC1);
inputs.push_back(input);
Mat indices = getBlob(node_proto, 1);
indices.convertTo(indices, CV_32FC1);
inputs.push_back(indices);
runLayer(layerParams, inputs, output);
output.back().convertTo(output.back(), type);
if (real_ndims < 2) // In case of scalars or 1D vectors, OpenCV initializes 2D cv::Mat
output.back().dims = std::max(input_real_ndims - real_ndims, 1);
addConstant(node_proto.output(0), output.back());
return;
}
}

, but the following code converts the constant indices into a Const layer:

for (int i = 0; i < node_proto.input_size(); ++i)
{
if (layer_id.find(node_proto.input(i)) == layer_id.end())
{
LayerParams constParams;
constParams.name = node_proto.input(i);
constParams.type = "Const";
Mat blob = getBlob(node_proto, i);
if (i == 1)
{
blob.convertTo(blob, CV_32FC1);
}
constParams.blobs.push_back(blob);
opencv_onnx::NodeProto proto;
proto.add_output(constParams.name);
addLayer(constParams, proto);
}
}

, which makes problems for later Gather operators who have shared indices. For later Gather who have shared indices, indices have been converted to a Const layer in dnn, leading to real_ndims non-set.


Similar problems may happen on other operators as well. Need further investigation.

 

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 original 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

Copy link
Copy Markdown
Member

@dkurt dkurt left a comment

Choose a reason for hiding this comment

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

Thank you!

@dkurt dkurt self-assigned this Sep 28, 2023
@asmorkalov asmorkalov merged commit b8d4ac5 into opencv:4.x Sep 28, 2023
@asmorkalov asmorkalov mentioned this pull request Sep 28, 2023
@fengyuentau fengyuentau deleted the fix_24319 branch September 29, 2023 08:28
@fengyuentau fengyuentau changed the title dnn onnx: fix not-found constant indices for Gather if shared dnn onnx: fix for multiple Gather operators with shared constants. Oct 6, 2023
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 category: dnn

Projects

None yet

Development

Successfully merging this pull request may close these issues.

error loading onnx model while reading it from opencv dnn module

3 participants