From 9515c7ec4f4535fff2c8f2d3f88974474d3f3468 Mon Sep 17 00:00:00 2001 From: Keith Davis Date: Fri, 21 Jun 2019 09:33:59 +0100 Subject: IVGCVSW-3263 - Add End to End tests for SpaceToDepth on Ref Change-Id: I35d1c06b34ca160895f902255a69b87b711275b7 Signed-off-by: Keith Davis --- src/backends/backendsCommon/test/CMakeLists.txt | 1 + .../test/SpaceToDepthEndToEndTestImpl.hpp | 106 ++++++++++++++++++ src/backends/reference/test/RefEndToEndTests.cpp | 118 +++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 src/backends/backendsCommon/test/SpaceToDepthEndToEndTestImpl.hpp (limited to 'src') diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt index 7819cfe056..caf2dd34b0 100644 --- a/src/backends/backendsCommon/test/CMakeLists.txt +++ b/src/backends/backendsCommon/test/CMakeLists.txt @@ -45,6 +45,7 @@ list(APPEND armnnBackendsCommonUnitTests_sources RuntimeTestImpl.hpp SoftmaxTestImpl.hpp SpaceToDepthTestImpl.hpp + SpaceToDepthEndToEndTestImpl.hpp SplitterEndToEndTestImpl.hpp SplitterTestImpl.hpp StridedSliceTestImpl.hpp diff --git a/src/backends/backendsCommon/test/SpaceToDepthEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/SpaceToDepthEndToEndTestImpl.hpp new file mode 100644 index 0000000000..456af4cbbb --- /dev/null +++ b/src/backends/backendsCommon/test/SpaceToDepthEndToEndTestImpl.hpp @@ -0,0 +1,106 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "ResolveType.hpp" +#include "DataLayoutIndexed.hpp" +#include "EndToEndTestImpl.hpp" + +#include "armnn/INetwork.hpp" + +#include "backendsCommon/test/CommonTestUtils.hpp" + +#include +#include + +#include + +namespace +{ +template> +void PermuteDataToNCHW(const std::vector& backends, + const armnn::DataLayout& dataLayout, + TensorInfo& tensorInfo, + std::vector& data) +{ + const armnn::PermutationVector NHWCToNCHW = {0, 2, 3, 1}; + + tensorInfo = armnnUtils::Permuted(tensorInfo, NHWCToNCHW); + + std::vector tmp(data.size()); + armnnUtils::Permute(tensorInfo.GetShape(), NHWCToNCHW, data.data(), tmp.data(), sizeof(T)); + + data = tmp; +} + +template +armnn::INetworkPtr CreateSpaceToDepthNetwork(const armnn::TensorShape& inputShape, + const armnn::TensorShape& outputShape, + const armnn::DataLayout dataLayout, + unsigned int blockSize, + const float qScale = 1.0f, + const int32_t qOffset = 0) +{ + using namespace armnn; + // Builds up the structure of the network. + INetworkPtr net(INetwork::Create()); + + TensorInfo inputTensorInfo(inputShape, DataType, qScale, qOffset); + + armnnUtils::DataLayoutIndexed dimensionIndices(dataLayout); + if (inputShape[dimensionIndices.GetHeightIndex()] % blockSize!=0 + || inputShape[dimensionIndices.GetWidthIndex()] % blockSize!=0) + { + throw InvalidArgumentException("Input shape must be divisible by block size in all spatial dimensions"); + } + + SpaceToDepthDescriptor spaceToDepthDesc; + spaceToDepthDesc.m_BlockSize = blockSize; + spaceToDepthDesc.m_DataLayout = dataLayout; + + IConnectableLayer* SpaceToDepth = net->AddSpaceToDepthLayer(spaceToDepthDesc, "SpaceToDepth"); + IConnectableLayer* input = net->AddInputLayer(0, "input"); + Connect(input, SpaceToDepth, inputTensorInfo, 0, 0); + + TensorInfo outputTensorInfo(outputShape, DataType, qScale, qOffset); + IConnectableLayer* output = net->AddOutputLayer(0, "output"); + Connect(SpaceToDepth, output, outputTensorInfo, 0, 0); + + return net; +} + +void SpaceToDepthEndToEnd(const std::vector& backends, + const armnn::DataLayout& dataLayout, + TensorInfo& inputTensorInfo, + TensorInfo& outputTensorInfo, + std::vector& inputData, + std::vector& expectedOutputData, + const unsigned int blockSize) +{ + using namespace armnn; + + if (dataLayout == armnn::DataLayout::NCHW){ + PermuteDataToNCHW(backends, dataLayout, inputTensorInfo, inputData); + PermuteDataToNCHW(backends, dataLayout, outputTensorInfo, expectedOutputData); + } + + // Builds up the structure of the network + INetworkPtr net = CreateSpaceToDepthNetwork(inputTensorInfo.GetShape(), + outputTensorInfo.GetShape(), + dataLayout, + blockSize); + + BOOST_TEST_CHECKPOINT("Create a network"); + + std::map> inputTensorData = { { 0, inputData } }; + std::map> expectedOutputTensorData = { { 0, expectedOutputData } }; + + EndToEndLayerTestImpl(move(net), + inputTensorData, + expectedOutputTensorData, + backends); +} + +} // anonymous namespace diff --git a/src/backends/reference/test/RefEndToEndTests.cpp b/src/backends/reference/test/RefEndToEndTests.cpp index 885773d5e9..be73116f65 100644 --- a/src/backends/reference/test/RefEndToEndTests.cpp +++ b/src/backends/reference/test/RefEndToEndTests.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -641,6 +642,123 @@ BOOST_AUTO_TEST_CASE(RefDetectionPostProcessFastNmsUint8Test) 1.0f, 1, 0.01f, 0, 0.5f, 0); } +BOOST_AUTO_TEST_CASE(RefSpaceToDepthNHWCEndToEndTest1) +{ + const unsigned int blockSize = 2; + + armnn::TensorShape inputShape{1, 2, 2, 1}; + armnn::TensorInfo inputTensorInfo(inputShape, armnn::DataType::Float32); + + armnn::TensorShape outputShape{1, 1, 1, 4}; + armnn::TensorInfo outputTensorInfo(outputShape, armnn::DataType::Float32); + + std::vector inputData = std::vector( + { + 1.0f, 2.0f, 3.0f, 4.0f + }); + + std::vector expectedOutputData = std::vector( + { + 1.0f, 2.0f, 3.0f, 4.0f + }); + + SpaceToDepthEndToEnd(defaultBackends, + armnn::DataLayout::NHWC, + inputTensorInfo, + outputTensorInfo, + inputData, + expectedOutputData, + blockSize); +} + +BOOST_AUTO_TEST_CASE(RefSpaceToDepthNCHWEndToEndTest1) +{ + const unsigned int blockSize = 2; + + armnn::TensorShape inputShape{1, 2, 2, 1}; + armnn::TensorInfo inputTensorInfo(inputShape, armnn::DataType::Float32); + + armnn::TensorShape outputShape{1, 1, 1, 4}; + armnn::TensorInfo outputTensorInfo(outputShape, armnn::DataType::Float32); + + std::vector inputData = std::vector( + { + 1.0f, 2.0f, 3.0f, 4.0f + }); + + std::vector expectedOutputData = std::vector( + { + 1.0f, 2.0f, 3.0f, 4.0f + }); + + SpaceToDepthEndToEnd(defaultBackends, + armnn::DataLayout::NCHW, + inputTensorInfo, + outputTensorInfo, + inputData, + expectedOutputData, + blockSize); +} + +BOOST_AUTO_TEST_CASE(RefSpaceToDepthNHWCEndToEndTest2) +{ + const unsigned int blockSize = 2; + + armnn::TensorShape inputShape{1, 2, 2, 2}; + armnn::TensorShape outputShape{1, 1, 1, 8}; + + armnn::TensorInfo outputTensorInfo(outputShape, armnn::DataType::Float32); + armnn::TensorInfo inputTensorInfo(inputShape, armnn::DataType::Float32); + + std::vector inputData = std::vector( + { + 1.4f, 2.3f, 3.2f, 4.1f, 5.4f, 6.3f, 7.2f, 8.1f + }); + + std::vector expectedOutputData = std::vector( + { + 1.4f, 2.3f, 3.2f, 4.1f, 5.4f, 6.3f, 7.2f, 8.1f + }); + + SpaceToDepthEndToEnd(defaultBackends, + armnn::DataLayout::NHWC, + inputTensorInfo, + outputTensorInfo, + inputData, + expectedOutputData, + blockSize); +} + +BOOST_AUTO_TEST_CASE(RefSpaceToDepthNCHWEndToEndTest2) +{ + const unsigned int blockSize = 2; + + armnn::TensorShape inputShape{1, 2, 2, 2}; + armnn::TensorShape outputShape{1, 1, 1, 8}; + + armnn::TensorInfo inputTensorInfo(inputShape, armnn::DataType::Float32); + armnn::TensorInfo outputTensorInfo(outputShape, armnn::DataType::Float32); + + + std::vector inputData = std::vector( + { + 1.4f, 2.3f, 3.2f, 4.1f, 5.4f, 6.3f, 7.2f, 8.1f + }); + + std::vector expectedOutputData = std::vector( + { + 1.4f, 2.3f, 3.2f, 4.1f, 5.4f, 6.3f, 7.2f, 8.1f + }); + + SpaceToDepthEndToEnd(defaultBackends, + armnn::DataLayout::NCHW, + inputTensorInfo, + outputTensorInfo, + inputData, + expectedOutputData, + blockSize); +} + BOOST_AUTO_TEST_CASE(RefSplitter1dEndToEndTest) { Splitter1dEndToEnd(defaultBackends); -- cgit v1.2.1