From 28658bc2ac3a3d6f6e791c35003316a06d6b00ba Mon Sep 17 00:00:00 2001 From: Teresa Charlin Date: Tue, 19 Dec 2023 15:49:31 +0000 Subject: Fix for Resize with align corners = true creates a memory leak when using valgrind * Add end to end unit test to CpuRef, CpuAcc and GpuAcc backends Resolves: IVGCVSW-8193 Signed-off-by: Teresa Charlin Change-Id: I7be226f084ec814ac72c2c9b3c47c07b3baf0aa5 --- include/armnn/Utils.hpp | 7 +++++ src/backends/cl/test/ClEndToEndTests.cpp | 33 ++++++++++++++++++++++++ src/backends/neon/test/NeonEndToEndTests.cpp | 33 ++++++++++++++++++++++++ src/backends/reference/test/RefEndToEndTests.cpp | 10 +++++++ src/backends/reference/workloads/Resize.cpp | 30 ++++++++++----------- 5 files changed, 98 insertions(+), 15 deletions(-) diff --git a/include/armnn/Utils.hpp b/include/armnn/Utils.hpp index 7c1f096823..8976b38ecc 100644 --- a/include/armnn/Utils.hpp +++ b/include/armnn/Utils.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include namespace armnn { @@ -39,4 +40,10 @@ bool NeonDetected(); const std::string GetVersion(); +inline float roundf(float value) +{ + // Workaround Valgrind's mismatches: when running from Valgrind the call to std::round(4.5) == 4.0 instead of 5.0 + return (value < 0.f) ? ::floorf(value - 0.5f) : ::floorf(value + 0.5f); +} + } // namespace armnn diff --git a/src/backends/cl/test/ClEndToEndTests.cpp b/src/backends/cl/test/ClEndToEndTests.cpp index 78d2dea90d..b83bb1b0ad 100644 --- a/src/backends/cl/test/ClEndToEndTests.cpp +++ b/src/backends/cl/test/ClEndToEndTests.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -346,6 +347,38 @@ TEST_CASE("ClReshapeEndToEndTestFloat16") ReshapeEndToEndFloat16(clDefaultBackends); } +// Resize Bilinear +TEST_CASE("ClResizeBilinearEndToEndFloatNchwTest") +{ + ResizeBilinearEndToEnd(clDefaultBackends, armnn::DataLayout::NCHW); +} + +TEST_CASE("ClResizeBilinearEndToEndFloatNhwcTest") +{ + ResizeBilinearEndToEnd(clDefaultBackends, armnn::DataLayout::NHWC); +} + +// Resize NearestNeighbor +TEST_CASE("ClResizeNearestNeighborEndToEndFloatNchwTest") +{ + ResizeNearestNeighborEndToEnd(clDefaultBackends, armnn::DataLayout::NCHW); +} + +TEST_CASE("ClResizeNearestNeighborEndToEndFloatNhwcTest") +{ + ResizeNearestNeighborEndToEnd(clDefaultBackends, armnn::DataLayout::NHWC); +} + +TEST_CASE("ClResizeNearestNeighborEndToEndFloatAlignCornersNhwcTest") +{ + ResizeNearestNeighborEndToEnd(clDefaultBackends, armnn::DataLayout::NHWC, true, false); +} + +TEST_CASE("ClResizeNearestNeighborEndToEndFloatHalfPixelNhwcTest") +{ + ResizeNearestNeighborEndToEnd(clDefaultBackends, armnn::DataLayout::NHWC, false, true); +} + // ReverseV2 TEST_CASE("ClReverseV2EndToEndTest") { diff --git a/src/backends/neon/test/NeonEndToEndTests.cpp b/src/backends/neon/test/NeonEndToEndTests.cpp index 1e2636bf6f..9baded6671 100644 --- a/src/backends/neon/test/NeonEndToEndTests.cpp +++ b/src/backends/neon/test/NeonEndToEndTests.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -672,6 +673,38 @@ TEST_CASE("NeonReshapeEndToEndTestFloat16") ReshapeEndToEndFloat16(neonDefaultBackends); } +// Resize Bilinear +TEST_CASE("NeonResizeBilinearEndToEndFloatNchwTest") +{ + ResizeBilinearEndToEnd(neonDefaultBackends, armnn::DataLayout::NCHW); +} + +TEST_CASE("NeonResizeBilinearEndToEndFloatNhwcTest") +{ + ResizeBilinearEndToEnd(neonDefaultBackends, armnn::DataLayout::NHWC); +} + +// Resize NearestNeighbor +TEST_CASE("NeonResizeNearestNeighborEndToEndFloatNchwTest") +{ + ResizeNearestNeighborEndToEnd(neonDefaultBackends, armnn::DataLayout::NCHW); +} + +TEST_CASE("NeonResizeNearestNeighborEndToEndFloatNhwcTest") +{ + ResizeNearestNeighborEndToEnd(neonDefaultBackends, armnn::DataLayout::NHWC); +} + +TEST_CASE("NeonResizeNearestNeighborEndToEndFloatAlignCornersNhwcTest") +{ + ResizeNearestNeighborEndToEnd(neonDefaultBackends, armnn::DataLayout::NHWC, true, false); +} + +TEST_CASE("NeonResizeNearestNeighborEndToEndFloatHalfPixelNhwcTest") +{ + ResizeNearestNeighborEndToEnd(neonDefaultBackends, armnn::DataLayout::NHWC, false, true); +} + // ReverseV2 TEST_CASE("NeonReverseV2EndToEndTest") { diff --git a/src/backends/reference/test/RefEndToEndTests.cpp b/src/backends/reference/test/RefEndToEndTests.cpp index 143d85ac9b..78852bc645 100644 --- a/src/backends/reference/test/RefEndToEndTests.cpp +++ b/src/backends/reference/test/RefEndToEndTests.cpp @@ -1404,11 +1404,21 @@ TEST_CASE("RefResizeNearestNeighborEndToEndInt16NhwcTest") ResizeNearestNeighborEndToEnd(defaultBackends, armnn::DataLayout::NHWC); } +TEST_CASE("RefResizeNearestNeighborEndToEndFloatAlignCornersNhwcTest") +{ + ResizeNearestNeighborEndToEnd(defaultBackends, armnn::DataLayout::NHWC, true, false); +} + TEST_CASE("RefResizeNearestNeighborEndToEndFloatHalfPixelNhwcTest") { ResizeNearestNeighborEndToEnd(defaultBackends, armnn::DataLayout::NHWC, false, true); } +TEST_CASE("RefResizeNearestNeighborEndToEndInt8AlignCornersNhwcTest") +{ + ResizeNearestNeighborEndToEnd(defaultBackends, armnn::DataLayout::NHWC, true, false); +} + TEST_CASE("RefResizeNearestNeighborEndToEndInt8HalfPixelNhwcTest") { ResizeNearestNeighborEndToEnd(defaultBackends, armnn::DataLayout::NHWC, false, true); diff --git a/src/backends/reference/workloads/Resize.cpp b/src/backends/reference/workloads/Resize.cpp index b8bf1bceae..e80a2057e0 100644 --- a/src/backends/reference/workloads/Resize.cpp +++ b/src/backends/reference/workloads/Resize.cpp @@ -8,15 +8,13 @@ #include "TensorBufferArrayView.hpp" #include +#include #include #include using namespace armnnUtils; -namespace armnn -{ - namespace { @@ -62,12 +60,14 @@ inline float PixelScaler(const unsigned int& Pixel, }// anonymous namespace +namespace armnn +{ void Resize(Decoder& in, const TensorInfo& inputInfo, Encoder& out, const TensorInfo& outputInfo, DataLayoutIndexed dataLayout, - armnn::ResizeMethod resizeMethod, + ResizeMethod resizeMethod, bool alignCorners, bool halfPixelCenters) { @@ -91,8 +91,8 @@ void Resize(Decoder& in, const float scaleY = CalculateResizeScale(inputHeight, outputHeight, alignCorners); const float scaleX = CalculateResizeScale(inputWidth, outputWidth, alignCorners); - TensorShape inputShape = inputInfo.GetShape(); - TensorShape outputShape = outputInfo.GetShape(); + const TensorShape& inputShape = inputInfo.GetShape(); + const TensorShape& outputShape = outputInfo.GetShape(); for (unsigned int n = 0; n < batchSize; ++n) { @@ -104,8 +104,8 @@ void Resize(Decoder& in, float iy = PixelScaler(y, scaleY, halfPixelCenters, resizeMethod); // Discrete height coordinate of top-left texel (in the 2x2 texel area used for interpolation). - const float fiy = (resizeMethod == armnn::ResizeMethod::NearestNeighbor && alignCorners) ? - roundf(iy) : floorf(iy); + const float fiy = (resizeMethod == ResizeMethod::NearestNeighbor && alignCorners) ? armnn::roundf(iy) + : floorf(iy); // Pixel scaling a value with Half Pixel Centers can be negative, if so set to 0 const unsigned int y0 = static_cast(std::max(fiy, 0.0f)); @@ -118,8 +118,8 @@ void Resize(Decoder& in, float ix = PixelScaler(x, scaleX, halfPixelCenters, resizeMethod); // Nearest Neighbour uses rounding to align to corners - const float fix = resizeMethod == armnn::ResizeMethod::NearestNeighbor && alignCorners ? - roundf(ix) : floorf(ix); + const float fix = resizeMethod == ResizeMethod::NearestNeighbor && alignCorners ? armnn::roundf(ix) + : floorf(ix); // Pixel scaling a value with Half Pixel Centers can be negative, if so set to 0 const unsigned int x0 = static_cast(std::max(fix, 0.0f)); @@ -144,7 +144,7 @@ void Resize(Decoder& in, float interpolatedValue; switch (resizeMethod) { - case armnn::ResizeMethod::Bilinear: + case ResizeMethod::Bilinear: { in[dataLayout.GetIndex(inputShape, n, c, y0, x0)]; float input1 = in.Get(); @@ -160,7 +160,7 @@ void Resize(Decoder& in, interpolatedValue = Lerp(ly0, ly1, yw); break; } - case armnn::ResizeMethod::NearestNeighbor: + case ResizeMethod::NearestNeighbor: { // calculate euclidean distance to the 4 neighbours auto distance00 = EuclideanDistance(fix, fiy, x0, y0); @@ -195,7 +195,7 @@ void Resize(Decoder& in, } else { - throw armnn::InvalidArgumentException("Resize Nearest Neighbor failure"); + throw InvalidArgumentException("Resize Nearest Neighbor failure"); } in[dataLayout.GetIndex(inputShape, n, c, yNearest, xNearest)]; @@ -203,8 +203,8 @@ void Resize(Decoder& in, break; } default: - throw armnn::InvalidArgumentException("Unknown resize method: " + - std::to_string(static_cast(resizeMethod))); + throw InvalidArgumentException("Unknown resize method: " + + std::to_string(static_cast(resizeMethod))); } out[dataLayout.GetIndex(outputShape, n, c, y, x)]; out.Set(interpolatedValue); -- cgit v1.2.1