ArmNN
 22.05
ConcatEndToEndTestImpl.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
7 #include <CommonTestUtils.hpp>
8 
9 #include <ResolveType.hpp>
10 
11 #include <armnn/INetwork.hpp>
12 
14 
15 #include <doctest/doctest.h>
16 
17 #include <vector>
18 
19 namespace
20 {
21 
22 template<typename armnn::DataType DataType>
23 INetworkPtr CreateConcatNetwork(const std::vector<TensorShape>& inputShapes,
24  const TensorShape &outputShape,
25  unsigned int concatAxis,
26  const float qScale = 1.0f,
27  const int32_t qOffset = 0)
28 {
29  using namespace armnn;
30  // Builds up the structure of the network.
32 
33  OriginsDescriptor descriptor;
34 
35  descriptor = CreateDescriptorForConcatenation(inputShapes.begin(),
36  inputShapes.end(),
37  concatAxis);
38  IConnectableLayer* concat = net->AddConcatLayer(descriptor, "concat");
39 
40  for (unsigned int i = 0; i < inputShapes.size(); ++i)
41  {
42  TensorInfo inputTensorInfo(inputShapes[i], DataType, qScale, qOffset, true);
43  IConnectableLayer* input = net->AddInputLayer(armnn::numeric_cast<LayerBindingId>(i));
44  Connect(input, concat, inputTensorInfo, 0, i);
45  }
46 
47  TensorInfo outputTensorInfo(outputShape, DataType, qScale, qOffset);
48  IConnectableLayer* output = net->AddOutputLayer(0, "output");
49  Connect(concat, output, outputTensorInfo, 0, 0);
50 
51  return net;
52 }
53 
54 template<armnn::DataType ArmnnType>
55 void ConcatDim0EndToEnd(const std::vector<BackendId>& backends)
56 {
57  using namespace armnn;
58  using T = ResolveType<ArmnnType>;
59 
60  unsigned int concatAxis = 0;
61  const std::vector<TensorShape> inputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }};
62  const TensorShape& outputShape = { 4, 3, 2, 2 };
63 
64  // Builds up the structure of the network
65  INetworkPtr net = CreateConcatNetwork<ArmnnType>(inputShapes, outputShape, concatAxis);
66 
67  CHECK(net);
68 
69  // Creates structures for input & output.
70  std::vector<T> inputData{
71  1, 2,
72  3, 4,
73  5, 6,
74  7, 8,
75  9, 10,
76  11, 12,
77  1, 2,
78  3, 4,
79  5, 6,
80  7, 8,
81  9, 10,
82  11, 12
83  };
84 
85  std::vector<T> expectedOutput{
86  1, 2,
87  3, 4,
88  5, 6,
89  7, 8,
90  9, 10,
91  11, 12,
92  1, 2,
93  3, 4,
94  5, 6,
95  7, 8,
96  9, 10,
97  11, 12,
98  1, 2,
99  3, 4,
100  5, 6,
101  7, 8,
102  9, 10,
103  11, 12,
104  1, 2,
105  3, 4,
106  5, 6,
107  7, 8,
108  9, 10,
109  11, 12
110  };
111 
112  std::map<int, std::vector<T>> inputTensorData = {{ 0,inputData }, { 1,inputData }};
113  std::map<int, std::vector<T>> expectedOutputData = {{ 0,expectedOutput }};
114 
115  EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
116 }
117 
118 template<armnn::DataType ArmnnType>
119 void ConcatDim1EndToEnd(const std::vector<BackendId>& backends)
120 {
121  using namespace armnn;
122  using T = ResolveType<ArmnnType>;
123 
124  unsigned int concatAxis = 1;
125  const std::vector<TensorShape> inputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }};
126  const TensorShape& outputShape = { 2, 6, 2, 2 };
127 
128  // Builds up the structure of the network
129  INetworkPtr net = CreateConcatNetwork<ArmnnType>(inputShapes, outputShape, concatAxis);
130 
131  // Creates structures for input & output.
132  std::vector<T> inputData{
133  1, 2,
134  3, 4,
135  5, 6,
136  7, 8,
137  9, 10,
138  11, 12,
139  1, 2,
140  3, 4,
141  5, 6,
142  7, 8,
143  9, 10,
144  11, 12
145  };
146 
147  std::vector<T> expectedOutput{
148  1, 2,
149  3, 4,
150  5, 6,
151  7, 8,
152  9, 10,
153  11, 12,
154  1, 2,
155  3, 4,
156  5, 6,
157  7, 8,
158  9, 10,
159  11, 12,
160  1, 2,
161  3, 4,
162  5, 6,
163  7, 8,
164  9, 10,
165  11, 12,
166  1, 2,
167  3, 4,
168  5, 6,
169  7, 8,
170  9, 10,
171  11, 12
172  };
173 
174  std::map<int, std::vector<T>> inputTensorData = {{ 0,inputData }, { 1,inputData }};
175  std::map<int, std::vector<T>> expectedOutputData = {{ 0,expectedOutput }};
176 
177  EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
178 }
179 
180 template<armnn::DataType ArmnnType>
181 void ConcatDim2EndToEnd(const std::vector<BackendId>& backends)
182 {
183  using namespace armnn;
184  using T = ResolveType<ArmnnType>;
185 
186  unsigned int concatAxis = 2;
187  const std::vector<TensorShape> inputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }};
188  const TensorShape& outputShape = { 2, 3, 4, 2 };
189 
190  // Builds up the structure of the network
191  INetworkPtr net = CreateConcatNetwork<ArmnnType>(inputShapes, outputShape, concatAxis);
192 
193  // Creates structures for input & output.
194  std::vector<T> inputData{
195  1, 2,
196  3, 4,
197  5, 6,
198  7, 8,
199  9, 10,
200  11, 12,
201  1, 2,
202  3, 4,
203  5, 6,
204  7, 8,
205  9, 10,
206  11, 12
207  };
208 
209  std::vector<T> expectedOutput{
210  1, 2,
211  3, 4,
212  1, 2,
213  3, 4,
214  5, 6,
215  7, 8,
216  5, 6,
217  7, 8,
218  9, 10,
219  11, 12,
220  9, 10,
221  11, 12,
222  1, 2,
223  3, 4,
224  1, 2,
225  3, 4,
226  5, 6,
227  7, 8,
228  5, 6,
229  7, 8,
230  9, 10,
231  11, 12,
232  9, 10,
233  11, 12
234  };
235 
236  std::map<int, std::vector<T>> inputTensorData = {{ 0,inputData }, { 1,inputData }};
237  std::map<int, std::vector<T>> expectedOutputData = {{ 0,expectedOutput }};
238 
239  EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
240 }
241 
242 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
243 void ConcatDim3EndToEnd(const std::vector<BackendId>& backends)
244 {
245  using namespace armnn;
246 
247  unsigned int concatAxis = 3;
248  const std::vector<TensorShape> inputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }};
249  const TensorShape& outputShape = { 2, 3, 2, 4 };
250 
251  // Builds up the structure of the network
252  INetworkPtr net = CreateConcatNetwork<ArmnnType>(inputShapes, outputShape, concatAxis);
253 
254  // Creates structures for input & output.
255  std::vector<T> inputData{
256  1, 2,
257  3, 4,
258  5, 6,
259  7, 8,
260  9, 10,
261  11, 12,
262  1, 2,
263  3, 4,
264  5, 6,
265  7, 8,
266  9, 10,
267  11, 12
268  };
269 
270  std::vector<T> expectedOutput{
271  1, 2,
272  1, 2,
273  3, 4,
274  3, 4,
275  5, 6,
276  5, 6,
277  7, 8,
278  7, 8,
279  9, 10,
280  9, 10,
281  11, 12,
282  11, 12,
283  1, 2,
284  1, 2,
285  3, 4,
286  3, 4,
287  5, 6,
288  5, 6,
289  7, 8,
290  7, 8,
291  9, 10,
292  9, 10,
293  11, 12,
294  11, 12
295  };
296 
297  std::map<int, std::vector<T>> inputTensorData = {{ 0,inputData }, { 1,inputData }};
298  std::map<int, std::vector<T>> expectedOutputData = {{ 0,expectedOutput }};
299 
300  EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
301 }
302 
303 } // anonymous namespace
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:66
typename ResolveTypeImpl< DT >::Type ResolveType
Definition: ResolveType.hpp:79
Copyright (c) 2021 ARM Limited and Contributors.
DataType
Definition: Types.hpp:48
An OriginsDescriptor for the ConcatLayer.
void Connect(armnn::IConnectableLayer *from, armnn::IConnectableLayer *to, const armnn::TensorInfo &tensorInfo, unsigned int fromIndex, unsigned int toIndex)
Definition: TestUtils.cpp:14
OriginsDescriptor CreateDescriptorForConcatenation(TensorShapeIt first, TensorShapeIt last, unsigned int concatenationDimension)
Convenience template to create an OriginsDescriptor to use when creating a ConcatLayer for performing...
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
Definition: INetwork.hpp:241
static INetworkPtr Create(NetworkOptions networkOptions={})
Definition: Network.cpp:476