From 0be43386864ad3f86ad6c569520c9374883776f7 Mon Sep 17 00:00:00 2001 From: Narumol Prangnawarat Date: Mon, 27 May 2019 11:29:59 +0100 Subject: IVGCVSW-2771 Add end to end tests for splitter on Cl, Neon, Ref Signed-off-by: Narumol Prangnawarat Change-Id: I44f8f1799f6182721751b1d117c9ada5b91f52e1 --- src/backends/backendsCommon/test/CMakeLists.txt | 1 + .../test/SplitterEndToEndTestImpl.hpp | 380 +++++++++++++++++++++ src/backends/cl/test/ClEndToEndTests.cpp | 41 +++ src/backends/neon/test/NeonEndToEndTests.cpp | 41 +++ src/backends/reference/test/RefEndToEndTests.cpp | 41 +++ 5 files changed, 504 insertions(+) create mode 100644 src/backends/backendsCommon/test/SplitterEndToEndTestImpl.hpp diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt index f91fd9cf31..8050a0ab63 100644 --- a/src/backends/backendsCommon/test/CMakeLists.txt +++ b/src/backends/backendsCommon/test/CMakeLists.txt @@ -44,6 +44,7 @@ list(APPEND armnnBackendsCommonUnitTests_sources ReshapeTestImpl.hpp RuntimeTestImpl.hpp SoftmaxTestImpl.hpp + SplitterEndToEndTestImpl.hpp SplitterTestImpl.hpp StridedSliceTestImpl.hpp TensorCopyUtils.cpp diff --git a/src/backends/backendsCommon/test/SplitterEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/SplitterEndToEndTestImpl.hpp new file mode 100644 index 0000000000..f9fbcf55cb --- /dev/null +++ b/src/backends/backendsCommon/test/SplitterEndToEndTestImpl.hpp @@ -0,0 +1,380 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include + +#include + +#include + +#include + +#include + +namespace +{ + +template +INetworkPtr CreateSplitterNetwork(const TensorShape& inputShape, + const std::vector& outputShapes, + unsigned int splitAxis, + unsigned int numSplit, + 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); + + std::vector splitterDimSizes(inputShape.GetNumDimensions()); + + // Add current input shape to splitterDimSizes + for (unsigned int i = 0; i < inputShape.GetNumDimensions(); ++i) + { + splitterDimSizes[i] = inputTensorInfo.GetShape()[i]; + } + + if (splitterDimSizes[splitAxis] % numSplit != 0) + { + throw ParseException("Number of splits must evenly divide the dimension"); + } + splitterDimSizes[splitAxis] /= numSplit; + + SplitterDescriptor splitDesc(numSplit); + for (unsigned int g = 0; g < numSplit; ++g) + { + // Set the size of the views. + for (unsigned int dimIdx = 0; dimIdx < splitterDimSizes.size(); ++dimIdx) + { + splitDesc.SetViewSize(g, dimIdx, splitterDimSizes[dimIdx]); + } + splitDesc.SetViewOriginCoord(g, splitAxis, splitterDimSizes[splitAxis] * g); + } + + IConnectableLayer* splitter = net->AddSplitterLayer(splitDesc, "splitter"); + IConnectableLayer* input = net->AddInputLayer(0, "input"); + Connect(input, splitter, inputTensorInfo, 0, 0); + + for (unsigned int i = 0; i < outputShapes.size(); ++i) + { + TensorInfo outputTensorInfo(outputShapes[i], DataType, qScale, qOffset); + IConnectableLayer* output = net->AddOutputLayer(boost::numeric_cast(i)); + Connect(splitter, output, outputTensorInfo, i, 0); + } + + return net; +} + +template +void SplitterDim0EndToEnd(const std::vector& backends) +{ + using namespace armnn; + using T = ResolveType; + + unsigned int splitAxis = 0; + unsigned int numSplit = 2; + const TensorShape& inputShape = { 4, 3, 2, 2 }; + const std::vector outputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }}; + + // Builds up the structure of the network + INetworkPtr net = CreateSplitterNetwork(inputShape, outputShapes, splitAxis, numSplit); + + BOOST_TEST_CHECKPOINT("create a network"); + + // Creates structures for input & output. + std::vector inputData{ + 1, 2, + 3, 4, + 5, 6, + 7, 8, + 9, 10, + 11, 12, + 13, 14, + 15, 16, + 17, 18, + 19, 20, + 21, 22, + 23, 24, + 25, 26, + 27, 28, + 29, 30, + 31, 32, + 33, 34, + 35, 36, + 37, 38, + 39, 40, + 41, 42, + 43, 44, + 45, 46, + 47, 48 + }; + + std::vector expectedOutput0{ + 1, 2, + 3, 4, + 5, 6, + 7, 8, + 9, 10, + 11, 12, + 13, 14, + 15, 16, + 17, 18, + 19, 20, + 21, 22, + 23, 24 + }; + + std::vector expectedOutput1{ + 25, 26, + 27, 28, + 29, 30, + 31, 32, + 33, 34, + 35, 36, + 37, 38, + 39, 40, + 41, 42, + 43, 44, + 45, 46, + 47, 48 + }; + + std::map> inputTensorData = {{ 0,inputData }}; + std::map> expectedOutputData = {{ 0, expectedOutput0 }, { 1, expectedOutput1 }}; + + EndToEndLayerTestImpl(move(net), inputTensorData, expectedOutputData, backends); +} + +template +void SplitterDim1EndToEnd(const std::vector& backends) +{ + using namespace armnn; + using T = ResolveType; + + unsigned int splitAxis = 1; + unsigned int numSplit = 2; + const TensorShape& inputShape = { 2, 6, 2, 2 }; + const std::vector outputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }}; + + // Builds up the structure of the network + INetworkPtr net = CreateSplitterNetwork(inputShape, outputShapes, splitAxis, numSplit); + + BOOST_TEST_CHECKPOINT("create a network"); + + // Creates structures for input & output. + std::vector inputData{ + 1, 2, + 3, 4, + 5, 6, + 7, 8, + 9, 10, + 11, 12, + 13, 14, + 15, 16, + 17, 18, + 19, 20, + 21, 22, + 23, 24, + 25, 26, + 27, 28, + 29, 30, + 31, 32, + 33, 34, + 35, 36, + 37, 38, + 39, 40, + 41, 42, + 43, 44, + 45, 46, + 47, 48 + }; + + std::vector expectedOutput0{ + 1, 2, + 3, 4, + 5, 6, + 7, 8, + 9, 10, + 11, 12, + 25, 26, + 27, 28, + 29, 30, + 31, 32, + 33, 34, + 35, 36 + }; + + std::vector expectedOutput1{ + 13, 14, + 15, 16, + 17, 18, + 19, 20, + 21, 22, + 23, 24, + 37, 38, + 39, 40, + 41, 42, + 43, 44, + 45, 46, + 47, 48 + }; + + std::map> inputTensorData = {{ 0,inputData }}; + std::map> expectedOutputData = {{ 0, expectedOutput0 }, { 1, expectedOutput1 }}; + + EndToEndLayerTestImpl(move(net), inputTensorData, expectedOutputData, backends); +} + +template +void SplitterDim2EndToEnd(const std::vector& backends) +{ + using namespace armnn; + using T = ResolveType; + + unsigned int splitAxis = 2; + unsigned int numSplit = 2; + const TensorShape& inputShape = { 2, 3, 4, 2 }; + const std::vector outputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }}; + + // Builds up the structure of the network + INetworkPtr net = CreateSplitterNetwork(inputShape, outputShapes, splitAxis, numSplit); + + BOOST_TEST_CHECKPOINT("create a network"); + + // Creates structures for input & output. + std::vector inputData{ + 1, 2, + 3, 4, + 5, 6, + 7, 8, + 9, 10, + 11, 12, + 13, 14, + 15, 16, + 17, 18, + 19, 20, + 21, 22, + 23, 24, + 25, 26, + 27, 28, + 29, 30, + 31, 32, + 33, 34, + 35, 36, + 37, 38, + 39, 40, + 41, 42, + 43, 44, + 45, 46, + 47, 48 + }; + + std::vector expectedOutput0{ + 1, 2, + 3, 4, + 9, 10, + 11, 12, + 17, 18, + 19, 20, + 25, 26, + 27, 28, + 33, 34, + 35, 36, + 41, 42, + 43, 44 + }; + + std::vector expectedOutput1{ + 5, 6, + 7, 8, + 13, 14, + 15, 16, + 21, 22, + 23, 24, + 29, 30, + 31, 32, + 37, 38, + 39, 40, + 45, 46, + 47, 48 + }; + + std::map> inputTensorData = {{ 0,inputData }}; + std::map> expectedOutputData = {{ 0, expectedOutput0 }, { 1, expectedOutput1 }}; + + EndToEndLayerTestImpl(move(net), inputTensorData, expectedOutputData, backends); +} + +template> +void SplitterDim3EndToEnd(const std::vector& backends) +{ + using namespace armnn; + + unsigned int splitAxis = 3; + unsigned int numSplit = 2; + const TensorShape& inputShape = { 2, 3, 4, 2 }; + const std::vector outputShapes{{ 2, 3, 4, 1 }, { 2, 3, 4, 1 }}; + + // Builds up the structure of the network + INetworkPtr net = CreateSplitterNetwork(inputShape, outputShapes, splitAxis, numSplit); + + BOOST_TEST_CHECKPOINT("create a network"); + + // Creates structures for input & output. + std::vector inputData{ + 1, 2, + 3, 4, + 5, 6, + 7, 8, + 9, 10, + 11, 12, + 13, 14, + 15, 16, + 17, 18, + 19, 20, + 21, 22, + 23, 24, + 25, 26, + 27, 28, + 29, 30, + 31, 32, + 33, 34, + 35, 36, + 37, 38, + 39, 40, + 41, 42, + 43, 44, + 45, 46, + 47, 48 + }; + + std::vector expectedOutput0{ + 1, 3, 5, 7, + 9, 11, 13, 15, + 17, 19, 21, 23, + 25, 27, 29, 31, + 33, 35, 37, 39, + 41, 43, 45, 47 + }; + + std::vector expectedOutput1{ + 2, 4, 6, 8, + 10, 12, 14, 16, + 18, 20, 22, 24, + 26, 28, 30, 32, + 34, 36, 38, 40, + 42, 44, 46, 48 + }; + + std::map> inputTensorData = {{ 0,inputData }}; + std::map> expectedOutputData = {{ 0, expectedOutput0 }, { 1, expectedOutput1 }}; + + EndToEndLayerTestImpl(move(net), inputTensorData, expectedOutputData, backends); +} + +} // anonymous namespace diff --git a/src/backends/cl/test/ClEndToEndTests.cpp b/src/backends/cl/test/ClEndToEndTests.cpp index bc0bad2fa6..9c010fccad 100644 --- a/src/backends/cl/test/ClEndToEndTests.cpp +++ b/src/backends/cl/test/ClEndToEndTests.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -88,5 +89,45 @@ BOOST_AUTO_TEST_CASE(ClGreaterBroadcastEndToEndUint8Test) expectedOutput); } +BOOST_AUTO_TEST_CASE(ClSplitDim0EndToEndTest) +{ + SplitterDim0EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(ClSplitDim1EndToEndTest) +{ + SplitterDim1EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(ClSplitDim2EndToEndTest) +{ + SplitterDim2EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(ClSplitDim3EndToEndTest) +{ + SplitterDim3EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(ClSplitDim0EndToEndUint8Test) +{ + SplitterDim0EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(ClSplitDim1EndToEndUint8Test) +{ + SplitterDim1EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(ClSplitDim2EndToEndUint8Test) +{ + SplitterDim2EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(ClSplitDim3EndToEndUint8Test) +{ + SplitterDim3EndToEnd(defaultBackends); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/backends/neon/test/NeonEndToEndTests.cpp b/src/backends/neon/test/NeonEndToEndTests.cpp index deaa8eb81b..441efed9a9 100644 --- a/src/backends/neon/test/NeonEndToEndTests.cpp +++ b/src/backends/neon/test/NeonEndToEndTests.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -122,4 +123,44 @@ BOOST_AUTO_TEST_CASE(NeonMergerEndToEndDim3Uint8Test) MergerDim3EndToEnd(defaultBackends); } +BOOST_AUTO_TEST_CASE(NeonSplitDim0EndToEndTest) +{ + SplitterDim0EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(NeonSplitDim1EndToEndTest) +{ + SplitterDim1EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(NeonSplitDim2EndToEndTest) +{ + SplitterDim2EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(NeonSplitDim3EndToEndTest) +{ + SplitterDim3EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(NeonSplitDim0EndToEndUint8Test) +{ + SplitterDim0EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(NeonSplitDim1EndToEndUint8Test) +{ + SplitterDim1EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(NeonSplitDim2EndToEndUint8Test) +{ + SplitterDim2EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(NeonSplitDim3EndToEndUint8Test) +{ + SplitterDim3EndToEnd(defaultBackends); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/backends/reference/test/RefEndToEndTests.cpp b/src/backends/reference/test/RefEndToEndTests.cpp index c89e586f03..6dacfab4d1 100644 --- a/src/backends/reference/test/RefEndToEndTests.cpp +++ b/src/backends/reference/test/RefEndToEndTests.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -619,4 +620,44 @@ BOOST_AUTO_TEST_CASE(RefDetectionPostProcessFastNmsUint8Test) 1.0f, 1, 0.01f, 0, 0.5f, 0); } +BOOST_AUTO_TEST_CASE(RefSplitDim0EndToEndTest) +{ + SplitterDim0EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(RefSplitDim1EndToEndTest) +{ + SplitterDim1EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(RefSplitDim2EndToEndTest) +{ + SplitterDim2EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(RefSplitDim3EndToEndTest) +{ + SplitterDim3EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(RefSplitDim0EndToEndUint8Test) +{ + SplitterDim0EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(RefSplitDim1EndToEndUint8Test) +{ + SplitterDim1EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(RefSplitDim2EndToEndUint8Test) +{ + SplitterDim2EndToEnd(defaultBackends); +} + +BOOST_AUTO_TEST_CASE(RefSplitDim3EndToEndUint8Test) +{ + SplitterDim3EndToEnd(defaultBackends); +} + BOOST_AUTO_TEST_SUITE_END() -- cgit v1.2.1