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

Merge pull request #28724 from ssam18:fix/resize-ngraph-two-inputs-28707

dnn: fix Resize initNgraph for two-input case #28724

## Summary

Fixes the issue #28707

When a Resize/Upsample layer has two inputs, the data tensor and a reference tensor whose **shape** defines the output spatial size, the OpenVINO/NGRAPH backend's `initNgraph()` was ignoring `nodes[1]` entirely and relying solely on the `outHeight`/`outWidth` member variables.

These variables are set by `finalize()` from the pre-computed output blob dimensions. However, when the output shape is determined dynamically at runtime from the second input, `finalize()` sets them from the live tensor, but the OpenVINO backend calls `initNgraph()` to build a static compiled graph. If the member variables are 0 at that point, the compiled `Interpolate` node gets hardcoded with `{0, 0}` output dimensions, causing CV_Assert failure: {N,C,0,0} vs {N,C,H2,W2}
This commit is contained in:
SamareshSingh
2026-03-30 02:06:54 -05:00
committed by GitHub
parent c7732e1043
commit 2027a33990
+22 -9
View File
@@ -400,17 +400,30 @@ public:
attrs.nearest_mode = ov::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
std::vector<int64_t> shape = {outHeight, outWidth};
auto out_shape = std::make_shared<ov::op::v0::Constant>(ov::element::i64, ov::Shape{2}, shape.data());
auto& input_shape = ieInpNode.get_shape();
CV_Assert_N(input_shape[2] != 0, input_shape[3] != 0);
std::vector<float> scales = {static_cast<float>(outHeight) / input_shape[2], static_cast<float>(outWidth) / input_shape[3]};
auto scales_shape = std::make_shared<ov::op::v0::Constant>(ov::element::f32, ov::Shape{2}, scales.data());
std::shared_ptr<ov::Node> out_shape_node;
std::shared_ptr<ov::Node> scales_node;
if (nodes.size() == 2)
{
auto& ieRefNode = nodes[1].dynamicCast<InfEngineNgraphNode>()->node;
auto ref_shape = std::make_shared<ov::op::v3::ShapeOf>(ieRefNode, ov::element::i64);
auto hw_indices = std::make_shared<ov::op::v0::Constant>(ov::element::i64, ov::Shape{2}, std::vector<int64_t>{2, 3});
auto gather_axis = std::make_shared<ov::op::v0::Constant>(ov::element::i64, ov::Shape{}, 0LL);
out_shape_node = std::make_shared<ov::op::v8::Gather>(ref_shape, hw_indices, gather_axis);
std::vector<float> dummy_scales = {1.0f, 1.0f};
scales_node = std::make_shared<ov::op::v0::Constant>(ov::element::f32, ov::Shape{2}, dummy_scales.data());
}
else
{
std::vector<int64_t> shape = {outHeight, outWidth};
out_shape_node = std::make_shared<ov::op::v0::Constant>(ov::element::i64, ov::Shape{2}, shape.data());
auto& input_shape = ieInpNode.get_shape();
CV_Assert_N(input_shape[2] != 0, input_shape[3] != 0);
std::vector<float> scales = {static_cast<float>(outHeight) / input_shape[2],static_cast<float>(outWidth) / input_shape[3]};
scales_node = std::make_shared<ov::op::v0::Constant>(ov::element::f32, ov::Shape{2}, scales.data());
}
auto axes = std::make_shared<ov::op::v0::Constant>(ov::element::i64, ov::Shape{2}, std::vector<int64_t>{2, 3});
auto interp = std::make_shared<ov::op::v4::Interpolate>(ieInpNode, out_shape, scales_shape, axes, attrs);
auto interp = std::make_shared<ov::op::v4::Interpolate>(ieInpNode, out_shape_node, scales_node, axes, attrs);
return Ptr<BackendNode>(new InfEngineNgraphNode(interp));
}
#endif // HAVE_DNN_NGRAPH