blob: 456af4cbbb0e7d5add353a0590aab9bba064d03b [file] [log] [blame]
Keith Davis9515c7e2019-06-21 09:33:59 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5#pragma once
6
7#include "ResolveType.hpp"
8#include "DataLayoutIndexed.hpp"
9#include "EndToEndTestImpl.hpp"
10
11#include "armnn/INetwork.hpp"
12
13#include "backendsCommon/test/CommonTestUtils.hpp"
14
15#include <Permute.hpp>
16#include <boost/test/unit_test.hpp>
17
18#include <vector>
19
20namespace
21{
22template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
23void PermuteDataToNCHW(const std::vector<armnn::BackendId>& backends,
24 const armnn::DataLayout& dataLayout,
25 TensorInfo& tensorInfo,
26 std::vector<T>& data)
27{
28 const armnn::PermutationVector NHWCToNCHW = {0, 2, 3, 1};
29
30 tensorInfo = armnnUtils::Permuted(tensorInfo, NHWCToNCHW);
31
32 std::vector<T> tmp(data.size());
33 armnnUtils::Permute(tensorInfo.GetShape(), NHWCToNCHW, data.data(), tmp.data(), sizeof(T));
34
35 data = tmp;
36}
37
38template<typename armnn::DataType DataType>
39armnn::INetworkPtr CreateSpaceToDepthNetwork(const armnn::TensorShape& inputShape,
40 const armnn::TensorShape& outputShape,
41 const armnn::DataLayout dataLayout,
42 unsigned int blockSize,
43 const float qScale = 1.0f,
44 const int32_t qOffset = 0)
45{
46 using namespace armnn;
47 // Builds up the structure of the network.
48 INetworkPtr net(INetwork::Create());
49
50 TensorInfo inputTensorInfo(inputShape, DataType, qScale, qOffset);
51
52 armnnUtils::DataLayoutIndexed dimensionIndices(dataLayout);
53 if (inputShape[dimensionIndices.GetHeightIndex()] % blockSize!=0
54 || inputShape[dimensionIndices.GetWidthIndex()] % blockSize!=0)
55 {
56 throw InvalidArgumentException("Input shape must be divisible by block size in all spatial dimensions");
57 }
58
59 SpaceToDepthDescriptor spaceToDepthDesc;
60 spaceToDepthDesc.m_BlockSize = blockSize;
61 spaceToDepthDesc.m_DataLayout = dataLayout;
62
63 IConnectableLayer* SpaceToDepth = net->AddSpaceToDepthLayer(spaceToDepthDesc, "SpaceToDepth");
64 IConnectableLayer* input = net->AddInputLayer(0, "input");
65 Connect(input, SpaceToDepth, inputTensorInfo, 0, 0);
66
67 TensorInfo outputTensorInfo(outputShape, DataType, qScale, qOffset);
68 IConnectableLayer* output = net->AddOutputLayer(0, "output");
69 Connect(SpaceToDepth, output, outputTensorInfo, 0, 0);
70
71 return net;
72}
73
74void SpaceToDepthEndToEnd(const std::vector<armnn::BackendId>& backends,
75 const armnn::DataLayout& dataLayout,
76 TensorInfo& inputTensorInfo,
77 TensorInfo& outputTensorInfo,
78 std::vector<float>& inputData,
79 std::vector<float>& expectedOutputData,
80 const unsigned int blockSize)
81{
82 using namespace armnn;
83
84 if (dataLayout == armnn::DataLayout::NCHW){
85 PermuteDataToNCHW<armnn::DataType::Float32>(backends, dataLayout, inputTensorInfo, inputData);
86 PermuteDataToNCHW<armnn::DataType::Float32>(backends, dataLayout, outputTensorInfo, expectedOutputData);
87 }
88
89 // Builds up the structure of the network
90 INetworkPtr net = CreateSpaceToDepthNetwork<armnn::DataType::Float32>(inputTensorInfo.GetShape(),
91 outputTensorInfo.GetShape(),
92 dataLayout,
93 blockSize);
94
95 BOOST_TEST_CHECKPOINT("Create a network");
96
97 std::map<int, std::vector<float>> inputTensorData = { { 0, inputData } };
98 std::map<int, std::vector<float>> expectedOutputTensorData = { { 0, expectedOutputData } };
99
100 EndToEndLayerTestImpl<armnn::DataType::Float32, armnn::DataType::Float32>(move(net),
101 inputTensorData,
102 expectedOutputTensorData,
103 backends);
104}
105
106} // anonymous namespace