From 262553e0d4e2571c8d7b3c57a7271c23a783e04b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89anna=20=C3=93=20Cath=C3=A1in?= Date: Wed, 14 Nov 2018 11:26:23 +0000 Subject: IVGCVSW-2054: Fixing issue with InferOutputShape implementation in BatchToSpaceNdLayer. * added Unit test Change-Id: I80f55e8c7afb39d96006c8dd027fc9683ea8182e --- CMakeLists.txt | 1 + include/armnn/Descriptors.hpp | 3 +- src/armnn/layers/BatchToSpaceNdLayer.cpp | 35 ++++++++++++++++++-- src/armnn/test/LayerValidateOutputTest.cpp | 38 ++++++++++++++++++++++ src/backends/backendsCommon/test/LayerTests.cpp | 16 +++++++++ src/backends/backendsCommon/test/LayerTests.hpp | 2 ++ src/backends/reference/test/RefLayerTests.cpp | 2 ++ .../workloads/RefBatchToSpaceNdUint8Workload.cpp | 3 +- 8 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 src/armnn/test/LayerValidateOutputTest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 95ca39fb1b..0fa1907190 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -350,6 +350,7 @@ if(BUILD_UNIT_TESTS) src/armnn/test/GraphTests.cpp src/armnn/test/GraphUtils.hpp src/armnn/test/InstrumentTests.cpp + src/armnn/test/LayerValidateOutputTest.cpp src/armnn/test/NetworkTests.cpp src/armnn/test/ObservableTest.cpp src/armnn/test/OptimizerTests.cpp diff --git a/include/armnn/Descriptors.hpp b/include/armnn/Descriptors.hpp index 32ac959808..396e427ee4 100644 --- a/include/armnn/Descriptors.hpp +++ b/include/armnn/Descriptors.hpp @@ -299,8 +299,7 @@ struct BatchNormalizationDescriptor struct BatchToSpaceNdDescriptor { BatchToSpaceNdDescriptor() - : m_BlockShape({0, 0}) - , m_Crops({{0, 0}, {0, 0}}) + : m_Crops({{0, 0}, {0, 0}}) , m_DataLayout(DataLayout::NCHW) {} diff --git a/src/armnn/layers/BatchToSpaceNdLayer.cpp b/src/armnn/layers/BatchToSpaceNdLayer.cpp index 9366a8710b..aff818e664 100644 --- a/src/armnn/layers/BatchToSpaceNdLayer.cpp +++ b/src/armnn/layers/BatchToSpaceNdLayer.cpp @@ -66,10 +66,41 @@ std::vector BatchToSpaceNdLayer::InferOutputShapes(const std::vecto std::pair xCrops = crops[1]; unsigned int inputHeight = inputShape[dataLayout.GetHeightIndex()]; - unsigned int outputHeight = theBlockShape.at(0) * (inputHeight - (yCrops.first + yCrops.second)); + unsigned int outputHeight; + unsigned int yCropsTotal = yCrops.first + yCrops.second; + + BOOST_ASSERT_MSG(yCropsTotal <= inputHeight, + "BatchToSpaceLayer: Overall height crop should be less than or equal to the input height."); + + unsigned int croppedHeight = inputHeight - yCropsTotal; + + if (theBlockShape.at(0) > 0) + { + outputHeight = theBlockShape.at(0) * croppedHeight; + } + else + { + outputHeight = croppedHeight; + } + + unsigned int outputWidth; unsigned int inputWidth = inputShape[dataLayout.GetWidthIndex()]; - unsigned int outputWidth = theBlockShape.at(1) * (inputWidth - (xCrops.first + xCrops.second)); + + unsigned int xCropsTotal = xCrops.first + xCrops.second; + + BOOST_ASSERT_MSG(xCropsTotal <= inputWidth, + "BatchToSpaceLayer: Overall width crop should be less than or equal to the input width."); + unsigned int croppedWidth = inputWidth - xCropsTotal; + + if (theBlockShape.at(1) > 0) + { + outputWidth = theBlockShape.at(1) * croppedWidth; + } + else + { + outputWidth = croppedWidth; + } unsigned int outputBatchSize = overallSize / (outputHeight * outputWidth); diff --git a/src/armnn/test/LayerValidateOutputTest.cpp b/src/armnn/test/LayerValidateOutputTest.cpp new file mode 100644 index 0000000000..62b9c4a0d8 --- /dev/null +++ b/src/armnn/test/LayerValidateOutputTest.cpp @@ -0,0 +1,38 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#include + +#include +#include +#include +#include + + +BOOST_AUTO_TEST_SUITE(LayerValidateOutput) + +BOOST_AUTO_TEST_CASE(TestBatchToSpaceInferOutputShape) +{ + armnn::Graph graph; + + armnn::BatchToSpaceNdDescriptor descriptor; + std::vector theBlockShape = {2, 2}; + descriptor.m_BlockShape = theBlockShape; + descriptor.m_DataLayout = armnn::DataLayout::NHWC; + + armnn::BatchToSpaceNdLayer* const batchToSpaceLayer = + graph.AddLayer(descriptor, "batchToSpace"); + + std::vector shapes; + const std::vector theDimSizes = {4, 2, 2, 1}; + armnn::TensorShape shape(4, theDimSizes.data()); + shapes.push_back(shape); + + const std::vector expectedDimSizes = {1, 4, 4, 1}; + armnn::TensorShape expectedShape(4, expectedDimSizes.data()); + + BOOST_CHECK(expectedShape == batchToSpaceLayer->InferOutputShapes(shapes).at(0)); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/src/backends/backendsCommon/test/LayerTests.cpp b/src/backends/backendsCommon/test/LayerTests.cpp index 2556a3e1f5..1ce69142df 100755 --- a/src/backends/backendsCommon/test/LayerTests.cpp +++ b/src/backends/backendsCommon/test/LayerTests.cpp @@ -6113,3 +6113,19 @@ LayerTestResult BatchToSpaceNdNchwFloat32Test1(armnn::IWorkloadFactory return BatchToSpaceNdHelper(workloadFactory, armnn::DataLayout::NCHW, inputShape, input, blockShape, crops, outputShape, expectedOutput); } + + +LayerTestResult BatchToSpaceNdNhwcUintTest1(armnn::IWorkloadFactory& workloadFactory) +{ + const unsigned int inputShape[] = {4, 2, 2, 1}; + const unsigned int outputShape[] = {1, 4, 4, 1}; + + std::vector input({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }); + std::vector expectedOutput({ 1, 5, 2, 6, 9, 13, 10, 14, 3, 7, 4, 8, 11, 15, 12, 16}); + + std::vector blockShape({2, 2}); + std::vector> crops = {{0, 0}, {0, 0}}; + + return BatchToSpaceNdHelper(workloadFactory, armnn::DataLayout::NHWC, inputShape, input, blockShape, + crops, outputShape, expectedOutput); +} \ No newline at end of file diff --git a/src/backends/backendsCommon/test/LayerTests.hpp b/src/backends/backendsCommon/test/LayerTests.hpp index 34d55832da..c38d84fac2 100644 --- a/src/backends/backendsCommon/test/LayerTests.hpp +++ b/src/backends/backendsCommon/test/LayerTests.hpp @@ -439,3 +439,5 @@ LayerTestResult BatchToSpaceNdNhwcFloat32Test2(armnn::IWorkloadFactory LayerTestResult BatchToSpaceNdNhwcFloat32Test3(armnn::IWorkloadFactory& workloadFactory); LayerTestResult BatchToSpaceNdNchwFloat32Test1(armnn::IWorkloadFactory &workloadFactory); + +LayerTestResult BatchToSpaceNdNhwcUintTest1(armnn::IWorkloadFactory &workloadFactory); \ No newline at end of file diff --git a/src/backends/reference/test/RefLayerTests.cpp b/src/backends/reference/test/RefLayerTests.cpp index 8bbf11bfad..4ff5cf2a2e 100644 --- a/src/backends/reference/test/RefLayerTests.cpp +++ b/src/backends/reference/test/RefLayerTests.cpp @@ -385,4 +385,6 @@ ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcFloat323, BatchToSpaceNdNhwcFloat32Test3) ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwFloat321, BatchToSpaceNdNchwFloat32Test1) +ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcUint1, BatchToSpaceNdNhwcUintTest1) + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/backends/reference/workloads/RefBatchToSpaceNdUint8Workload.cpp b/src/backends/reference/workloads/RefBatchToSpaceNdUint8Workload.cpp index a66bcd42de..e4e108edb1 100644 --- a/src/backends/reference/workloads/RefBatchToSpaceNdUint8Workload.cpp +++ b/src/backends/reference/workloads/RefBatchToSpaceNdUint8Workload.cpp @@ -18,11 +18,10 @@ void RefBatchToSpaceNdUint8Workload::Execute() const const TensorInfo& inputInfo = GetTensorInfo(m_Data.m_Inputs[0]); const TensorInfo& outputInfo = GetTensorInfo(m_Data.m_Outputs[0]); auto dequantizedInputData = Dequantize(GetInputTensorDataU8(0, m_Data), inputInfo); - float* outputData = GetOutputTensorDataFloat(0, m_Data); std::vector results(outputInfo.GetNumElements()); BatchToSpaceNd(m_Data.m_Parameters.m_DataLayout, inputInfo, outputInfo, m_Data.m_Parameters.m_BlockShape, - m_Data.m_Parameters.m_Crops, dequantizedInputData.data(), outputData); + m_Data.m_Parameters.m_Crops, dequantizedInputData.data(), results.data()); Quantize(GetOutputTensorDataU8(0, m_Data), results.data(), outputInfo); } -- cgit v1.2.1