From 12b5091ba48611da9812422e93431259eee6d27c Mon Sep 17 00:00:00 2001 From: Anemptyship Date: Mon, 9 Feb 2026 03:06:08 +0000 Subject: [PATCH] optimize(dnn): parallelize Resize layer implementation Backport of PR #28442 to 4.x branch. Signed-off-by: Anemptyship --- modules/dnn/perf/perf_resize.cpp | 63 +++++++++++++++++++++++++ modules/dnn/src/layers/resize_layer.cpp | 14 ++++-- 2 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 modules/dnn/perf/perf_resize.cpp diff --git a/modules/dnn/perf/perf_resize.cpp b/modules/dnn/perf/perf_resize.cpp new file mode 100644 index 0000000000..b1cf798b26 --- /dev/null +++ b/modules/dnn/perf/perf_resize.cpp @@ -0,0 +1,63 @@ +// 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. + +#include "perf_precomp.hpp" + +namespace opencv_test { + +struct Layer_Resize : public TestBaseWithParam> +{ + void test_layer(const std::vector& inpShape, int outH, int outW, const String& interp) + { + int backendId = get<0>(GetParam()); + int targetId = get<1>(GetParam()); + + Mat input(inpShape, CV_32FC1); + randu(input, 0.f, 1.f); + + Net net; + LayerParams lp; + lp.type = "Resize"; + lp.name = "testLayer"; + lp.set("interpolation", interp); + lp.set("width", outW); + lp.set("height", outH); + + int id = net.addLayerToPrev(lp.name, lp.type, lp); + net.connect(0, 0, id, 0); + + // warmup + { + net.setInputsNames({"data"}); + net.setInput(input, "data"); + net.setPreferableBackend(backendId); + net.setPreferableTarget(targetId); + Mat out = net.forward(); + } + + TEST_CYCLE() + { + Mat res = net.forward(); + } + + SANITY_CHECK_NOTHING(); + } +}; + +PERF_TEST_P_(Layer_Resize, Resize_Upsample_Linear) +{ + // N=4, C=64, H=64, W=64 -> 128x128 (x2 upsample) + // Common in segmentation/detection heads + test_layer({4, 64, 64, 64}, 128, 128, "opencv_linear"); +} + +PERF_TEST_P_(Layer_Resize, Resize_Downsample_Nearest) +{ + // N=4, C=128, H=128, W=128 -> 64x64 (x0.5 downsample) + test_layer({4, 128, 128, 128}, 64, 64, "nearest"); +} + +INSTANTIATE_TEST_CASE_P(/**/, Layer_Resize, dnnBackendsAndTargets()); + +} // namespace opencv_test diff --git a/modules/dnn/src/layers/resize_layer.cpp b/modules/dnn/src/layers/resize_layer.cpp index a7c80cc210..3d904db67a 100644 --- a/modules/dnn/src/layers/resize_layer.cpp +++ b/modules/dnn/src/layers/resize_layer.cpp @@ -140,14 +140,20 @@ public: { // INTER_LINEAR Resize mode does not support INT8 inputs InterpolationFlags mode = interpolation == "nearest" ? INTER_NEAREST : INTER_LINEAR; - for (size_t n = 0; n < inputs[0].size[0]; ++n) - { - for (size_t ch = 0; ch < inputs[0].size[1]; ++ch) + + size_t nbatch = inputs[0].size[0]; + size_t nch = inputs[0].size[1]; + size_t total_planes = nbatch * nch; + + parallel_for_(Range(0, (int)total_planes), [&](const Range& range){ + for (int i = range.start; i < range.end; ++i) { + int n = i / nch; + int ch = i % nch; resize(getPlane(inp, n, ch), getPlane(out, n, ch), Size(outWidth, outHeight), 0, 0, mode); } - } + }); } else if (interpolation == "nearest") {