xref: /aosp_15_r20/external/armnn/src/backends/tosaCommon/test/OneToOneMappingTests.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "TosaTestUtils.hpp"
7 #include "CommonTestUtils.hpp"
8 
9 using namespace armnn;
10 using namespace tosa;
11 
12 TEST_SUITE("TosaOperatorMappingOneToOneTests")
13 {
14 TEST_CASE("GetTosaMapping_AdditionLayer")
15 {
16     TensorInfo info = TensorInfo({ 1, 2, 4, 2 }, DataType::Float32, 0.0f, 0, true);
17 
18     std::vector<std::vector<int32_t>> inputShape  = {{ 1, 2, 4, 2 }, { 1, 2, 4, 2 }};
19     std::vector<std::vector<int32_t>> outputShape = {{ 1, 2, 4, 2 }};
20 
21     TosaSerializationBasicBlock* basicBlock =
22         GetTosaMapping(nullptr, LayerType::Addition, {&info, &info}, {&info}, BaseDescriptor());
23     AssertTosaOneToOneMappingBasicBlock(
24         basicBlock, inputShape, outputShape, Op_ADD, Attribute_NONE, BaseDescriptor(), LayerType::Addition);
25 }
26 
27 TEST_CASE("GetTosaMappingFromLayer_AdditionLayer")
28 {
29     IRuntime::CreationOptions options;
30     IRuntimePtr runtime(IRuntime::Create(options));
31 
32     // Builds up the structure of the network.
33     INetworkPtr net(INetwork::Create());
34 
35     IConnectableLayer* input0 = net->AddInputLayer(0, "input0");
36     IConnectableLayer* input1 = net->AddInputLayer(1, "input1");
37     ARMNN_NO_DEPRECATE_WARN_BEGIN
38     IConnectableLayer* add    = net->AddAdditionLayer("add");
39     ARMNN_NO_DEPRECATE_WARN_END
40     IConnectableLayer* output = net->AddOutputLayer(0, "output");
41 
42     input0->GetOutputSlot(0).Connect(add->GetInputSlot(0));
43     input1->GetOutputSlot(0).Connect(add->GetInputSlot(1));
44     add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
45 
46     TensorInfo info = TensorInfo({ 1, 2, 4, 2 }, DataType::Float32, 0.0f, 0, true);
47 
48     input0->GetOutputSlot(0).SetTensorInfo(info);
49     input1->GetOutputSlot(0).SetTensorInfo(info);
50     add->GetOutputSlot(0).SetTensorInfo(info);
51 
52     std::vector<std::vector<int32_t>> inputShape  = {{ 1, 2, 4, 2 }, { 1, 2, 4, 2 }};
53     std::vector<std::vector<int32_t>> outputShape = {{ 1, 2, 4, 2 }};
54 
55     TosaSerializationBasicBlock* basicBlock =
56         GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(add));
57     AssertTosaOneToOneMappingBasicBlock(
58         basicBlock, inputShape, outputShape, Op_ADD, Attribute_NONE, BaseDescriptor(), LayerType::Addition);
59 }
60 
61 TEST_CASE("GetTosaMapping_ConcatLayer")
62 {
63     std::vector<armnn::TensorShape> inputTensorShapes = { { 2, 3, 2, 2 }, { 2, 3, 2, 2 } };
64     armnn::TensorInfo input0Info(inputTensorShapes[0], DataType::Float32);
65     armnn::TensorInfo input1Info(inputTensorShapes[1], DataType::Float32);
66     armnn::TensorInfo outputInfo({ 2, 6, 2, 2 }, DataType::Float32);
67 
68     armnn::OriginsDescriptor descriptor;
69     unsigned int concatAxis = 1;
70     descriptor.SetConcatAxis(concatAxis);
71     descriptor = armnn::CreateDescriptorForConcatenation(inputTensorShapes.begin(),
72                                                          inputTensorShapes.end(),
73                                                          concatAxis);
74 
75     TosaSerializationBasicBlock* basicBlock =
76             GetTosaMapping(nullptr, LayerType::Concat, {&input0Info,&input1Info}, {&outputInfo}, descriptor);
77 
78     std::vector<std::vector<int32_t>> inputShapes = { { 2, 3, 2, 2 }, { 2, 3, 2, 2 }};
79     std::vector<std::vector<int32_t>> outputShape = { { 2, 6, 2, 2 } };
80 
81     AssertTosaOneToOneMappingBasicBlock(basicBlock,
82                                         inputShapes,
83                                         outputShape,
84                                         Op_CONCAT,
85                                         Attribute_AxisAttribute,
86                                         descriptor,
87                                         LayerType::Concat);
88 }
89 
90 TEST_CASE("GetTosaMappingFromLayer_ConcatLayer")
91 {
92     IRuntime::CreationOptions options;
93     IRuntimePtr runtime(IRuntime::Create(options));
94 
95     // Builds up the structure of the network.
96     INetworkPtr net(INetwork::Create());
97 
98     armnn::OriginsDescriptor descriptor;
99     unsigned int concatAxis = 1;
100     descriptor.SetConcatAxis(concatAxis);
101     std::vector<armnn::TensorShape> inputTensorShapes = { { 2, 3, 2, 2 }, { 2, 3, 2, 2 } };
102     descriptor = armnn::CreateDescriptorForConcatenation(inputTensorShapes.begin(),
103                                                          inputTensorShapes.end(),
104                                                          concatAxis);
105 
106     IConnectableLayer* input0 = net->AddInputLayer(0, "input0");
107     IConnectableLayer* input1 = net->AddInputLayer(1, "input1");
108     IConnectableLayer* concat = net->AddConcatLayer(descriptor, "concat");
109     IConnectableLayer* output = net->AddOutputLayer(0, "output");
110 
111     input0->GetOutputSlot(0).Connect(concat->GetInputSlot(0));
112     input1->GetOutputSlot(0).Connect(concat->GetInputSlot(1));
113     concat->GetOutputSlot(0).Connect(output->GetInputSlot(0));
114 
115 
116     TensorInfo inputInfo0 = TensorInfo(inputTensorShapes[0], DataType::Float32, 0.0f, 0, true);
117     TensorInfo inputInfo1 = TensorInfo(inputTensorShapes[1], DataType::Float32, 0.0f, 0, true);
118     armnn::TensorInfo outputInfo({ 2, 6, 2, 2 }, DataType::Float32);
119 
120     input0->GetOutputSlot(0).SetTensorInfo(inputInfo0);
121     input1->GetOutputSlot(0).SetTensorInfo(inputInfo1);
122     concat->GetOutputSlot(0).SetTensorInfo(outputInfo);
123 
124     std::vector<std::vector<int32_t>> inputShapes = { { 2, 3, 2, 2 }, { 2, 3, 2, 2 }};
125     std::vector<std::vector<int32_t>> outputShape = { { 2, 6, 2, 2 } };
126 
127     TosaSerializationBasicBlock* basicBlock = GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(concat));
128     AssertTosaOneToOneMappingBasicBlock(basicBlock,
129                                         inputShapes,
130                                         outputShape,
131                                         Op_CONCAT,
132                                         Attribute_AxisAttribute,
133                                         descriptor,
134                                         LayerType::Concat);
135 }
136 
137 TEST_CASE("GetTosaMapping_ConstantLayer")
138 {
139     TensorInfo outputInfo = TensorInfo({ 1, 2, 4, 2 }, DataType::Float32, 0.0f, 0, true);
140     std::vector<std::vector<int32_t>> outputShape = {{ 1, 2, 4, 2 }};
141 
142     TosaSerializationBasicBlock* basicBlock =
143             GetTosaMapping(nullptr, LayerType::Constant, {}, {&outputInfo}, BaseDescriptor());
144     AssertTosaOneToOneMappingBasicBlock(
145             basicBlock, {}, outputShape, Op_CONST, Attribute_NONE, BaseDescriptor(), LayerType::Constant);
146 }
147 
148 TEST_CASE("GetTosaMappingFromLayer_ConstantLayer")
149 {
150     IRuntime::CreationOptions options;
151     IRuntimePtr runtime(IRuntime::Create(options));
152 
153     // Builds up the structure of the network.
154     INetworkPtr net(INetwork::Create());
155 
156     TensorInfo info = TensorInfo({ 1, 2, 4, 2 }, DataType::Float32, 0.0f, 0, true);
157     std::vector<std::vector<int32_t>> outputShape = {{ 1, 2, 4, 2 }};
158 
159     std::vector<float> data = GenerateRandomData<float>(info.GetNumElements());
160     ConstTensor constTensor(info, data);
161 
162     IConnectableLayer* constant = net->AddConstantLayer(constTensor, "constant");
163     IConnectableLayer* output = net->AddOutputLayer(0, "output");
164 
165     constant->GetOutputSlot(0).Connect(output->GetInputSlot(0));
166     constant->GetOutputSlot(0).SetTensorInfo(info);
167 
168     TosaSerializationBasicBlock* basicBlock =
169             GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(constant));
170     AssertTosaOneToOneMappingBasicBlock(
171             basicBlock, {}, outputShape, Op_CONST, Attribute_NONE, BaseDescriptor(), LayerType::Constant);
172 }
173 
174 TEST_CASE("GetTosaMapping_Conv2dLayer")
175 {
176     Convolution2dDescriptor descriptor;
177     descriptor.m_PadLeft     = 1;
178     descriptor.m_PadRight    = 1;
179     descriptor.m_PadTop      = 1;
180     descriptor.m_PadBottom   = 1;
181     descriptor.m_StrideX     = 2;
182     descriptor.m_StrideY     = 2;
183     descriptor.m_DilationX   = 2;
184     descriptor.m_DilationY   = 2;
185     descriptor.m_BiasEnabled = true;
186 
187     const TensorInfo inputInfo ({ 1, 5, 5, 1 }, DataType::Float32);
188     const TensorInfo outputInfo({ 1, 3, 3, 1 }, DataType::Float32);
189     const TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32, 0.0f, 0, true);
190     const TensorInfo biasesInfo ({ 1 }, DataType::Float32, 0.0f, 0, true);
191 
192     std::vector<std::vector<int32_t>> inputShape  = {{ 1, 5, 5, 1 }, { 1, 3, 3, 1 }, { 1 }};
193     std::vector<std::vector<int32_t>> outputShape = {{ 1, 3, 3, 1 }};
194 
195     TosaSerializationBasicBlock* basicBlock = GetTosaMapping(nullptr,
196                                                              LayerType::Convolution2d,
197                                                              {&inputInfo, &weightsInfo, &biasesInfo},
198                                                              {&outputInfo},
199                                                              descriptor);
200     AssertTosaOneToOneMappingBasicBlock(
201         basicBlock, inputShape, outputShape, Op_CONV2D, Attribute_ConvAttribute, descriptor, LayerType::Convolution2d);
202 }
203 
204 TEST_CASE("GetTosaMappingFromLayer_Conv2dLayer")
205 {
206     IRuntime::CreationOptions options;
207     IRuntimePtr runtime(IRuntime::Create(options));
208 
209     // Builds up the structure of the network.
210     INetworkPtr net(INetwork::Create());
211 
212     Convolution2dDescriptor descriptor;
213     descriptor.m_PadLeft     = 1;
214     descriptor.m_PadRight    = 1;
215     descriptor.m_PadTop      = 1;
216     descriptor.m_PadBottom   = 1;
217     descriptor.m_StrideX     = 2;
218     descriptor.m_StrideY     = 2;
219     descriptor.m_DilationX   = 2;
220     descriptor.m_DilationY   = 2;
221     descriptor.m_BiasEnabled = true;
222 
223     const TensorInfo inputInfo ({ 1, 5, 5, 1 }, DataType::Float32);
224     const TensorInfo outputInfo({ 1, 3, 3, 1 }, DataType::Float32);
225     const TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32, 0.0f, 0, true);
226     const TensorInfo biasesInfo ({ 1 }, DataType::Float32, 0.0f, 0, true);
227 
228     std::vector<std::vector<int32_t>> inputShape  = {{ 1, 5, 5, 1 }};
229     std::vector<std::vector<int32_t>> outputShape = {{ 1, 3, 3, 1 }};
230 
231     std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
232     ConstTensor weights(weightsInfo, weightsData);
233 
234     std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
235     ConstTensor biases(biasesInfo, biasesData);
236 
237     IConnectableLayer* const inputLayer  = net->AddInputLayer(0, "input0");
238     IConnectableLayer* const weightsLayer = net->AddConstantLayer(weights, "weights");
239     IConnectableLayer* const biasesLayer = net->AddConstantLayer(biases, "biases");
240     IConnectableLayer* const convLayer   = net->AddConvolution2dLayer(descriptor, "conv2d");
241     IConnectableLayer* const outputLayer = net->AddOutputLayer(0);
242 
243     inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
244     weightsLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(1));
245     biasesLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(2));
246     convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
247 
248     inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
249     weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsInfo);
250     biasesLayer->GetOutputSlot(0).SetTensorInfo(biasesInfo);
251     convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
252 
253     TosaSerializationBasicBlock* basicBlock = GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(convLayer));
254     AssertTosaOneToOneMappingBasicBlock(
255         basicBlock, inputShape, outputShape, Op_CONV2D, Attribute_ConvAttribute, descriptor, LayerType::Convolution2d);
256 }
257 TEST_CASE("GetTosaMapping_ElementwiseUnaryLayerRsqrt")
258 {
259     TensorInfo inputInfo  = TensorInfo({ 2, 2 }, DataType::Float32, 0.0f, 0, true);
260     TensorInfo outputInfo = TensorInfo({ 2, 2 }, DataType::Float32, 0.0f, 0, true);
261     std::vector<std::vector<int32_t>> inputShape  = {{ 2, 2 }};
262     std::vector<std::vector<int32_t>> outputShape = {{ 2, 2 }};
263 
264     ElementwiseUnaryDescriptor unaryDescriptor = ElementwiseUnaryDescriptor(UnaryOperation::Rsqrt);
265     TosaSerializationBasicBlock* basicBlock =
266             GetTosaMapping(nullptr, LayerType::ElementwiseUnary, {&inputInfo,}, {&outputInfo}, unaryDescriptor);
267 
268     AssertTosaOneToOneMappingBasicBlock(basicBlock,
269                                         inputShape,
270                                         outputShape,
271                                         tosa::Op_RSQRT,
272                                         tosa::Attribute_NONE,
273                                         unaryDescriptor,
274                                         LayerType::ElementwiseUnary);
275 }
276 TEST_CASE("GetTosaMappingFromLayer_ElementwiseUnaryLayerRsqrt")
277 {
278     IRuntime::CreationOptions options;
279     IRuntimePtr runtime(IRuntime::Create(options));
280 
281     // Builds up the structure of the network.
282     INetworkPtr net(INetwork::Create());
283     ElementwiseUnaryDescriptor unaryDescriptor = ElementwiseUnaryDescriptor(UnaryOperation::Rsqrt);
284     IConnectableLayer* input     = net->AddInputLayer(0, "input0");
285     IConnectableLayer* unaryRsqrt = net->AddElementwiseUnaryLayer(unaryDescriptor, "rsqrt");
286     IConnectableLayer* output    = net->AddOutputLayer(0, "output");
287 
288     input->GetOutputSlot(0).Connect(unaryRsqrt->GetInputSlot(0));
289     unaryRsqrt->GetOutputSlot(0).Connect(output->GetInputSlot(0));
290     TensorInfo inputInfo  = TensorInfo({ 2, 2 }, DataType::Float32, 0.0f, 0, true);
291     TensorInfo outputInfo = TensorInfo({ 2, 2 }, DataType::Float32, 0.0f, 0, true);
292     input->GetOutputSlot(0).SetTensorInfo(inputInfo);
293     unaryRsqrt->GetOutputSlot(0).SetTensorInfo(outputInfo);
294     std::vector<std::vector<int32_t>> inputShape  = {{ 2, 2 }};
295     std::vector<std::vector<int32_t>> outputShape = {{ 2, 2 }};
296 
297     TosaSerializationBasicBlock* basicBlock =
298             GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(unaryRsqrt));
299     AssertTosaOneToOneMappingBasicBlock(basicBlock,
300                                         inputShape,
301                                         outputShape,
302                                         tosa::Op_RSQRT,
303                                         tosa::Attribute_NONE,
304                                         unaryDescriptor,
305                                         LayerType::ElementwiseUnary);
306 }
307 
308 TEST_CASE("GetTosaMapping_MultiplicationLayer")
309 {
310 
311     const TensorInfo input0Info ({ 1, 2, 4, 2 }, DataType::Float32);
312     const TensorInfo input1Info ({ 1, 2, 4, 2 }, DataType::Float32);
313     const TensorInfo outputInfo ({ 1, 2, 4, 2 }, DataType::Float32);
314 
315     std::vector<std::vector<int32_t>> inputShape  = {{ 1, 2, 4, 2 }, { 1, 2, 4, 2 }};
316     std::vector<std::vector<int32_t>> outputShape = {{ 1, 2, 4, 2 }};
317 
318     TosaSerializationBasicBlock* basicBlock =
319         GetTosaMapping(nullptr, LayerType::Multiplication, {&input0Info, &input1Info}, {&outputInfo}, BaseDescriptor());
320     AssertTosaOneToOneMappingBasicBlock( basicBlock, inputShape, outputShape,
321         tosa::Op_MUL, tosa::Attribute_MulAttribute, BaseDescriptor(), LayerType::Multiplication);
322 }
323 
324 TEST_CASE("GetTosaMappingFromLayer_MultiplicationLayer")
325 {
326     IRuntime::CreationOptions options;
327     IRuntimePtr runtime(IRuntime::Create(options));
328 
329     // Builds up the structure of the network.
330     INetworkPtr net(INetwork::Create());
331 
332     IConnectableLayer* input0 = net->AddInputLayer(0, "input0");
333     IConnectableLayer* input1 = net->AddInputLayer(1, "input1");
334     ARMNN_NO_DEPRECATE_WARN_BEGIN
335     IConnectableLayer* add    = net->AddMultiplicationLayer("multiplication");
336     ARMNN_NO_DEPRECATE_WARN_END
337     IConnectableLayer* output = net->AddOutputLayer(0, "output");
338 
339     input0->GetOutputSlot(0).Connect(add->GetInputSlot(0));
340     input1->GetOutputSlot(0).Connect(add->GetInputSlot(1));
341     add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
342 
343     TensorInfo info = TensorInfo({ 2, 2 }, DataType::Float32, 0.0f, 0, true);
344 
345     input0->GetOutputSlot(0).SetTensorInfo(info);
346     input1->GetOutputSlot(0).SetTensorInfo(info);
347     add->GetOutputSlot(0).SetTensorInfo(info);
348 
349     std::vector<std::vector<int32_t>> inputShape  = {{ 2, 2 }, { 2, 2 }};
350     std::vector<std::vector<int32_t>> outputShape = {{ 2, 2 }};
351 
352     TosaSerializationBasicBlock* basicBlock =
353             GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(add));
354     AssertTosaOneToOneMappingBasicBlock( basicBlock, inputShape, outputShape,
355             tosa::Op_MUL, Attribute_MulAttribute, BaseDescriptor(), LayerType::Multiplication);
356 }
357 
358 TEST_CASE("GetTosaMapping_AvgPool2DLayer")
359 {
360     Pooling2dDescriptor descriptor;
361     descriptor.m_PoolType = PoolingAlgorithm::Average;
362     descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2;
363     descriptor.m_StrideX = descriptor.m_StrideY = 2;
364     descriptor.m_PadLeft = 1;
365     descriptor.m_PadRight = 1;
366     descriptor.m_PadTop = 1;
367     descriptor.m_PadBottom = 1;
368     descriptor.m_PaddingMethod = PaddingMethod::Exclude;
369 
370     TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, DataType::Float32);
371     TensorInfo outputTensorInfo({ 1, 1, 3, 3 }, DataType::Float32);
372 
373     std::vector<std::vector<int32_t>> inputShape  = {{ 1, 1, 4, 4 }};
374     std::vector<std::vector<int32_t>> outputShape = {{ 1, 1, 3, 3 }};
375 
376     TosaSerializationBasicBlock* basicBlock =
377             GetTosaMapping(nullptr, LayerType::Pooling2d, {&inputTensorInfo}, {&outputTensorInfo}, descriptor);
378     AssertTosaOneToOneMappingBasicBlock(basicBlock,
379                                         inputShape,
380                                         outputShape,
381                                         Op_AVG_POOL2D,
382                                         Attribute_PoolAttribute,
383                                         descriptor,
384                                         LayerType::Pooling2d);
385 }
386 
387 TEST_CASE("GetTosaMappingFromLayer_AvgPool2DLayer")
388 {
389     IRuntime::CreationOptions options;
390     IRuntimePtr runtime(IRuntime::Create(options));
391 
392     // Builds up the structure of the network.
393     INetworkPtr net(INetwork::Create());
394 
395     Pooling2dDescriptor descriptor;
396     descriptor.m_PoolType = PoolingAlgorithm::Average;
397     descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2;
398     descriptor.m_StrideX = descriptor.m_StrideY = 2;
399     descriptor.m_PadLeft = 1;
400     descriptor.m_PadRight = 1;
401     descriptor.m_PadTop = 1;
402     descriptor.m_PadBottom = 1;
403     descriptor.m_PaddingMethod = PaddingMethod::Exclude;
404 
405     IConnectableLayer* input0  = net->AddInputLayer(0, "input0");
406     IConnectableLayer* pool    = net->AddPooling2dLayer(descriptor, "pool");
407     IConnectableLayer* output  = net->AddOutputLayer(0, "output");
408 
409     input0->GetOutputSlot(0).Connect(pool->GetInputSlot(0));
410     pool->GetOutputSlot(0).Connect(output->GetInputSlot(0));
411 
412     TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, DataType::Float32);
413     TensorInfo outputTensorInfo({ 1, 1, 3, 3 }, DataType::Float32);
414 
415     std::vector<std::vector<int32_t>> inputShape  = {{ 1, 1, 4, 4 }};
416     std::vector<std::vector<int32_t>> outputShape = {{ 1, 1, 3, 3 }};
417 
418     input0->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
419     pool->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
420 
421     TosaSerializationBasicBlock* basicBlock =
422             GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(pool));
423     AssertTosaOneToOneMappingBasicBlock(basicBlock,
424                                         inputShape,
425                                         outputShape,
426                                         Op_AVG_POOL2D,
427                                         Attribute_PoolAttribute,
428                                         descriptor,
429                                         LayerType::Pooling2d);
430 }
431 
432 TEST_CASE("GetTosaMapping_MaxPool2DLayer")
433 {
434     Pooling2dDescriptor descriptor;
435     descriptor.m_PoolType = PoolingAlgorithm::Max;
436     descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2;
437     descriptor.m_StrideX = descriptor.m_StrideY = 2;
438     descriptor.m_PadLeft = 1;
439     descriptor.m_PadRight = 1;
440     descriptor.m_PadTop = 1;
441     descriptor.m_PadBottom = 1;
442     descriptor.m_PaddingMethod = PaddingMethod::Exclude;
443 
444     TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, DataType::Float32);
445     TensorInfo outputTensorInfo({ 1, 1, 3, 3 }, DataType::Float32);
446 
447     std::vector<std::vector<int32_t>> inputShape  = {{ 1, 1, 4, 4 }};
448     std::vector<std::vector<int32_t>> outputShape = {{ 1, 1, 3, 3 }};
449 
450     TosaSerializationBasicBlock* basicBlock =
451         GetTosaMapping(nullptr, LayerType::Pooling2d, {&inputTensorInfo}, {&outputTensorInfo}, descriptor);
452     AssertTosaOneToOneMappingBasicBlock(
453         basicBlock, inputShape, outputShape, Op_MAX_POOL2D, Attribute_PoolAttribute, descriptor, LayerType::Pooling2d);
454 }
455 
456 TEST_CASE("GetTosaMappingFromLayer_MaxPool2DLayer")
457 {
458     IRuntime::CreationOptions options;
459     IRuntimePtr runtime(IRuntime::Create(options));
460 
461     // Builds up the structure of the network.
462     INetworkPtr net(INetwork::Create());
463 
464     Pooling2dDescriptor descriptor;
465     descriptor.m_PoolType = PoolingAlgorithm::Max;
466     descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2;
467     descriptor.m_StrideX = descriptor.m_StrideY = 2;
468     descriptor.m_PadLeft = 1;
469     descriptor.m_PadRight = 1;
470     descriptor.m_PadTop = 1;
471     descriptor.m_PadBottom = 1;
472     descriptor.m_PaddingMethod = PaddingMethod::Exclude;
473 
474     IConnectableLayer* input  = net->AddInputLayer(0, "input0");
475     IConnectableLayer* pool   = net->AddPooling2dLayer(descriptor, "pool");
476     IConnectableLayer* output = net->AddOutputLayer(0, "output");
477 
478     input->GetOutputSlot(0).Connect(pool->GetInputSlot(0));
479     pool->GetOutputSlot(0).Connect(output->GetInputSlot(0));
480 
481     TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, DataType::Float32);
482     TensorInfo outputTensorInfo({ 1, 1, 3, 3 }, DataType::Float32);
483 
484     std::vector<std::vector<int32_t>> inputShape  = {{ 1, 1, 4, 4 }};
485     std::vector<std::vector<int32_t>> outputShape = {{ 1, 1, 3, 3 }};
486 
487     input->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
488     pool->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
489 
490     TosaSerializationBasicBlock* basicBlock =
491         GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(pool));
492     AssertTosaOneToOneMappingBasicBlock(
493         basicBlock, inputShape, outputShape, Op_MAX_POOL2D, Attribute_PoolAttribute, descriptor, LayerType::Pooling2d);
494 }
495 
496 TEST_CASE("GetTosaMapping_ReshapeLayer")
497 {
498     TensorInfo inputInfo = TensorInfo({ 2, 3 }, DataType::Float32);
499     TensorInfo outputInfo = TensorInfo({ 6 }, DataType::Float32);
500 
501     std::vector<std::vector<int32_t>> inputShape  = {{ 2, 3 }};
502     std::vector<std::vector<int32_t>> outputShape = {{ 6 }};
503 
504     ReshapeDescriptor descriptor;
505     descriptor.m_TargetShape = { 6 };
506 
507     TosaSerializationBasicBlock* basicBlock =
508         GetTosaMapping(nullptr, LayerType::Reshape, {&inputInfo}, {&outputInfo}, descriptor);
509     AssertTosaOneToOneMappingBasicBlock(basicBlock,
510                                         inputShape,
511                                         outputShape,
512                                         Op_RESHAPE,
513                                         Attribute_ReshapeAttribute,
514                                         descriptor,
515                                         LayerType::Reshape);
516 }
517 
518 TEST_CASE("GetTosaMappingFromLayer_ReshapeLayer")
519 {
520     IRuntime::CreationOptions options;
521     IRuntimePtr runtime(IRuntime::Create(options));
522 
523     // Builds up the structure of the network.
524     INetworkPtr net(INetwork::Create());
525 
526     ReshapeDescriptor descriptor;
527     descriptor.m_TargetShape = { 6 };
528 
529     IConnectableLayer* input   = net->AddInputLayer(0, "input");
530     IConnectableLayer* reshape = net->AddReshapeLayer(descriptor, "reshape");
531     IConnectableLayer* output  = net->AddOutputLayer(0, "output");
532 
533     input->GetOutputSlot(0).Connect(reshape->GetInputSlot(0));
534     reshape->GetOutputSlot(0).Connect(output->GetInputSlot(0));
535 
536     TensorInfo inputInfo = TensorInfo({ 2, 3 }, DataType::Float32);
537     TensorInfo outputInfo = TensorInfo({ 6 }, DataType::Float32);
538 
539     input->GetOutputSlot(0).SetTensorInfo(inputInfo);
540     reshape->GetOutputSlot(0).SetTensorInfo(outputInfo);
541 
542     std::vector<std::vector<int32_t>> inputShape  = {{ 2, 3 }};
543     std::vector<std::vector<int32_t>> outputShape = {{ 6 }};
544 
545     TosaSerializationBasicBlock* basicBlock =
546         GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(reshape));
547     AssertTosaOneToOneMappingBasicBlock(basicBlock,
548                                         inputShape,
549                                         outputShape,
550                                         Op_RESHAPE,
551                                         Attribute_ReshapeAttribute,
552                                         descriptor,
553                                         LayerType::Reshape);
554 }
555 
556 TEST_CASE("GetTosaMapping_SliceLayer")
557 {
558     TensorInfo inputInfo = TensorInfo({ 3, 2, 3 }, DataType::Float32);
559     TensorInfo outputInfo = TensorInfo({ 2, 1, 3 }, DataType::Float32);
560 
561     std::vector<std::vector<int32_t>> inputShape  = {{ 3, 2, 3 }};
562     std::vector<std::vector<int32_t>> outputShape = {{ 2, 1, 3 }};
563 
564     SliceDescriptor descriptor;
565     descriptor.m_Begin = { 1, 0, 0 };
566     descriptor.m_Size  = { 2, 1, 3 };
567 
568     TosaSerializationBasicBlock* basicBlock =
569         GetTosaMapping(nullptr, LayerType::Slice, {&inputInfo}, {&outputInfo}, descriptor);
570     AssertTosaOneToOneMappingBasicBlock(basicBlock,
571                                         inputShape,
572                                         outputShape,
573                                         Op_SLICE,
574                                         Attribute_SliceAttribute,
575                                         descriptor,
576                                         LayerType::Slice);
577 }
578 
579 TEST_CASE("GetTosaMappingFromLayer_SliceLayer")
580 {
581     IRuntime::CreationOptions options;
582     IRuntimePtr runtime(IRuntime::Create(options));
583 
584     // Builds up the structure of the network.
585     INetworkPtr net(INetwork::Create());
586 
587     TensorInfo inputInfo = TensorInfo({ 3, 2, 3 }, DataType::Float32);
588     TensorInfo outputInfo = TensorInfo({ 2, 1, 3 }, DataType::Float32);
589 
590     std::vector<std::vector<int32_t>> inputShape  = {{ 3, 2, 3 }};
591     std::vector<std::vector<int32_t>> outputShape = {{ 2, 1, 3 }};
592 
593     SliceDescriptor descriptor;
594     descriptor.m_Begin = { 1, 0, 0 };
595     descriptor.m_Size  = { 2, 1, 3 };
596 
597     IConnectableLayer* input  = net->AddInputLayer(0, "input");
598     IConnectableLayer* slice  = net->AddSliceLayer(descriptor, "slice");
599     IConnectableLayer* output = net->AddOutputLayer(0, "output");
600 
601     input->GetOutputSlot(0).Connect(slice->GetInputSlot(0));
602     slice->GetOutputSlot(0).Connect(output->GetInputSlot(0));
603 
604     input->GetOutputSlot(0).SetTensorInfo(inputInfo);
605     slice->GetOutputSlot(0).SetTensorInfo(outputInfo);
606 
607     TosaSerializationBasicBlock* basicBlock =
608         GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(slice));
609     AssertTosaOneToOneMappingBasicBlock(basicBlock,
610                                         inputShape,
611                                         outputShape,
612                                         Op_SLICE,
613                                         Attribute_SliceAttribute,
614                                         descriptor,
615                                         LayerType::Slice);
616 }
617 
618 
619 TEST_CASE("GetTosaMapping_TransposeConv2dLayer")
620 {
621     const TensorInfo inputInfo ({ 1, 7, 7, 1 }, DataType::Float32);
622     const TensorInfo outputInfo({ 1, 9, 9, 1 }, DataType::Float32);
623     const TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32, 0.0f, 0, true);
624     const TensorInfo biasesInfo ({ 1 }, DataType::Float32, 0.0f, 0, true);
625 
626     TransposeConvolution2dDescriptor descriptor;
627     descriptor.m_PadLeft     = 1;
628     descriptor.m_PadRight    = 1;
629     descriptor.m_PadTop      = 1;
630     descriptor.m_PadBottom   = 1;
631     descriptor.m_StrideX     = 1;
632     descriptor.m_StrideY     = 1;
633     descriptor.m_BiasEnabled = true;
634     descriptor.m_DataLayout  = DataLayout::NHWC;
635 
636     TosaSerializationBasicBlock* basicBlock = GetTosaMapping(nullptr,
637                                                              LayerType::TransposeConvolution2d,
638                                                              {&inputInfo, &weightsInfo, &biasesInfo},
639                                                              {&outputInfo},
640                                                              descriptor);
641 
642     CHECK(basicBlock->GetInputs().size() == 3);
643     CHECK(basicBlock->GetOutputs().size() == 1);
644     CHECK(basicBlock->GetOperators().size() == 3);
645     CHECK(basicBlock->GetTensors().size() == 4);
646 
647     CHECK(basicBlock->GetInputs()[0].find("input0_") != std::string::npos);
648     CHECK(basicBlock->GetInputs()[1].find("constant_") != std::string::npos);
649     CHECK(basicBlock->GetInputs()[2].find("constant_") != std::string::npos);
650     CHECK(basicBlock->GetOutputs()[0].find("output0_") != std::string::npos);
651 
652     VerifyTosaAttribute(descriptor,
653                         basicBlock->GetOperators().at(2)->GetAttribute(),
654                         {},
655                         {},
656                         LayerType::TransposeConvolution2d);
657 }
658 
659 TEST_CASE("GetTosaMappingFromLayer_TransposeConv2dLayer")
660 {
661     IRuntime::CreationOptions options;
662     IRuntimePtr runtime(IRuntime::Create(options));
663 
664     // Builds up the structure of the network.
665     INetworkPtr net(INetwork::Create());
666 
667     const TensorInfo inputInfo ({ 1, 7, 7, 1 }, DataType::Float32);
668     const TensorInfo outputInfo({ 1, 9, 9, 1 }, DataType::Float32);
669     const TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32, 0.0f, 0, true);
670     const TensorInfo biasesInfo ({ 1 }, DataType::Float32, 0.0f, 0, true);
671 
672     std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
673     ConstTensor weights(weightsInfo, weightsData);
674 
675     std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
676     ConstTensor biases(biasesInfo, biasesData);
677 
678     TransposeConvolution2dDescriptor descriptor;
679     descriptor.m_PadLeft     = 1;
680     descriptor.m_PadRight    = 1;
681     descriptor.m_PadTop      = 1;
682     descriptor.m_PadBottom   = 1;
683     descriptor.m_StrideX     = 1;
684     descriptor.m_StrideY     = 1;
685     descriptor.m_BiasEnabled = true;
686     descriptor.m_DataLayout  = DataLayout::NHWC;
687 
688     IConnectableLayer* const inputLayer  = net->AddInputLayer(0);
689     IConnectableLayer* const convLayer   =
690             net->AddTransposeConvolution2dLayer(descriptor,
691                                                 weights,
692                                                 Optional<ConstTensor>(biases),
693                                                 "transposeConvolution2d");
694     IConnectableLayer* const outputLayer = net->AddOutputLayer(0);
695 
696     inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
697     convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
698 
699     inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
700     convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
701 
702     TosaSerializationBasicBlock* basicBlock = GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(convLayer));
703 
704     CHECK(basicBlock->GetInputs().size() == 3);
705     CHECK(basicBlock->GetOutputs().size() == 1);
706     CHECK(basicBlock->GetOperators().size() == 3);
707     CHECK(basicBlock->GetTensors().size() == 4);
708 
709     CHECK(basicBlock->GetInputs()[0].find("input0_") != std::string::npos);
710     CHECK(basicBlock->GetInputs()[1].find("constant_") != std::string::npos);
711     CHECK(basicBlock->GetInputs()[2].find("constant_") != std::string::npos);
712     CHECK(basicBlock->GetOutputs()[0].find("output0_") != std::string::npos);
713 
714     VerifyTosaAttribute(descriptor,
715                         basicBlock->GetOperators().at(2)->GetAttribute(),
716                         {},
717                         {},
718                         LayerType::TransposeConvolution2d);
719 }
720 
721 TEST_CASE("GetTosaMapping_TransposeLayer")
722 {
723     TensorInfo inputInfo  = TensorInfo({ 1, 1, 5, 3 }, DataType::Float32, 0.0f, 0, true);
724     TensorInfo outputInfo = TensorInfo({ 1, 5, 1, 3 }, DataType::Float32, 0.0f, 0, true);
725 
726     std::vector<std::vector<int32_t>> inputShape  = {{ 1, 1, 5, 3 }};
727     std::vector<std::vector<int32_t>> outputShape = {{ 1, 5, 1, 3 }};
728 
729     TransposeDescriptor transposeDescriptor = TransposeDescriptor({ 0, 2, 1 ,3 });
730 
731     TosaSerializationBasicBlock* basicBlock =
732         GetTosaMapping(nullptr, LayerType::Transpose, {&inputInfo,}, {&outputInfo}, transposeDescriptor);
733     AssertTosaOneToOneMappingBasicBlock(basicBlock,
734                                         inputShape,
735                                         outputShape,
736                                         Op_TRANSPOSE,
737                                         Attribute_TransposeAttribute,
738                                         transposeDescriptor,
739                                         LayerType::Transpose);
740 }
741 
742 TEST_CASE("GetTosaMappingFromLayer_TransposeLayer")
743 {
744     IRuntime::CreationOptions options;
745     IRuntimePtr runtime(IRuntime::Create(options));
746 
747     // Builds up the structure of the network.
748     INetworkPtr net(INetwork::Create());
749 
750     TransposeDescriptor transposeDescriptor = TransposeDescriptor({ 0, 2, 1 ,3 });
751 
752     IConnectableLayer* input     = net->AddInputLayer(0, "input0");
753     IConnectableLayer* transpose = net->AddTransposeLayer(transposeDescriptor, "transpose");
754     IConnectableLayer* output    = net->AddOutputLayer(0, "output");
755 
756     input->GetOutputSlot(0).Connect(transpose->GetInputSlot(0));
757     transpose->GetOutputSlot(0).Connect(output->GetInputSlot(0));
758 
759     TensorInfo inputInfo  = TensorInfo({ 1, 1, 5, 3 }, DataType::Float32, 0.0f, 0, true);
760     TensorInfo outputInfo = TensorInfo({ 1, 5, 1, 3 }, DataType::Float32, 0.0f, 0, true);
761 
762     input->GetOutputSlot(0).SetTensorInfo(inputInfo);
763     transpose->GetOutputSlot(0).SetTensorInfo(outputInfo);
764 
765     std::vector<std::vector<int32_t>> inputShape  = {{ 1, 1, 5, 3 }};
766     std::vector<std::vector<int32_t>> outputShape = {{ 1, 5, 1, 3 }};
767 
768     TosaSerializationBasicBlock* basicBlock =
769         GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(transpose));
770     AssertTosaOneToOneMappingBasicBlock(basicBlock,
771                                         inputShape,
772                                         outputShape,
773                                         Op_TRANSPOSE,
774                                         Attribute_TransposeAttribute,
775                                         transposeDescriptor,
776                                         LayerType::Transpose);
777 }
778 
779 TEST_CASE("GetTosaMapping_Unimplemented")
780 {
781     TosaSerializationBasicBlock* basicBlock =
782         GetTosaMapping(nullptr, LayerType::UnidirectionalSequenceLstm, {}, {}, BaseDescriptor());
783 
784     CHECK(basicBlock->GetName() == "");
785     CHECK(basicBlock->GetTensors().size() == 0);
786     CHECK(basicBlock->GetOperators().size() == 1);
787     CHECK(basicBlock->GetInputs().size() == 0);
788     CHECK(basicBlock->GetOutputs().size() == 0);
789 
790     TosaSerializationOperator* op = basicBlock->GetOperators()[0];
791     CHECK(op->GetAttributeType() == Attribute_NONE);
792     CHECK(op->GetOp() == tosa::Op_UNKNOWN);
793     CHECK(op->GetInputTensorNames().size() == 0);
794     CHECK(op->GetOutputTensorNames().size() == 0);
795 }
796 }
797