ArmNN
 21.11
SpaceToDepthEndToEndTestImpl.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
7 #include "ResolveType.hpp"
8 #include "EndToEndTestImpl.hpp"
9 
10 #include <armnn/INetwork.hpp>
11 
12 #include <armnnUtils/Permute.hpp>
14 
16 
17 #include <test/TestUtils.hpp>
18 
19 #include <doctest/doctest.h>
20 
21 namespace
22 {
23 
24 template<typename armnn::DataType DataType>
25 armnn::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.
36 
37  TensorInfo inputTensorInfo(inputShape, DataType, qScale, qOffset, true);
38 
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 
61 void 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 
84  CHECK(net);
85 
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>(
90  move(net),
91  inputTensorData,
92  expectedOutputTensorData,
93  backends);
94 }
95 
96 } // anonymous namespace
97 
98 void 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};
105  TensorInfo inputTensorInfo(inputShape, DataType::Float32, 0.0f, 0, true);
106 
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,
122  inputTensorInfo,
123  outputTensorInfo,
124  inputData,
125  expectedOutputData,
126  blockSize);
127 }
128 
129 void 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};
136  TensorInfo inputTensorInfo(inputShape, DataType::Float32, 0.0f, 0, true);
137 
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,
153  inputTensorInfo,
154  outputTensorInfo,
155  inputData,
156  expectedOutputData,
157  blockSize);
158 }
159 
160 void 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);
170  TensorInfo inputTensorInfo(inputShape, DataType::Float32, 0.0f, 0, true);
171 
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,
184  inputTensorInfo,
185  outputTensorInfo,
186  inputData,
187  expectedOutputData,
188  blockSize);
189 }
190 
191 void 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 
200  TensorInfo inputTensorInfo(inputShape, DataType::Float32, 0.0f, 0, true);
201  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,
216  inputTensorInfo,
217  outputTensorInfo,
218  inputData,
219  expectedOutputData,
220  blockSize);
221 }
void SpaceToDepthNchwEndToEndTest1(const std::vector< armnn::BackendId > &defaultBackends)
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:61
DataLayout
Definition: Types.hpp:49
const TensorShape & GetShape() const
Definition: Tensor.hpp:191
Copyright (c) 2021 ARM Limited and Contributors.
A SpaceToDepthDescriptor for the SpaceToDepthLayer.
void SpaceToDepthNhwcEndToEndTest2(const std::vector< armnn::BackendId > &defaultBackends)
void SpaceToDepthNhwcEndToEndTest1(const std::vector< armnn::BackendId > &defaultBackends)
void SpaceToDepthNchwEndToEndTest2(const std::vector< armnn::BackendId > &defaultBackends)
DataType
Definition: Types.hpp:35
Provides access to the appropriate indexes for Channels, Height and Width based on DataLayout...
unsigned int m_BlockSize
Scalar specifying the input block size. It must be >= 1.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
void SpaceToDepth(const TensorInfo &inputInfo, const TensorInfo &outputInfo, const SpaceToDepthDescriptor &params, Decoder< float > &inputData, Encoder< float > &outputData)
void Connect(armnn::IConnectableLayer *from, armnn::IConnectableLayer *to, const armnn::TensorInfo &tensorInfo, unsigned int fromIndex, unsigned int toIndex)
Definition: TestUtils.cpp:12
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
Definition: INetwork.hpp:197
static INetworkPtr Create(NetworkOptions networkOptions={})
Definition: Network.cpp:478