blob: 8eb1c9735091a0ac9bca8b43697159dd67dd73f0 [file] [log] [blame]
Aron Virginas-Tarf97f6da2019-10-01 18:35:44 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "SpaceToDepthEndToEndTestImpl.hpp"
7
8#include "ResolveType.hpp"
9#include "DataLayoutIndexed.hpp"
10#include "EndToEndTestImpl.hpp"
11
12#include <Permute.hpp>
13
14#include <armnn/INetwork.hpp>
15
16#include <backendsCommon/test/DataLayoutUtils.hpp>
17
18#include <test/TestUtils.hpp>
19
20#include <boost/test/unit_test.hpp>
21
22namespace
23{
24
25template<typename armnn::DataType DataType>
26armnn::INetworkPtr CreateSpaceToDepthNetwork(const armnn::TensorShape& inputShape,
27 const armnn::TensorShape& outputShape,
28 const armnn::DataLayout dataLayout,
29 unsigned int blockSize,
30 const float qScale = 1.0f,
31 const int32_t qOffset = 0)
32{
33 using namespace armnn;
34
35 // Builds up the structure of the network.
36 INetworkPtr net(INetwork::Create());
37
38 TensorInfo inputTensorInfo(inputShape, DataType, qScale, qOffset);
39
40 armnnUtils::DataLayoutIndexed dimensionIndices(dataLayout);
41 if (inputShape[dimensionIndices.GetHeightIndex()] % blockSize!=0
42 || inputShape[dimensionIndices.GetWidthIndex()] % blockSize!=0)
43 {
44 throw InvalidArgumentException("Input shape must be divisible by block size in all spatial dimensions");
45 }
46
47 SpaceToDepthDescriptor spaceToDepthDesc;
48 spaceToDepthDesc.m_BlockSize = blockSize;
49 spaceToDepthDesc.m_DataLayout = dataLayout;
50
51 IConnectableLayer* SpaceToDepth = net->AddSpaceToDepthLayer(spaceToDepthDesc, "SpaceToDepth");
52 IConnectableLayer* input = net->AddInputLayer(0, "input");
53 Connect(input, SpaceToDepth, inputTensorInfo, 0, 0);
54
55 TensorInfo outputTensorInfo(outputShape, DataType, qScale, qOffset);
56 IConnectableLayer* output = net->AddOutputLayer(0, "output");
57 Connect(SpaceToDepth, output, outputTensorInfo, 0, 0);
58
59 return net;
60}
61
62void SpaceToDepthEndToEnd(const std::vector<armnn::BackendId>& backends,
63 const armnn::DataLayout& dataLayout,
64 armnn::TensorInfo& inputTensorInfo,
65 armnn::TensorInfo& outputTensorInfo,
66 std::vector<float>& inputData,
67 std::vector<float>& expectedOutputData,
68 const unsigned int blockSize)
69{
70 using namespace armnn;
71
72 if (dataLayout == DataLayout::NCHW)
73 {
74 PermuteTensorNhwcToNchw<float>(inputTensorInfo, inputData);
75 PermuteTensorNhwcToNchw<float>(outputTensorInfo, expectedOutputData);
76 }
77
78 // Builds up the structure of the network
79 INetworkPtr net = CreateSpaceToDepthNetwork<DataType::Float32>(
80 inputTensorInfo.GetShape(),
81 outputTensorInfo.GetShape(),
82 dataLayout,
83 blockSize);
84
85 BOOST_TEST_CHECKPOINT("Create a network");
86
87 std::map<int, std::vector<float>> inputTensorData = { { 0, inputData } };
88 std::map<int, std::vector<float>> expectedOutputTensorData = { { 0, expectedOutputData } };
89
90 EndToEndLayerTestImpl<DataType::Float32, DataType::Float32>(
91 move(net),
92 inputTensorData,
93 expectedOutputTensorData,
94 backends);
95}
96
97} // anonymous namespace
98
99void SpaceToDepthNhwcEndToEndTest1(const std::vector<armnn::BackendId>& defaultBackends)
100{
101 using namespace armnn;
102
103 const unsigned int blockSize = 2;
104
105 TensorShape inputShape{1, 2, 2, 1};
106 TensorInfo inputTensorInfo(inputShape, DataType::Float32);
107
108 TensorShape outputShape{1, 1, 1, 4};
109 TensorInfo outputTensorInfo(outputShape, DataType::Float32);
110
111 std::vector<float> inputData = std::vector<float>(
112 {
113 1.0f, 2.0f, 3.0f, 4.0f
114 });
115
116 std::vector<float> expectedOutputData = std::vector<float>(
117 {
118 1.0f, 2.0f, 3.0f, 4.0f
119 });
120
121 SpaceToDepthEndToEnd(defaultBackends,
122 DataLayout::NHWC,
123 inputTensorInfo,
124 outputTensorInfo,
125 inputData,
126 expectedOutputData,
127 blockSize);
128}
129
130void SpaceToDepthNchwEndToEndTest1(const std::vector<armnn::BackendId>& defaultBackends)
131{
132 using namespace armnn;
133
134 const unsigned int blockSize = 2;
135
136 TensorShape inputShape{1, 2, 2, 1};
137 TensorInfo inputTensorInfo(inputShape, DataType::Float32);
138
139 TensorShape outputShape{1, 1, 1, 4};
140 TensorInfo outputTensorInfo(outputShape, DataType::Float32);
141
142 std::vector<float> inputData = std::vector<float>(
143 {
144 1.0f, 2.0f, 3.0f, 4.0f
145 });
146
147 std::vector<float> expectedOutputData = std::vector<float>(
148 {
149 1.0f, 2.0f, 3.0f, 4.0f
150 });
151
152 SpaceToDepthEndToEnd(defaultBackends,
153 DataLayout::NCHW,
154 inputTensorInfo,
155 outputTensorInfo,
156 inputData,
157 expectedOutputData,
158 blockSize);
159}
160
161void SpaceToDepthNhwcEndToEndTest2(const std::vector<armnn::BackendId>& defaultBackends)
162{
163 using namespace armnn;
164
165 const unsigned int blockSize = 2;
166
167 TensorShape inputShape{1, 2, 2, 2};
168 TensorShape outputShape{1, 1, 1, 8};
169
170 TensorInfo outputTensorInfo(outputShape, DataType::Float32);
171 TensorInfo inputTensorInfo(inputShape, DataType::Float32);
172
173 std::vector<float> inputData = std::vector<float>(
174 {
175 1.4f, 2.3f, 3.2f, 4.1f, 5.4f, 6.3f, 7.2f, 8.1f
176 });
177
178 std::vector<float> expectedOutputData = std::vector<float>(
179 {
180 1.4f, 2.3f, 3.2f, 4.1f, 5.4f, 6.3f, 7.2f, 8.1f
181 });
182
183 SpaceToDepthEndToEnd(defaultBackends,
184 DataLayout::NHWC,
185 inputTensorInfo,
186 outputTensorInfo,
187 inputData,
188 expectedOutputData,
189 blockSize);
190}
191
192void SpaceToDepthNchwEndToEndTest2(const std::vector<armnn::BackendId>& defaultBackends)
193{
194 using namespace armnn;
195
196 const unsigned int blockSize = 2;
197
198 TensorShape inputShape{1, 2, 2, 2};
199 TensorShape outputShape{1, 1, 1, 8};
200
201 TensorInfo inputTensorInfo(inputShape, DataType::Float32);
202 TensorInfo outputTensorInfo(outputShape, DataType::Float32);
203
204
205 std::vector<float> inputData = std::vector<float>(
206 {
207 1.4f, 2.3f, 3.2f, 4.1f, 5.4f, 6.3f, 7.2f, 8.1f
208 });
209
210 std::vector<float> expectedOutputData = std::vector<float>(
211 {
212 1.4f, 2.3f, 3.2f, 4.1f, 5.4f, 6.3f, 7.2f, 8.1f
213 });
214
215 SpaceToDepthEndToEnd(defaultBackends,
216 DataLayout::NCHW,
217 inputTensorInfo,
218 outputTensorInfo,
219 inputData,
220 expectedOutputData,
221 blockSize);
222}