• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
13 #include <armnn/utility/NumericCast.hpp>
14 
15 #include <boost/test/unit_test.hpp>
16 
17 #include <vector>
18 
19 namespace
20 {
21 
22 template<typename armnn::DataType DataType>
CreateConcatNetwork(const std::vector<TensorShape> & inputShapes,const TensorShape & outputShape,unsigned int concatAxis,const float qScale=1.0f,const int32_t qOffset=0)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.
31     INetworkPtr net(INetwork::Create());
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);
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>
ConcatDim0EndToEnd(const std::vector<BackendId> & backends)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     BOOST_TEST_CHECKPOINT("create a network");
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>
ConcatDim1EndToEnd(const std::vector<BackendId> & backends)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     BOOST_TEST_CHECKPOINT("create a network");
132 
133     // Creates structures for input & output.
134     std::vector<T> inputData{
135         1, 2,
136         3, 4,
137         5, 6,
138         7, 8,
139         9, 10,
140         11, 12,
141         1, 2,
142         3, 4,
143         5, 6,
144         7, 8,
145         9, 10,
146         11, 12
147     };
148 
149     std::vector<T> expectedOutput{
150         1, 2,
151         3, 4,
152         5, 6,
153         7, 8,
154         9, 10,
155         11, 12,
156         1, 2,
157         3, 4,
158         5, 6,
159         7, 8,
160         9, 10,
161         11, 12,
162         1, 2,
163         3, 4,
164         5, 6,
165         7, 8,
166         9, 10,
167         11, 12,
168         1, 2,
169         3, 4,
170         5, 6,
171         7, 8,
172         9, 10,
173         11, 12
174     };
175 
176     std::map<int, std::vector<T>> inputTensorData = {{ 0,inputData }, { 1,inputData }};
177     std::map<int, std::vector<T>> expectedOutputData = {{ 0,expectedOutput }};
178 
179     EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
180 }
181 
182 template<armnn::DataType ArmnnType>
ConcatDim2EndToEnd(const std::vector<BackendId> & backends)183 void ConcatDim2EndToEnd(const std::vector<BackendId>& backends)
184 {
185     using namespace armnn;
186     using T = ResolveType<ArmnnType>;
187 
188     unsigned int concatAxis = 2;
189     const std::vector<TensorShape> inputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }};
190     const TensorShape& outputShape = { 2, 3, 4, 2 };
191 
192     // Builds up the structure of the network
193     INetworkPtr net = CreateConcatNetwork<ArmnnType>(inputShapes, outputShape, concatAxis);
194 
195     BOOST_TEST_CHECKPOINT("create a network");
196 
197     // Creates structures for input & output.
198     std::vector<T> inputData{
199         1, 2,
200         3, 4,
201         5, 6,
202         7, 8,
203         9, 10,
204         11, 12,
205         1, 2,
206         3, 4,
207         5, 6,
208         7, 8,
209         9, 10,
210         11, 12
211     };
212 
213     std::vector<T> expectedOutput{
214         1, 2,
215         3, 4,
216         1, 2,
217         3, 4,
218         5, 6,
219         7, 8,
220         5, 6,
221         7, 8,
222         9, 10,
223         11, 12,
224         9, 10,
225         11, 12,
226         1, 2,
227         3, 4,
228         1, 2,
229         3, 4,
230         5, 6,
231         7, 8,
232         5, 6,
233         7, 8,
234         9, 10,
235         11, 12,
236         9, 10,
237         11, 12
238     };
239 
240     std::map<int, std::vector<T>> inputTensorData = {{ 0,inputData }, { 1,inputData }};
241     std::map<int, std::vector<T>> expectedOutputData = {{ 0,expectedOutput }};
242 
243     EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
244 }
245 
246 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ConcatDim3EndToEnd(const std::vector<BackendId> & backends)247 void ConcatDim3EndToEnd(const std::vector<BackendId>& backends)
248 {
249     using namespace armnn;
250 
251     unsigned int concatAxis = 3;
252     const std::vector<TensorShape> inputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }};
253     const TensorShape& outputShape = { 2, 3, 2, 4 };
254 
255     // Builds up the structure of the network
256     INetworkPtr net = CreateConcatNetwork<ArmnnType>(inputShapes, outputShape, concatAxis);
257 
258     BOOST_TEST_CHECKPOINT("create a network");
259 
260     // Creates structures for input & output.
261     std::vector<T> inputData{
262         1, 2,
263         3, 4,
264         5, 6,
265         7, 8,
266         9, 10,
267         11, 12,
268         1, 2,
269         3, 4,
270         5, 6,
271         7, 8,
272         9, 10,
273         11, 12
274     };
275 
276     std::vector<T> expectedOutput{
277         1, 2,
278         1, 2,
279         3, 4,
280         3, 4,
281         5, 6,
282         5, 6,
283         7, 8,
284         7, 8,
285         9, 10,
286         9, 10,
287         11, 12,
288         11, 12,
289         1, 2,
290         1, 2,
291         3, 4,
292         3, 4,
293         5, 6,
294         5, 6,
295         7, 8,
296         7, 8,
297         9, 10,
298         9, 10,
299         11, 12,
300         11, 12
301     };
302 
303     std::map<int, std::vector<T>> inputTensorData = {{ 0,inputData }, { 1,inputData }};
304     std::map<int, std::vector<T>> expectedOutputData = {{ 0,expectedOutput }};
305 
306     EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
307 }
308 
309 } // anonymous namespace
310