From 2027a3399076b099930fc8eb2721d8c028fdabc0 Mon Sep 17 00:00:00 2001 From: SamareshSingh <97642706+ssam18@users.noreply.github.com> Date: Mon, 30 Mar 2026 02:06:54 -0500 Subject: [PATCH] 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} --- modules/dnn/src/layers/resize_layer.cpp | 31 ++++++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/modules/dnn/src/layers/resize_layer.cpp b/modules/dnn/src/layers/resize_layer.cpp index 3d904db67a..89732fbe85 100644 --- a/modules/dnn/src/layers/resize_layer.cpp +++ b/modules/dnn/src/layers/resize_layer.cpp @@ -400,17 +400,30 @@ public: attrs.nearest_mode = ov::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR; - - std::vector shape = {outHeight, outWidth}; - auto out_shape = std::make_shared(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 scales = {static_cast(outHeight) / input_shape[2], static_cast(outWidth) / input_shape[3]}; - auto scales_shape = std::make_shared(ov::element::f32, ov::Shape{2}, scales.data()); + std::shared_ptr out_shape_node; + std::shared_ptr scales_node; + if (nodes.size() == 2) + { + auto& ieRefNode = nodes[1].dynamicCast()->node; + auto ref_shape = std::make_shared(ieRefNode, ov::element::i64); + auto hw_indices = std::make_shared(ov::element::i64, ov::Shape{2}, std::vector{2, 3}); + auto gather_axis = std::make_shared(ov::element::i64, ov::Shape{}, 0LL); + out_shape_node = std::make_shared(ref_shape, hw_indices, gather_axis); + std::vector dummy_scales = {1.0f, 1.0f}; + scales_node = std::make_shared(ov::element::f32, ov::Shape{2}, dummy_scales.data()); + } + else + { + std::vector shape = {outHeight, outWidth}; + out_shape_node = std::make_shared(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 scales = {static_cast(outHeight) / input_shape[2],static_cast(outWidth) / input_shape[3]}; + scales_node = std::make_shared(ov::element::f32, ov::Shape{2}, scales.data()); + } auto axes = std::make_shared(ov::element::i64, ov::Shape{2}, std::vector{2, 3}); - auto interp = std::make_shared(ieInpNode, out_shape, scales_shape, axes, attrs); + auto interp = std::make_shared(ieInpNode, out_shape_node, scales_node, axes, attrs); return Ptr(new InfEngineNgraphNode(interp)); } #endif // HAVE_DNN_NGRAPH