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