ArmNN
 21.05
SerializerTests.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "../Serializer.hpp"
8 
9 #include <armnn/Descriptors.hpp>
10 #include <armnn/INetwork.hpp>
11 #include <armnn/TypesUtils.hpp>
12 #include <armnn/LstmParams.hpp>
16 
17 #include <random>
18 #include <vector>
19 
20 #include <boost/test/unit_test.hpp>
21 
23 
24 BOOST_AUTO_TEST_SUITE(SerializerTests)
25 
26 BOOST_AUTO_TEST_CASE(SerializeAbs)
27 {
28  const std::string layerName("abs");
29  const armnn::TensorInfo tensorInfo({1, 2, 3}, armnn::DataType::Float32);
30 
32  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
33 
35  armnn::IConnectableLayer* const absLayer = network->AddAbsLayer(layerName.c_str());
37  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
38 
39  inputLayer->GetOutputSlot(0).Connect(absLayer->GetInputSlot(0));
40  absLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
41 
42  inputLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
43  absLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
44 
45  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
46  BOOST_CHECK(deserializedNetwork);
47 
48  LayerVerifierBase verifier(layerName, {tensorInfo}, {tensorInfo});
49  deserializedNetwork->ExecuteStrategy(verifier);
50 }
51 
52 BOOST_AUTO_TEST_CASE(SerializeAddition)
53 {
54  const std::string layerName("addition");
55  const armnn::TensorInfo tensorInfo({1, 2, 3}, armnn::DataType::Float32);
56 
58  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
59  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
60  armnn::IConnectableLayer* const additionLayer = network->AddAdditionLayer(layerName.c_str());
61  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
62 
63  inputLayer0->GetOutputSlot(0).Connect(additionLayer->GetInputSlot(0));
64  inputLayer1->GetOutputSlot(0).Connect(additionLayer->GetInputSlot(1));
65  additionLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
66 
67  inputLayer0->GetOutputSlot(0).SetTensorInfo(tensorInfo);
68  inputLayer1->GetOutputSlot(0).SetTensorInfo(tensorInfo);
69  additionLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
70 
71  std::string serializedNetwork = SerializeNetwork(*network);
72  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(serializedNetwork);
73  BOOST_CHECK(deserializedNetwork);
74 
75  LayerVerifierBase verifier(layerName, {tensorInfo, tensorInfo}, {tensorInfo});
76  deserializedNetwork->ExecuteStrategy(verifier);
77 }
78 
80 {
81  const std::string layerName("argminmax");
82  const armnn::TensorInfo inputInfo({1, 2, 3}, armnn::DataType::Float32);
83  const armnn::TensorInfo outputInfo({1, 3}, dataType);
84 
85  armnn::ArgMinMaxDescriptor descriptor;
87  descriptor.m_Axis = 1;
88 
90  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
91  armnn::IConnectableLayer* const argMinMaxLayer = network->AddArgMinMaxLayer(descriptor, layerName.c_str());
92  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
93 
94  inputLayer->GetOutputSlot(0).Connect(argMinMaxLayer->GetInputSlot(0));
95  argMinMaxLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
96 
97  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
98  argMinMaxLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
99 
100  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
101  BOOST_CHECK(deserializedNetwork);
102 
104  {inputInfo},
105  {outputInfo},
106  descriptor);
107  deserializedNetwork->ExecuteStrategy(verifier);
108 }
109 
110 BOOST_AUTO_TEST_CASE(SerializeArgMinMaxSigned32)
111 {
113 }
114 
115 BOOST_AUTO_TEST_CASE(SerializeArgMinMaxSigned64)
116 {
118 }
119 
120 BOOST_AUTO_TEST_CASE(SerializeBatchNormalization)
121 {
122  const std::string layerName("batchNormalization");
123  const armnn::TensorInfo inputInfo ({ 1, 3, 3, 1 }, armnn::DataType::Float32);
124  const armnn::TensorInfo outputInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
125 
126  const armnn::TensorInfo meanInfo({1}, armnn::DataType::Float32);
127  const armnn::TensorInfo varianceInfo({1}, armnn::DataType::Float32);
128  const armnn::TensorInfo betaInfo({1}, armnn::DataType::Float32);
129  const armnn::TensorInfo gammaInfo({1}, armnn::DataType::Float32);
130 
132  descriptor.m_Eps = 0.0010000000475f;
133  descriptor.m_DataLayout = armnn::DataLayout::NHWC;
134 
135  std::vector<float> meanData({5.0});
136  std::vector<float> varianceData({2.0});
137  std::vector<float> betaData({1.0});
138  std::vector<float> gammaData({0.0});
139 
140  std::vector<armnn::ConstTensor> constants;
141  constants.emplace_back(armnn::ConstTensor(meanInfo, meanData));
142  constants.emplace_back(armnn::ConstTensor(varianceInfo, varianceData));
143  constants.emplace_back(armnn::ConstTensor(betaInfo, betaData));
144  constants.emplace_back(armnn::ConstTensor(gammaInfo, gammaData));
145 
147  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
148  armnn::IConnectableLayer* const batchNormalizationLayer =
149  network->AddBatchNormalizationLayer(descriptor,
150  constants[0],
151  constants[1],
152  constants[2],
153  constants[3],
154  layerName.c_str());
155  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
156 
157  inputLayer->GetOutputSlot(0).Connect(batchNormalizationLayer->GetInputSlot(0));
158  batchNormalizationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
159 
160  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
161  batchNormalizationLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
162 
163  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
164  BOOST_CHECK(deserializedNetwork);
165 
167  layerName, {inputInfo}, {outputInfo}, descriptor, constants);
168  deserializedNetwork->ExecuteStrategy(verifier);
169 }
170 
171 BOOST_AUTO_TEST_CASE(SerializeBatchToSpaceNd)
172 {
173  const std::string layerName("spaceToBatchNd");
174  const armnn::TensorInfo inputInfo({4, 1, 2, 2}, armnn::DataType::Float32);
175  const armnn::TensorInfo outputInfo({1, 1, 4, 4}, armnn::DataType::Float32);
176 
179  desc.m_BlockShape = {2, 2};
180  desc.m_Crops = {{0, 0}, {0, 0}};
181 
183  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
184  armnn::IConnectableLayer* const batchToSpaceNdLayer = network->AddBatchToSpaceNdLayer(desc, layerName.c_str());
185  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
186 
187  inputLayer->GetOutputSlot(0).Connect(batchToSpaceNdLayer->GetInputSlot(0));
188  batchToSpaceNdLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
189 
190  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
191  batchToSpaceNdLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
192 
193  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
194  BOOST_CHECK(deserializedNetwork);
195 
197  {inputInfo},
198  {outputInfo},
199  desc);
200  deserializedNetwork->ExecuteStrategy(verifier);
201 }
202 
203 BOOST_AUTO_TEST_CASE(SerializeCast)
204 {
205  const std::string layerName("cast");
206 
207  const armnn::TensorShape shape{1, 5, 2, 3};
208 
211 
213  armnn::IConnectableLayer* inputLayer = network->AddInputLayer(0);
214  armnn::IConnectableLayer* castLayer = network->AddCastLayer(layerName.c_str());
215  armnn::IConnectableLayer* outputLayer = network->AddOutputLayer(0);
216 
217  inputLayer->GetOutputSlot(0).Connect(castLayer->GetInputSlot(0));
218  castLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
219 
220  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
221  castLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
222 
223  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
224  BOOST_CHECK(deserializedNetwork);
225 
226  LayerVerifierBase verifier(layerName, {inputInfo}, {outputInfo});
227  deserializedNetwork->ExecuteStrategy(verifier);
228 }
229 
230 BOOST_AUTO_TEST_CASE(SerializeComparison)
231 {
232  const std::string layerName("comparison");
233 
234  const armnn::TensorShape shape{2, 1, 2, 4};
235 
238 
240 
242  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
243  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
244  armnn::IConnectableLayer* const comparisonLayer = network->AddComparisonLayer(descriptor, layerName.c_str());
245  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
246 
247  inputLayer0->GetOutputSlot(0).Connect(comparisonLayer->GetInputSlot(0));
248  inputLayer1->GetOutputSlot(0).Connect(comparisonLayer->GetInputSlot(1));
249  comparisonLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
250 
251  inputLayer0->GetOutputSlot(0).SetTensorInfo(inputInfo);
252  inputLayer1->GetOutputSlot(0).SetTensorInfo(inputInfo);
253  comparisonLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
254 
255  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
256  BOOST_CHECK(deserializedNetwork);
257 
259  { inputInfo, inputInfo },
260  { outputInfo },
261  descriptor);
262  deserializedNetwork->ExecuteStrategy(verifier);
263 }
264 
265 BOOST_AUTO_TEST_CASE(SerializeConstant)
266 {
267  class ConstantLayerVerifier : public LayerVerifierBase
268  {
269  public:
270  ConstantLayerVerifier(const std::string& layerName,
271  const std::vector<armnn::TensorInfo>& inputInfos,
272  const std::vector<armnn::TensorInfo>& outputInfos,
273  const std::vector<armnn::ConstTensor>& constants)
274  : LayerVerifierBase(layerName, inputInfos, outputInfos)
275  , m_Constants(constants) {}
276 
277  void ExecuteStrategy(const armnn::IConnectableLayer* layer,
278  const armnn::BaseDescriptor& descriptor,
279  const std::vector<armnn::ConstTensor>& constants,
280  const char* name,
281  const armnn::LayerBindingId id = 0) override
282  {
283  armnn::IgnoreUnused(descriptor, id);
284 
285  switch (layer->GetType())
286  {
287  case armnn::LayerType::Input: break;
288  case armnn::LayerType::Output: break;
289  case armnn::LayerType::Addition: break;
290  default:
291  {
292  this->VerifyNameAndConnections(layer, name);
293 
294  for (std::size_t i = 0; i < constants.size(); i++)
295  {
296  CompareConstTensor(constants[i], m_Constants[i]);
297  }
298  }
299  }
300  }
301 
302  private:
303  const std::vector<armnn::ConstTensor> m_Constants;
304  };
305 
306  const std::string layerName("constant");
307  const armnn::TensorInfo info({ 2, 3 }, armnn::DataType::Float32);
308 
309  std::vector<float> constantData = GenerateRandomData<float>(info.GetNumElements());
310  armnn::ConstTensor constTensor(info, constantData);
311 
313  armnn::IConnectableLayer* input = network->AddInputLayer(0);
314  armnn::IConnectableLayer* constant = network->AddConstantLayer(constTensor, layerName.c_str());
315  armnn::IConnectableLayer* add = network->AddAdditionLayer();
316  armnn::IConnectableLayer* output = network->AddOutputLayer(0);
317 
318  input->GetOutputSlot(0).Connect(add->GetInputSlot(0));
319  constant->GetOutputSlot(0).Connect(add->GetInputSlot(1));
320  add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
321 
322  input->GetOutputSlot(0).SetTensorInfo(info);
323  constant->GetOutputSlot(0).SetTensorInfo(info);
324  add->GetOutputSlot(0).SetTensorInfo(info);
325 
326  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
327  BOOST_CHECK(deserializedNetwork);
328 
329  ConstantLayerVerifier verifier(layerName, {}, {info}, {constTensor});
330  deserializedNetwork->ExecuteStrategy(verifier);
331 }
332 
333 BOOST_AUTO_TEST_CASE(SerializeConvolution2d)
334 {
335  const std::string layerName("convolution2d");
336  const armnn::TensorInfo inputInfo ({ 1, 5, 5, 1 }, armnn::DataType::Float32);
337  const armnn::TensorInfo outputInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
338 
339  const armnn::TensorInfo weightsInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
340  const armnn::TensorInfo biasesInfo ({ 1 }, armnn::DataType::Float32);
341 
342  std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
343  armnn::ConstTensor weights(weightsInfo, weightsData);
344 
345  std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
346  armnn::ConstTensor biases(biasesInfo, biasesData);
347 
349  descriptor.m_PadLeft = 1;
350  descriptor.m_PadRight = 1;
351  descriptor.m_PadTop = 1;
352  descriptor.m_PadBottom = 1;
353  descriptor.m_StrideX = 2;
354  descriptor.m_StrideY = 2;
355  descriptor.m_DilationX = 2;
356  descriptor.m_DilationY = 2;
357  descriptor.m_BiasEnabled = true;
359 
361  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
362  armnn::IConnectableLayer* const convLayer =
363  network->AddConvolution2dLayer(descriptor,
364  weights,
366  layerName.c_str());
367  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
368 
369  inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
370  convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
371 
372  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
373  convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
374 
375  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
376  BOOST_CHECK(deserializedNetwork);
377 
378  const std::vector<armnn::ConstTensor>& constants {weights, biases};
380  layerName, {inputInfo}, {outputInfo}, descriptor, constants);
381  deserializedNetwork->ExecuteStrategy(verifier);
382 }
383 
384 BOOST_AUTO_TEST_CASE(SerializeConvolution2dWithPerAxisParams)
385 {
386  using namespace armnn;
387 
388  const std::string layerName("convolution2dWithPerAxis");
389  const TensorInfo inputInfo ({ 1, 3, 1, 2 }, DataType::QAsymmU8, 0.55f, 128);
390  const TensorInfo outputInfo({ 1, 3, 1, 3 }, DataType::QAsymmU8, 0.75f, 128);
391 
392  const std::vector<float> quantScales{ 0.75f, 0.65f, 0.85f };
393  constexpr unsigned int quantDimension = 0;
394 
395  const TensorInfo kernelInfo({ 3, 1, 1, 2 }, DataType::QSymmS8, quantScales, quantDimension);
396 
397  const std::vector<float> biasQuantScales{ 0.25f, 0.50f, 0.75f };
398  const TensorInfo biasInfo({ 3 }, DataType::Signed32, biasQuantScales, quantDimension);
399 
400  std::vector<int8_t> kernelData = GenerateRandomData<int8_t>(kernelInfo.GetNumElements());
401  armnn::ConstTensor weights(kernelInfo, kernelData);
402  std::vector<int32_t> biasData = GenerateRandomData<int32_t>(biasInfo.GetNumElements());
403  armnn::ConstTensor biases(biasInfo, biasData);
404 
405  Convolution2dDescriptor descriptor;
406  descriptor.m_StrideX = 1;
407  descriptor.m_StrideY = 1;
408  descriptor.m_PadLeft = 0;
409  descriptor.m_PadRight = 0;
410  descriptor.m_PadTop = 0;
411  descriptor.m_PadBottom = 0;
412  descriptor.m_BiasEnabled = true;
414 
416  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
417  armnn::IConnectableLayer* const convLayer =
418  network->AddConvolution2dLayer(descriptor,
419  weights,
421  layerName.c_str());
422  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
423 
424  inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
425  convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
426 
427  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
428  convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
429 
430  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
431  BOOST_CHECK(deserializedNetwork);
432 
433  const std::vector<armnn::ConstTensor>& constants {weights, biases};
435  layerName, {inputInfo}, {outputInfo}, descriptor, constants);
436  deserializedNetwork->ExecuteStrategy(verifier);
437 }
438 
439 BOOST_AUTO_TEST_CASE(SerializeDepthToSpace)
440 {
441  const std::string layerName("depthToSpace");
442 
443  const armnn::TensorInfo inputInfo ({ 1, 8, 4, 12 }, armnn::DataType::Float32);
444  const armnn::TensorInfo outputInfo({ 1, 16, 8, 3 }, armnn::DataType::Float32);
445 
447  desc.m_BlockSize = 2;
448  desc.m_DataLayout = armnn::DataLayout::NHWC;
449 
451  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
452  armnn::IConnectableLayer* const depthToSpaceLayer = network->AddDepthToSpaceLayer(desc, layerName.c_str());
453  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
454 
455  inputLayer->GetOutputSlot(0).Connect(depthToSpaceLayer->GetInputSlot(0));
456  depthToSpaceLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
457 
458  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
459  depthToSpaceLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
460 
461  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
462  BOOST_CHECK(deserializedNetwork);
463 
464  LayerVerifierBaseWithDescriptor<armnn::DepthToSpaceDescriptor> verifier(layerName, {inputInfo}, {outputInfo}, desc);
465  deserializedNetwork->ExecuteStrategy(verifier);
466 }
467 
468 BOOST_AUTO_TEST_CASE(SerializeDepthwiseConvolution2d)
469 {
470  const std::string layerName("depwiseConvolution2d");
471  const armnn::TensorInfo inputInfo ({ 1, 5, 5, 3 }, armnn::DataType::Float32);
472  const armnn::TensorInfo outputInfo({ 1, 3, 3, 3 }, armnn::DataType::Float32);
473 
474  const armnn::TensorInfo weightsInfo({ 1, 3, 3, 3 }, armnn::DataType::Float32);
475  const armnn::TensorInfo biasesInfo ({ 3 }, armnn::DataType::Float32);
476 
477  std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
478  armnn::ConstTensor weights(weightsInfo, weightsData);
479 
480  std::vector<int32_t> biasesData = GenerateRandomData<int32_t>(biasesInfo.GetNumElements());
481  armnn::ConstTensor biases(biasesInfo, biasesData);
482 
484  descriptor.m_PadLeft = 1;
485  descriptor.m_PadRight = 1;
486  descriptor.m_PadTop = 1;
487  descriptor.m_PadBottom = 1;
488  descriptor.m_StrideX = 2;
489  descriptor.m_StrideY = 2;
490  descriptor.m_DilationX = 2;
491  descriptor.m_DilationY = 2;
492  descriptor.m_BiasEnabled = true;
494 
496  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
497  armnn::IConnectableLayer* const depthwiseConvLayer =
498  network->AddDepthwiseConvolution2dLayer(descriptor,
499  weights,
501  layerName.c_str());
502  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
503 
504  inputLayer->GetOutputSlot(0).Connect(depthwiseConvLayer->GetInputSlot(0));
505  depthwiseConvLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
506 
507  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
508  depthwiseConvLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
509 
510  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
511  BOOST_CHECK(deserializedNetwork);
512 
513  const std::vector<armnn::ConstTensor>& constants {weights, biases};
515  layerName, {inputInfo}, {outputInfo}, descriptor, constants);
516  deserializedNetwork->ExecuteStrategy(verifier);
517 }
518 
519 BOOST_AUTO_TEST_CASE(SerializeDepthwiseConvolution2dWithPerAxisParams)
520 {
521  using namespace armnn;
522 
523  const std::string layerName("depwiseConvolution2dWithPerAxis");
524  const TensorInfo inputInfo ({ 1, 3, 3, 2 }, DataType::QAsymmU8, 0.55f, 128);
525  const TensorInfo outputInfo({ 1, 2, 2, 4 }, DataType::QAsymmU8, 0.75f, 128);
526 
527  const std::vector<float> quantScales{ 0.75f, 0.80f, 0.90f, 0.95f };
528  const unsigned int quantDimension = 0;
529  TensorInfo kernelInfo({ 2, 2, 2, 2 }, DataType::QSymmS8, quantScales, quantDimension);
530 
531  const std::vector<float> biasQuantScales{ 0.25f, 0.35f, 0.45f, 0.55f };
532  constexpr unsigned int biasQuantDimension = 0;
533  TensorInfo biasInfo({ 4 }, DataType::Signed32, biasQuantScales, biasQuantDimension);
534 
535  std::vector<int8_t> kernelData = GenerateRandomData<int8_t>(kernelInfo.GetNumElements());
536  armnn::ConstTensor weights(kernelInfo, kernelData);
537  std::vector<int32_t> biasData = GenerateRandomData<int32_t>(biasInfo.GetNumElements());
538  armnn::ConstTensor biases(biasInfo, biasData);
539 
541  descriptor.m_StrideX = 1;
542  descriptor.m_StrideY = 1;
543  descriptor.m_PadLeft = 0;
544  descriptor.m_PadRight = 0;
545  descriptor.m_PadTop = 0;
546  descriptor.m_PadBottom = 0;
547  descriptor.m_DilationX = 1;
548  descriptor.m_DilationY = 1;
549  descriptor.m_BiasEnabled = true;
551 
553  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
554  armnn::IConnectableLayer* const depthwiseConvLayer =
555  network->AddDepthwiseConvolution2dLayer(descriptor,
556  weights,
558  layerName.c_str());
559  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
560 
561  inputLayer->GetOutputSlot(0).Connect(depthwiseConvLayer->GetInputSlot(0));
562  depthwiseConvLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
563 
564  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
565  depthwiseConvLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
566 
567  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
568  BOOST_CHECK(deserializedNetwork);
569 
570  const std::vector<armnn::ConstTensor>& constants {weights, biases};
572  layerName, {inputInfo}, {outputInfo}, descriptor, constants);
573  deserializedNetwork->ExecuteStrategy(verifier);
574 }
575 
576 BOOST_AUTO_TEST_CASE(SerializeDequantize)
577 {
578  const std::string layerName("dequantize");
579  const armnn::TensorInfo inputInfo({ 1, 5, 2, 3 }, armnn::DataType::QAsymmU8, 0.5f, 1);
580  const armnn::TensorInfo outputInfo({ 1, 5, 2, 3 }, armnn::DataType::Float32);
581 
583  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
584  armnn::IConnectableLayer* const dequantizeLayer = network->AddDequantizeLayer(layerName.c_str());
585  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
586 
587  inputLayer->GetOutputSlot(0).Connect(dequantizeLayer->GetInputSlot(0));
588  dequantizeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
589 
590  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
591  dequantizeLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
592 
593  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
594  BOOST_CHECK(deserializedNetwork);
595 
596  LayerVerifierBase verifier(layerName, {inputInfo}, {outputInfo});
597  deserializedNetwork->ExecuteStrategy(verifier);
598 }
599 
600 BOOST_AUTO_TEST_CASE(SerializeDeserializeDetectionPostProcess)
601 {
602  const std::string layerName("detectionPostProcess");
603 
604  const std::vector<armnn::TensorInfo> inputInfos({
607  });
608 
609  const std::vector<armnn::TensorInfo> outputInfos({
614  });
615 
617  descriptor.m_UseRegularNms = true;
618  descriptor.m_MaxDetections = 3;
619  descriptor.m_MaxClassesPerDetection = 1;
620  descriptor.m_DetectionsPerClass =1;
621  descriptor.m_NmsScoreThreshold = 0.0;
622  descriptor.m_NmsIouThreshold = 0.5;
623  descriptor.m_NumClasses = 2;
624  descriptor.m_ScaleY = 10.0;
625  descriptor.m_ScaleX = 10.0;
626  descriptor.m_ScaleH = 5.0;
627  descriptor.m_ScaleW = 5.0;
628 
630  const std::vector<float> anchorsData({
631  0.5f, 0.5f, 1.0f, 1.0f,
632  0.5f, 0.5f, 1.0f, 1.0f,
633  0.5f, 0.5f, 1.0f, 1.0f,
634  0.5f, 10.5f, 1.0f, 1.0f,
635  0.5f, 10.5f, 1.0f, 1.0f,
636  0.5f, 100.5f, 1.0f, 1.0f
637  });
638  armnn::ConstTensor anchors(anchorsInfo, anchorsData);
639 
641  armnn::IConnectableLayer* const detectionLayer =
642  network->AddDetectionPostProcessLayer(descriptor, anchors, layerName.c_str());
643 
644  for (unsigned int i = 0; i < 2; i++)
645  {
646  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(static_cast<int>(i));
647  inputLayer->GetOutputSlot(0).Connect(detectionLayer->GetInputSlot(i));
648  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfos[i]);
649  }
650 
651  for (unsigned int i = 0; i < 4; i++)
652  {
653  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(static_cast<int>(i));
654  detectionLayer->GetOutputSlot(i).Connect(outputLayer->GetInputSlot(0));
655  detectionLayer->GetOutputSlot(i).SetTensorInfo(outputInfos[i]);
656  }
657 
658  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
659  BOOST_CHECK(deserializedNetwork);
660 
661  const std::vector<armnn::ConstTensor>& constants {anchors};
663  layerName, inputInfos, outputInfos, descriptor, constants);
664  deserializedNetwork->ExecuteStrategy(verifier);
665 }
666 
667 BOOST_AUTO_TEST_CASE(SerializeDivision)
668 {
669  const std::string layerName("division");
670  const armnn::TensorInfo info({ 1, 5, 2, 3 }, armnn::DataType::Float32);
671 
673  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
674  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
675  armnn::IConnectableLayer* const divisionLayer = network->AddDivisionLayer(layerName.c_str());
676  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
677 
678  inputLayer0->GetOutputSlot(0).Connect(divisionLayer->GetInputSlot(0));
679  inputLayer1->GetOutputSlot(0).Connect(divisionLayer->GetInputSlot(1));
680  divisionLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
681 
682  inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
683  inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
684  divisionLayer->GetOutputSlot(0).SetTensorInfo(info);
685 
686  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
687  BOOST_CHECK(deserializedNetwork);
688 
689  LayerVerifierBase verifier(layerName, {info, info}, {info});
690  deserializedNetwork->ExecuteStrategy(verifier);
691 }
692 
693 BOOST_AUTO_TEST_CASE(SerializeDeserializeEqual)
694 {
695  const std::string layerName("EqualLayer");
696  const armnn::TensorInfo inputTensorInfo1 = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Float32);
697  const armnn::TensorInfo inputTensorInfo2 = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Float32);
698  const armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Boolean);
699 
701  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(0);
702  armnn::IConnectableLayer* const inputLayer2 = network->AddInputLayer(1);
704  armnn::IConnectableLayer* const equalLayer = network->AddEqualLayer(layerName.c_str());
706  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
707 
708  inputLayer1->GetOutputSlot(0).Connect(equalLayer->GetInputSlot(0));
709  inputLayer1->GetOutputSlot(0).SetTensorInfo(inputTensorInfo1);
710  inputLayer2->GetOutputSlot(0).Connect(equalLayer->GetInputSlot(1));
711  inputLayer2->GetOutputSlot(0).SetTensorInfo(inputTensorInfo2);
712  equalLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
713  equalLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
714 
715  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
716  BOOST_CHECK(deserializedNetwork);
717 
718  LayerVerifierBase verifier(layerName, {inputTensorInfo1, inputTensorInfo2}, {outputTensorInfo});
719  deserializedNetwork->ExecuteStrategy(verifier);
720 }
721 
722 BOOST_AUTO_TEST_CASE(SerializeFill)
723 {
724  const std::string layerName("fill");
725  const armnn::TensorInfo inputInfo({4}, armnn::DataType::Signed32);
726  const armnn::TensorInfo outputInfo({1, 3, 3, 1}, armnn::DataType::Float32);
727 
728  armnn::FillDescriptor descriptor(1.0f);
729 
731  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
732  armnn::IConnectableLayer* const fillLayer = network->AddFillLayer(descriptor, layerName.c_str());
733  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
734 
735  inputLayer->GetOutputSlot(0).Connect(fillLayer->GetInputSlot(0));
736  fillLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
737 
738  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
739  fillLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
740 
741  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
742  BOOST_CHECK(deserializedNetwork);
743 
744  LayerVerifierBaseWithDescriptor<armnn::FillDescriptor> verifier(layerName, {inputInfo}, {outputInfo}, descriptor);
745 
746  deserializedNetwork->ExecuteStrategy(verifier);
747 }
748 
749 BOOST_AUTO_TEST_CASE(SerializeFloor)
750 {
751  const std::string layerName("floor");
753 
755  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
756  armnn::IConnectableLayer* const floorLayer = network->AddFloorLayer(layerName.c_str());
757  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
758 
759  inputLayer->GetOutputSlot(0).Connect(floorLayer->GetInputSlot(0));
760  floorLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
761 
762  inputLayer->GetOutputSlot(0).SetTensorInfo(info);
763  floorLayer->GetOutputSlot(0).SetTensorInfo(info);
764 
765  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
766  BOOST_CHECK(deserializedNetwork);
767 
768  LayerVerifierBase verifier(layerName, {info}, {info});
769  deserializedNetwork->ExecuteStrategy(verifier);
770 }
771 
772 BOOST_AUTO_TEST_CASE(SerializeFullyConnected)
773 {
774  const std::string layerName("fullyConnected");
775  const armnn::TensorInfo inputInfo ({ 2, 5, 1, 1 }, armnn::DataType::Float32);
776  const armnn::TensorInfo outputInfo({ 2, 3 }, armnn::DataType::Float32);
777 
778  const armnn::TensorInfo weightsInfo({ 5, 3 }, armnn::DataType::Float32);
779  const armnn::TensorInfo biasesInfo ({ 3 }, armnn::DataType::Float32);
780  std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
781  std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
782  armnn::ConstTensor weights(weightsInfo, weightsData);
783  armnn::ConstTensor biases(biasesInfo, biasesData);
784 
786  descriptor.m_BiasEnabled = true;
787  descriptor.m_TransposeWeightMatrix = false;
788  descriptor.m_ConstantWeights = true;
789 
791  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
792  armnn::IConnectableLayer* const fullyConnectedLayer =
793  network->AddFullyConnectedLayer(descriptor,
794  weights,
796  layerName.c_str());
797  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
798 
799  inputLayer->GetOutputSlot(0).Connect(fullyConnectedLayer->GetInputSlot(0));
800  fullyConnectedLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
801 
802  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
803  fullyConnectedLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
804 
805  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
806  BOOST_CHECK(deserializedNetwork);
807 
808  const std::vector<armnn::ConstTensor> constants {weights, biases};
810  layerName, {inputInfo}, {outputInfo}, descriptor, constants);
811  deserializedNetwork->ExecuteStrategy(verifier);
812 }
813 
814 BOOST_AUTO_TEST_CASE(SerializeFullyConnectedWeightsAsInputs)
815 {
816  const std::string layerName("fullyConnected_weights_as_inputs");
817  const armnn::TensorInfo inputInfo ({ 2, 5, 1, 1 }, armnn::DataType::Float32);
818  const armnn::TensorInfo outputInfo({ 2, 3 }, armnn::DataType::Float32);
819 
820  const armnn::TensorInfo weightsInfo({ 5, 3 }, armnn::DataType::Float32);
821  const armnn::TensorInfo biasesInfo ({ 3 }, armnn::DataType::Float32);
822 
825 
827  descriptor.m_BiasEnabled = true;
828  descriptor.m_TransposeWeightMatrix = false;
829  descriptor.m_ConstantWeights = false;
830 
832  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
833  armnn::IConnectableLayer* const weightsInputLayer = network->AddInputLayer(1);
834  armnn::IConnectableLayer* const biasInputLayer = network->AddInputLayer(2);
835  armnn::IConnectableLayer* const fullyConnectedLayer =
836  network->AddFullyConnectedLayer(descriptor,
837  weights,
838  bias,
839  layerName.c_str());
840  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
841 
842  inputLayer->GetOutputSlot(0).Connect(fullyConnectedLayer->GetInputSlot(0));
843  weightsInputLayer->GetOutputSlot(0).Connect(fullyConnectedLayer->GetInputSlot(1));
844  biasInputLayer->GetOutputSlot(0).Connect(fullyConnectedLayer->GetInputSlot(2));
845  fullyConnectedLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
846 
847  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
848  weightsInputLayer->GetOutputSlot(0).SetTensorInfo(weightsInfo);
849  biasInputLayer->GetOutputSlot(0).SetTensorInfo(biasesInfo);
850  fullyConnectedLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
851 
852  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
853  BOOST_CHECK(deserializedNetwork);
854 
855  const std::vector<armnn::ConstTensor> constants {};
857  layerName, {inputInfo, weightsInfo, biasesInfo}, {outputInfo}, descriptor, constants);
858  deserializedNetwork->ExecuteStrategy(verifier);
859 }
860 
861 BOOST_AUTO_TEST_CASE(SerializeGather)
862 {
864  class GatherLayerVerifier : public LayerVerifierBaseWithDescriptor<GatherDescriptor>
865  {
866  public:
867  GatherLayerVerifier(const std::string& layerName,
868  const std::vector<armnn::TensorInfo>& inputInfos,
869  const std::vector<armnn::TensorInfo>& outputInfos,
870  const GatherDescriptor& descriptor)
871  : LayerVerifierBaseWithDescriptor<GatherDescriptor>(layerName, inputInfos, outputInfos, descriptor) {}
872 
873  void ExecuteStrategy(const armnn::IConnectableLayer* layer,
874  const armnn::BaseDescriptor& descriptor,
875  const std::vector<armnn::ConstTensor>& constants,
876  const char* name,
877  const armnn::LayerBindingId id = 0) override
878  {
879  armnn::IgnoreUnused(constants, id);
880  switch (layer->GetType())
881  {
882  case armnn::LayerType::Input: break;
883  case armnn::LayerType::Output: break;
884  case armnn::LayerType::Constant: break;
885  default:
886  {
887  VerifyNameAndConnections(layer, name);
888  const GatherDescriptor& layerDescriptor = static_cast<const GatherDescriptor&>(descriptor);
889  BOOST_CHECK(layerDescriptor.m_Axis == m_Descriptor.m_Axis);
890  }
891  }
892  }
893  };
894 
895  const std::string layerName("gather");
896  armnn::TensorInfo paramsInfo({ 8 }, armnn::DataType::QAsymmU8);
897  armnn::TensorInfo outputInfo({ 3 }, armnn::DataType::QAsymmU8);
898  const armnn::TensorInfo indicesInfo({ 3 }, armnn::DataType::Signed32);
899  GatherDescriptor descriptor;
900  descriptor.m_Axis = 1;
901 
902  paramsInfo.SetQuantizationScale(1.0f);
903  paramsInfo.SetQuantizationOffset(0);
904  outputInfo.SetQuantizationScale(1.0f);
905  outputInfo.SetQuantizationOffset(0);
906 
907  const std::vector<int32_t>& indicesData = {7, 6, 5};
908 
910  armnn::IConnectableLayer *const inputLayer = network->AddInputLayer(0);
911  armnn::IConnectableLayer *const constantLayer =
912  network->AddConstantLayer(armnn::ConstTensor(indicesInfo, indicesData));
913  armnn::IConnectableLayer *const gatherLayer = network->AddGatherLayer(descriptor, layerName.c_str());
914  armnn::IConnectableLayer *const outputLayer = network->AddOutputLayer(0);
915 
916  inputLayer->GetOutputSlot(0).Connect(gatherLayer->GetInputSlot(0));
917  constantLayer->GetOutputSlot(0).Connect(gatherLayer->GetInputSlot(1));
918  gatherLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
919 
920  inputLayer->GetOutputSlot(0).SetTensorInfo(paramsInfo);
921  constantLayer->GetOutputSlot(0).SetTensorInfo(indicesInfo);
922  gatherLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
923 
924  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
925  BOOST_CHECK(deserializedNetwork);
926 
927  GatherLayerVerifier verifier(layerName, {paramsInfo, indicesInfo}, {outputInfo}, descriptor);
928  deserializedNetwork->ExecuteStrategy(verifier);
929 }
930 
931 
932 // NOTE: Until the deprecated AddGreaterLayer disappears this test checks that calling
933 // AddGreaterLayer places a ComparisonLayer into the serialized format and that
934 // when this deserialises we have a ComparisonLayer
935 BOOST_AUTO_TEST_CASE(SerializeGreaterDeprecated)
936 {
937  const std::string layerName("greater");
938 
939  const armnn::TensorShape shape{2, 1, 2, 4};
940 
943 
945  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
946  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
948  armnn::IConnectableLayer* const equalLayer = network->AddGreaterLayer(layerName.c_str());
950  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
951 
952  inputLayer0->GetOutputSlot(0).Connect(equalLayer->GetInputSlot(0));
953  inputLayer1->GetOutputSlot(0).Connect(equalLayer->GetInputSlot(1));
954  equalLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
955 
956  inputLayer0->GetOutputSlot(0).SetTensorInfo(inputInfo);
957  inputLayer1->GetOutputSlot(0).SetTensorInfo(inputInfo);
958  equalLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
959 
960  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
961  BOOST_CHECK(deserializedNetwork);
962 
963  LayerVerifierBase verifier(layerName, { inputInfo, inputInfo }, { outputInfo });
964  deserializedNetwork->ExecuteStrategy(verifier);
965 }
966 
967 
968 BOOST_AUTO_TEST_CASE(SerializeInstanceNormalization)
969 {
970  const std::string layerName("instanceNormalization");
971  const armnn::TensorInfo info({ 1, 2, 1, 5 }, armnn::DataType::Float32);
972 
974  descriptor.m_Gamma = 1.1f;
975  descriptor.m_Beta = 0.1f;
976  descriptor.m_Eps = 0.0001f;
977  descriptor.m_DataLayout = armnn::DataLayout::NHWC;
978 
980  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
981  armnn::IConnectableLayer* const instanceNormLayer =
982  network->AddInstanceNormalizationLayer(descriptor, layerName.c_str());
983  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
984 
985  inputLayer->GetOutputSlot(0).Connect(instanceNormLayer->GetInputSlot(0));
986  instanceNormLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
987 
988  inputLayer->GetOutputSlot(0).SetTensorInfo(info);
989  instanceNormLayer->GetOutputSlot(0).SetTensorInfo(info);
990 
991  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
992  BOOST_CHECK(deserializedNetwork);
993 
995  layerName, {info}, {info}, descriptor);
996  deserializedNetwork->ExecuteStrategy(verifier);
997 }
998 
999 BOOST_AUTO_TEST_CASE(SerializeL2Normalization)
1000 {
1001  const std::string l2NormLayerName("l2Normalization");
1002  const armnn::TensorInfo info({1, 2, 1, 5}, armnn::DataType::Float32);
1003 
1006  desc.m_Eps = 0.0001f;
1007 
1009  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1010  armnn::IConnectableLayer* const l2NormLayer = network->AddL2NormalizationLayer(desc, l2NormLayerName.c_str());
1011  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1012 
1013  inputLayer0->GetOutputSlot(0).Connect(l2NormLayer->GetInputSlot(0));
1014  l2NormLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1015 
1016  inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
1017  l2NormLayer->GetOutputSlot(0).SetTensorInfo(info);
1018 
1019  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1020  BOOST_CHECK(deserializedNetwork);
1021 
1023  l2NormLayerName, {info}, {info}, desc);
1024  deserializedNetwork->ExecuteStrategy(verifier);
1025 }
1026 
1027 BOOST_AUTO_TEST_CASE(EnsureL2NormalizationBackwardCompatibility)
1028 {
1029  // The hex data below is a flat buffer containing a simple network with one input
1030  // a L2Normalization layer and an output layer with dimensions as per the tensor infos below.
1031  //
1032  // This test verifies that we can still read back these old style
1033  // models without the normalization epsilon value.
1034  const std::vector<uint8_t> l2NormalizationModel =
1035  {
1036  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x0A, 0x00,
1037  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1038  0x3C, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
1039  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xE8, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0B,
1040  0x04, 0x00, 0x00, 0x00, 0xD6, 0xFE, 0xFF, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00,
1041  0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x9E, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00,
1042  0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
1043  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1044  0x4C, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
1045  0x00, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00,
1046  0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
1047  0x0E, 0x00, 0x18, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0E, 0x00, 0x00, 0x00,
1048  0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x20, 0x00,
1049  0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x6C, 0x32, 0x4E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x69, 0x7A, 0x61, 0x74,
1050  0x69, 0x6F, 0x6E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00,
1051  0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1052  0x52, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
1053  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1054  0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1055  0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
1056  0x04, 0x00, 0x00, 0x00, 0xF6, 0xFF, 0xFF, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0A, 0x00,
1057  0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x14, 0x00, 0x00, 0x00,
1058  0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
1059  0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1060  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x00, 0x00,
1061  0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x08, 0x00,
1062  0x07, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
1063  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1064  0x05, 0x00, 0x00, 0x00, 0x00
1065  };
1066 
1067  armnn::INetworkPtr deserializedNetwork =
1068  DeserializeNetwork(std::string(l2NormalizationModel.begin(), l2NormalizationModel.end()));
1069  BOOST_CHECK(deserializedNetwork);
1070 
1071  const std::string layerName("l2Normalization");
1072  const armnn::TensorInfo inputInfo = armnn::TensorInfo({1, 2, 1, 5}, armnn::DataType::Float32);
1073 
1076  // Since this variable does not exist in the l2NormalizationModel dump, the default value will be loaded
1077  desc.m_Eps = 1e-12f;
1078 
1080  layerName, {inputInfo}, {inputInfo}, desc);
1081  deserializedNetwork->ExecuteStrategy(verifier);
1082 }
1083 
1084 BOOST_AUTO_TEST_CASE(SerializeLogicalBinary)
1085 {
1086  const std::string layerName("logicalBinaryAnd");
1087 
1088  const armnn::TensorShape shape{2, 1, 2, 2};
1089 
1092 
1094 
1096  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1097  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
1098  armnn::IConnectableLayer* const logicalBinaryLayer = network->AddLogicalBinaryLayer(descriptor, layerName.c_str());
1099  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1100 
1101  inputLayer0->GetOutputSlot(0).Connect(logicalBinaryLayer->GetInputSlot(0));
1102  inputLayer1->GetOutputSlot(0).Connect(logicalBinaryLayer->GetInputSlot(1));
1103  logicalBinaryLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1104 
1105  inputLayer0->GetOutputSlot(0).SetTensorInfo(inputInfo);
1106  inputLayer1->GetOutputSlot(0).SetTensorInfo(inputInfo);
1107  logicalBinaryLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1108 
1109  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1110  BOOST_CHECK(deserializedNetwork);
1111 
1113  layerName, { inputInfo, inputInfo }, { outputInfo }, descriptor);
1114  deserializedNetwork->ExecuteStrategy(verifier);
1115 }
1116 
1117 BOOST_AUTO_TEST_CASE(SerializeLogicalUnary)
1118 {
1119  const std::string layerName("elementwiseUnaryLogicalNot");
1120 
1121  const armnn::TensorShape shape{2, 1, 2, 2};
1122 
1125 
1127 
1129  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1130  armnn::IConnectableLayer* const elementwiseUnaryLayer =
1131  network->AddElementwiseUnaryLayer(descriptor, layerName.c_str());
1132  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1133 
1134  inputLayer->GetOutputSlot(0).Connect(elementwiseUnaryLayer->GetInputSlot(0));
1135  elementwiseUnaryLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1136 
1137  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1138  elementwiseUnaryLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1139 
1140  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1141 
1142  BOOST_CHECK(deserializedNetwork);
1143 
1145  layerName, { inputInfo }, { outputInfo }, descriptor);
1146 
1147  deserializedNetwork->ExecuteStrategy(verifier);
1148 }
1149 
1150 BOOST_AUTO_TEST_CASE(SerializeLogSoftmax)
1151 {
1152  const std::string layerName("log_softmax");
1154 
1155  armnn::LogSoftmaxDescriptor descriptor;
1156  descriptor.m_Beta = 1.0f;
1157  descriptor.m_Axis = -1;
1158 
1160  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1161  armnn::IConnectableLayer* const logSoftmaxLayer = network->AddLogSoftmaxLayer(descriptor, layerName.c_str());
1162  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1163 
1164  inputLayer->GetOutputSlot(0).Connect(logSoftmaxLayer->GetInputSlot(0));
1165  logSoftmaxLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1166 
1167  inputLayer->GetOutputSlot(0).SetTensorInfo(info);
1168  logSoftmaxLayer->GetOutputSlot(0).SetTensorInfo(info);
1169 
1170  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1171  BOOST_CHECK(deserializedNetwork);
1172 
1173  LayerVerifierBaseWithDescriptor<armnn::LogSoftmaxDescriptor> verifier(layerName, {info}, {info}, descriptor);
1174  deserializedNetwork->ExecuteStrategy(verifier);
1175 }
1176 
1177 BOOST_AUTO_TEST_CASE(SerializeMaximum)
1178 {
1179  const std::string layerName("maximum");
1180  const armnn::TensorInfo info({ 1, 2, 2, 3 }, armnn::DataType::Float32);
1181 
1183  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1184  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
1185  armnn::IConnectableLayer* const maximumLayer = network->AddMaximumLayer(layerName.c_str());
1186  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1187 
1188  inputLayer0->GetOutputSlot(0).Connect(maximumLayer->GetInputSlot(0));
1189  inputLayer1->GetOutputSlot(0).Connect(maximumLayer->GetInputSlot(1));
1190  maximumLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1191 
1192  inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
1193  inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
1194  maximumLayer->GetOutputSlot(0).SetTensorInfo(info);
1195 
1196  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1197  BOOST_CHECK(deserializedNetwork);
1198 
1199  LayerVerifierBase verifier(layerName, {info, info}, {info});
1200  deserializedNetwork->ExecuteStrategy(verifier);
1201 }
1202 
1203 BOOST_AUTO_TEST_CASE(SerializeMean)
1204 {
1205  const std::string layerName("mean");
1206  const armnn::TensorInfo inputInfo({1, 1, 3, 2}, armnn::DataType::Float32);
1207  const armnn::TensorInfo outputInfo({1, 1, 1, 2}, armnn::DataType::Float32);
1208 
1209  armnn::MeanDescriptor descriptor;
1210  descriptor.m_Axis = { 2 };
1211  descriptor.m_KeepDims = true;
1212 
1214  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1215  armnn::IConnectableLayer* const meanLayer = network->AddMeanLayer(descriptor, layerName.c_str());
1216  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1217 
1218  inputLayer->GetOutputSlot(0).Connect(meanLayer->GetInputSlot(0));
1219  meanLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1220 
1221  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1222  meanLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1223 
1224  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1225  BOOST_CHECK(deserializedNetwork);
1226 
1227  LayerVerifierBaseWithDescriptor<armnn::MeanDescriptor> verifier(layerName, {inputInfo}, {outputInfo}, descriptor);
1228  deserializedNetwork->ExecuteStrategy(verifier);
1229 }
1230 
1231 BOOST_AUTO_TEST_CASE(SerializeMerge)
1232 {
1233  const std::string layerName("merge");
1234  const armnn::TensorInfo info({ 1, 2, 2, 3 }, armnn::DataType::Float32);
1235 
1237  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1238  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
1239  armnn::IConnectableLayer* const mergeLayer = network->AddMergeLayer(layerName.c_str());
1240  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1241 
1242  inputLayer0->GetOutputSlot(0).Connect(mergeLayer->GetInputSlot(0));
1243  inputLayer1->GetOutputSlot(0).Connect(mergeLayer->GetInputSlot(1));
1244  mergeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1245 
1246  inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
1247  inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
1248  mergeLayer->GetOutputSlot(0).SetTensorInfo(info);
1249 
1250  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1251  BOOST_CHECK(deserializedNetwork);
1252 
1253  LayerVerifierBase verifier(layerName, {info, info}, {info});
1254  deserializedNetwork->ExecuteStrategy(verifier);
1255 }
1256 
1257 class MergerLayerVerifier : public LayerVerifierBaseWithDescriptor<armnn::OriginsDescriptor>
1258 {
1259 public:
1260  MergerLayerVerifier(const std::string& layerName,
1261  const std::vector<armnn::TensorInfo>& inputInfos,
1262  const std::vector<armnn::TensorInfo>& outputInfos,
1263  const armnn::OriginsDescriptor& descriptor)
1264  : LayerVerifierBaseWithDescriptor<armnn::OriginsDescriptor>(layerName, inputInfos, outputInfos, descriptor) {}
1265 
1266  void ExecuteStrategy(const armnn::IConnectableLayer* layer,
1267  const armnn::BaseDescriptor& descriptor,
1268  const std::vector<armnn::ConstTensor>& constants,
1269  const char* name,
1270  const armnn::LayerBindingId id = 0) override
1271  {
1272  armnn::IgnoreUnused(descriptor, constants, id);
1273  switch (layer->GetType())
1274  {
1275  case armnn::LayerType::Input: break;
1276  case armnn::LayerType::Output: break;
1278  {
1279  throw armnn::Exception("MergerLayer should have translated to ConcatLayer");
1280  break;
1281  }
1283  {
1284  VerifyNameAndConnections(layer, name);
1285  const armnn::MergerDescriptor& layerDescriptor =
1286  static_cast<const armnn::MergerDescriptor&>(descriptor);
1287  VerifyDescriptor(layerDescriptor);
1288  break;
1289  }
1290  default:
1291  {
1292  throw armnn::Exception("Unexpected layer type in Merge test model");
1293  }
1294  }
1295  }
1296 };
1297 
1298 // NOTE: Until the deprecated AddMergerLayer disappears this test checks that calling
1299 // AddMergerLayer places a ConcatLayer into the serialized format and that
1300 // when this deserialises we have a ConcatLayer
1301 BOOST_AUTO_TEST_CASE(SerializeMerger)
1302 {
1303  const std::string layerName("merger");
1304  const armnn::TensorInfo inputInfo = armnn::TensorInfo({2, 3, 2, 2}, armnn::DataType::Float32);
1305  const armnn::TensorInfo outputInfo = armnn::TensorInfo({4, 3, 2, 2}, armnn::DataType::Float32);
1306 
1307  const std::vector<armnn::TensorShape> shapes({inputInfo.GetShape(), inputInfo.GetShape()});
1308 
1309  armnn::OriginsDescriptor descriptor =
1310  armnn::CreateDescriptorForConcatenation(shapes.begin(), shapes.end(), 0);
1311 
1313  armnn::IConnectableLayer* const inputLayerOne = network->AddInputLayer(0);
1314  armnn::IConnectableLayer* const inputLayerTwo = network->AddInputLayer(1);
1316  armnn::IConnectableLayer* const mergerLayer = network->AddMergerLayer(descriptor, layerName.c_str());
1318  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1319 
1320  inputLayerOne->GetOutputSlot(0).Connect(mergerLayer->GetInputSlot(0));
1321  inputLayerTwo->GetOutputSlot(0).Connect(mergerLayer->GetInputSlot(1));
1322  mergerLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1323 
1324  inputLayerOne->GetOutputSlot(0).SetTensorInfo(inputInfo);
1325  inputLayerTwo->GetOutputSlot(0).SetTensorInfo(inputInfo);
1326  mergerLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1327 
1328  std::string mergerLayerNetwork = SerializeNetwork(*network);
1329  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(mergerLayerNetwork);
1330  BOOST_CHECK(deserializedNetwork);
1331 
1332  MergerLayerVerifier verifier(layerName, {inputInfo, inputInfo}, {outputInfo}, descriptor);
1333  deserializedNetwork->ExecuteStrategy(verifier);
1334 }
1335 
1336 BOOST_AUTO_TEST_CASE(EnsureMergerLayerBackwardCompatibility)
1337 {
1338  // The hex data below is a flat buffer containing a simple network with two inputs
1339  // a merger layer (now deprecated) and an output layer with dimensions as per the tensor infos below.
1340  //
1341  // This test verifies that we can still read back these old style
1342  // models replacing the MergerLayers with ConcatLayers with the same parameters.
1343  const std::vector<uint8_t> mergerModel =
1344  {
1345  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x0A, 0x00,
1346  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1347  0x38, 0x02, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00,
1348  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1349  0xF4, 0xFD, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0B, 0x04, 0x00, 0x00, 0x00, 0x92, 0xFE, 0xFF, 0xFF, 0x04, 0x00,
1350  0x00, 0x00, 0x9A, 0xFE, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x7E, 0xFE, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
1351  0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
1352  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1353  0xF8, 0xFE, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xFE, 0xFF, 0xFF, 0x00, 0x00,
1354  0x00, 0x1F, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00,
1355  0x68, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00,
1356  0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1357  0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x22, 0xFF, 0xFF, 0xFF, 0x04, 0x00,
1358  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1359  0x00, 0x00, 0x00, 0x00, 0x3E, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
1360  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xFF, 0xFF, 0xFF,
1361  0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1C, 0x00,
1362  0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6D, 0x65, 0x72, 0x67, 0x65, 0x72, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1363  0x5C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x34, 0xFF,
1364  0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x92, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
1365  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00,
1366  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00,
1367  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00,
1368  0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0E, 0x00,
1369  0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
1370  0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0E, 0x00,
1371  0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
1372  0x0E, 0x00, 0x18, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0E, 0x00, 0x00, 0x00,
1373  0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00,
1374  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1375  0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00,
1376  0x00, 0x00, 0x66, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1377  0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00,
1378  0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
1379  0x04, 0x00, 0x00, 0x00, 0xF6, 0xFF, 0xFF, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0A, 0x00,
1380  0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x14, 0x00, 0x00, 0x00,
1381  0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
1382  0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1383  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x00, 0x00,
1384  0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x08, 0x00,
1385  0x07, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
1386  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1387  0x02, 0x00, 0x00, 0x00
1388  };
1389 
1390  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(std::string(mergerModel.begin(), mergerModel.end()));
1391  BOOST_CHECK(deserializedNetwork);
1392 
1393  const armnn::TensorInfo inputInfo = armnn::TensorInfo({ 2, 3, 2, 2 }, armnn::DataType::Float32);
1394  const armnn::TensorInfo outputInfo = armnn::TensorInfo({ 4, 3, 2, 2 }, armnn::DataType::Float32);
1395 
1396  const std::vector<armnn::TensorShape> shapes({inputInfo.GetShape(), inputInfo.GetShape()});
1397 
1398  armnn::OriginsDescriptor descriptor =
1399  armnn::CreateDescriptorForConcatenation(shapes.begin(), shapes.end(), 0);
1400 
1401  MergerLayerVerifier verifier("merger", { inputInfo, inputInfo }, { outputInfo }, descriptor);
1402  deserializedNetwork->ExecuteStrategy(verifier);
1403 }
1404 
1405 BOOST_AUTO_TEST_CASE(SerializeConcat)
1406 {
1407  const std::string layerName("concat");
1408  const armnn::TensorInfo inputInfo = armnn::TensorInfo({2, 3, 2, 2}, armnn::DataType::Float32);
1409  const armnn::TensorInfo outputInfo = armnn::TensorInfo({4, 3, 2, 2}, armnn::DataType::Float32);
1410 
1411  const std::vector<armnn::TensorShape> shapes({inputInfo.GetShape(), inputInfo.GetShape()});
1412 
1413  armnn::OriginsDescriptor descriptor =
1414  armnn::CreateDescriptorForConcatenation(shapes.begin(), shapes.end(), 0);
1415 
1417  armnn::IConnectableLayer* const inputLayerOne = network->AddInputLayer(0);
1418  armnn::IConnectableLayer* const inputLayerTwo = network->AddInputLayer(1);
1419  armnn::IConnectableLayer* const concatLayer = network->AddConcatLayer(descriptor, layerName.c_str());
1420  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1421 
1422  inputLayerOne->GetOutputSlot(0).Connect(concatLayer->GetInputSlot(0));
1423  inputLayerTwo->GetOutputSlot(0).Connect(concatLayer->GetInputSlot(1));
1424  concatLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1425 
1426  inputLayerOne->GetOutputSlot(0).SetTensorInfo(inputInfo);
1427  inputLayerTwo->GetOutputSlot(0).SetTensorInfo(inputInfo);
1428  concatLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1429 
1430  std::string concatLayerNetwork = SerializeNetwork(*network);
1431  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(concatLayerNetwork);
1432  BOOST_CHECK(deserializedNetwork);
1433 
1434  // NOTE: using the MergerLayerVerifier to ensure that it is a concat layer and not a
1435  // merger layer that gets placed into the graph.
1436  MergerLayerVerifier verifier(layerName, {inputInfo, inputInfo}, {outputInfo}, descriptor);
1437  deserializedNetwork->ExecuteStrategy(verifier);
1438 }
1439 
1440 BOOST_AUTO_TEST_CASE(SerializeMinimum)
1441 {
1442  const std::string layerName("minimum");
1443  const armnn::TensorInfo info({ 1, 2, 2, 3 }, armnn::DataType::Float32);
1444 
1446  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1447  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
1448  armnn::IConnectableLayer* const minimumLayer = network->AddMinimumLayer(layerName.c_str());
1449  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1450 
1451  inputLayer0->GetOutputSlot(0).Connect(minimumLayer->GetInputSlot(0));
1452  inputLayer1->GetOutputSlot(0).Connect(minimumLayer->GetInputSlot(1));
1453  minimumLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1454 
1455  inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
1456  inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
1457  minimumLayer->GetOutputSlot(0).SetTensorInfo(info);
1458 
1459  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1460  BOOST_CHECK(deserializedNetwork);
1461 
1462  LayerVerifierBase verifier(layerName, {info, info}, {info});
1463  deserializedNetwork->ExecuteStrategy(verifier);
1464 }
1465 
1466 BOOST_AUTO_TEST_CASE(SerializeMultiplication)
1467 {
1468  const std::string layerName("multiplication");
1469  const armnn::TensorInfo info({ 1, 5, 2, 3 }, armnn::DataType::Float32);
1470 
1472  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1473  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
1474  armnn::IConnectableLayer* const multiplicationLayer = network->AddMultiplicationLayer(layerName.c_str());
1475  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1476 
1477  inputLayer0->GetOutputSlot(0).Connect(multiplicationLayer->GetInputSlot(0));
1478  inputLayer1->GetOutputSlot(0).Connect(multiplicationLayer->GetInputSlot(1));
1479  multiplicationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1480 
1481  inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
1482  inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
1483  multiplicationLayer->GetOutputSlot(0).SetTensorInfo(info);
1484 
1485  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1486  BOOST_CHECK(deserializedNetwork);
1487 
1488  LayerVerifierBase verifier(layerName, {info, info}, {info});
1489  deserializedNetwork->ExecuteStrategy(verifier);
1490 }
1491 
1492 BOOST_AUTO_TEST_CASE(SerializePrelu)
1493 {
1494  const std::string layerName("prelu");
1495 
1496  armnn::TensorInfo inputTensorInfo ({ 4, 1, 2 }, armnn::DataType::Float32);
1497  armnn::TensorInfo alphaTensorInfo ({ 5, 4, 3, 1 }, armnn::DataType::Float32);
1498  armnn::TensorInfo outputTensorInfo({ 5, 4, 3, 2 }, armnn::DataType::Float32);
1499 
1501  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1502  armnn::IConnectableLayer* const alphaLayer = network->AddInputLayer(1);
1503  armnn::IConnectableLayer* const preluLayer = network->AddPreluLayer(layerName.c_str());
1504  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1505 
1506  inputLayer->GetOutputSlot(0).Connect(preluLayer->GetInputSlot(0));
1507  alphaLayer->GetOutputSlot(0).Connect(preluLayer->GetInputSlot(1));
1508  preluLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1509 
1510  inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
1511  alphaLayer->GetOutputSlot(0).SetTensorInfo(alphaTensorInfo);
1512  preluLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1513 
1514  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1515  BOOST_CHECK(deserializedNetwork);
1516 
1517  LayerVerifierBase verifier(layerName, {inputTensorInfo, alphaTensorInfo}, {outputTensorInfo});
1518  deserializedNetwork->ExecuteStrategy(verifier);
1519 }
1520 
1521 BOOST_AUTO_TEST_CASE(SerializeNormalization)
1522 {
1523  const std::string layerName("normalization");
1524  const armnn::TensorInfo info({2, 1, 2, 2}, armnn::DataType::Float32);
1525 
1528  desc.m_NormSize = 3;
1529  desc.m_Alpha = 1;
1530  desc.m_Beta = 1;
1531  desc.m_K = 1;
1532 
1534  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1535  armnn::IConnectableLayer* const normalizationLayer = network->AddNormalizationLayer(desc, layerName.c_str());
1536  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1537 
1538  inputLayer->GetOutputSlot(0).Connect(normalizationLayer->GetInputSlot(0));
1539  normalizationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1540 
1541  inputLayer->GetOutputSlot(0).SetTensorInfo(info);
1542  normalizationLayer->GetOutputSlot(0).SetTensorInfo(info);
1543 
1544  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1545  BOOST_CHECK(deserializedNetwork);
1546 
1548  deserializedNetwork->ExecuteStrategy(verifier);
1549 }
1550 
1552 {
1553  const std::string layerName("pad");
1554  const armnn::TensorInfo inputTensorInfo = armnn::TensorInfo({1, 2, 3, 4}, armnn::DataType::Float32);
1555  const armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({1, 3, 5, 7}, armnn::DataType::Float32);
1556 
1557  armnn::PadDescriptor desc({{0, 0}, {1, 0}, {1, 1}, {1, 2}});
1558 
1560  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1561  armnn::IConnectableLayer* const padLayer = network->AddPadLayer(desc, layerName.c_str());
1562  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1563 
1564  inputLayer->GetOutputSlot(0).Connect(padLayer->GetInputSlot(0));
1565  padLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1566 
1567  inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
1568  padLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1569 
1570  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1571  BOOST_CHECK(deserializedNetwork);
1572 
1574  {inputTensorInfo},
1575  {outputTensorInfo},
1576  desc);
1577  deserializedNetwork->ExecuteStrategy(verifier);
1578 }
1579 
1580 BOOST_AUTO_TEST_CASE(EnsurePadBackwardCompatibility)
1581 {
1582  // The PadDescriptor is being extended with a float PadValue (so a value other than 0
1583  // can be used to pad the tensor.
1584  //
1585  // This test contains a binary representation of a simple input->pad->output network
1586  // prior to this change to test that the descriptor has been updated in a backward
1587  // compatible way with respect to Deserialization of older binary dumps
1588  const std::vector<uint8_t> padModel =
1589  {
1590  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x0A, 0x00,
1591  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1592  0x54, 0x01, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
1593  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xD0, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0B,
1594  0x04, 0x00, 0x00, 0x00, 0x96, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x9E, 0xFF, 0xFF, 0xFF, 0x04, 0x00,
1595  0x00, 0x00, 0x72, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1596  0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
1597  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
1598  0x00, 0x00, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x16, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00,
1599  0x0E, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
1600  0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00,
1601  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1602  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
1603  0x0E, 0x00, 0x18, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0E, 0x00, 0x00, 0x00,
1604  0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00,
1605  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
1606  0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00,
1607  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x52, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
1608  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00,
1609  0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
1610  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00,
1611  0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x00, 0xF6, 0xFF, 0xFF, 0xFF, 0x0C, 0x00, 0x00, 0x00,
1612  0x00, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
1613  0x0E, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x00,
1614  0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
1615  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
1616  0x08, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
1617  0x0A, 0x00, 0x10, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1618  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
1619  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00
1620  };
1621 
1622  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(std::string(padModel.begin(), padModel.end()));
1623  BOOST_CHECK(deserializedNetwork);
1624 
1625  const armnn::TensorInfo inputInfo = armnn::TensorInfo({ 1, 2, 3, 4 }, armnn::DataType::Float32);
1626  const armnn::TensorInfo outputInfo = armnn::TensorInfo({ 1, 3, 5, 7 }, armnn::DataType::Float32);
1627 
1628  armnn::PadDescriptor descriptor({{ 0, 0 }, { 1, 0 }, { 1, 1 }, { 1, 2 }});
1629 
1630  LayerVerifierBaseWithDescriptor<armnn::PadDescriptor> verifier("pad", { inputInfo }, { outputInfo }, descriptor);
1631  deserializedNetwork->ExecuteStrategy(verifier);
1632 }
1633 
1634 BOOST_AUTO_TEST_CASE(SerializePermute)
1635 {
1636  const std::string layerName("permute");
1637  const armnn::TensorInfo inputTensorInfo({4, 3, 2, 1}, armnn::DataType::Float32);
1638  const armnn::TensorInfo outputTensorInfo({1, 2, 3, 4}, armnn::DataType::Float32);
1639 
1640  armnn::PermuteDescriptor descriptor(armnn::PermutationVector({3, 2, 1, 0}));
1641 
1643  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1644  armnn::IConnectableLayer* const permuteLayer = network->AddPermuteLayer(descriptor, layerName.c_str());
1645  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1646 
1647  inputLayer->GetOutputSlot(0).Connect(permuteLayer->GetInputSlot(0));
1648  permuteLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1649 
1650  inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
1651  permuteLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1652 
1653  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1654  BOOST_CHECK(deserializedNetwork);
1655 
1657  layerName, {inputTensorInfo}, {outputTensorInfo}, descriptor);
1658  deserializedNetwork->ExecuteStrategy(verifier);
1659 }
1660 
1661 BOOST_AUTO_TEST_CASE(SerializePooling2d)
1662 {
1663  const std::string layerName("pooling2d");
1664  const armnn::TensorInfo inputInfo({1, 2, 2, 1}, armnn::DataType::Float32);
1665  const armnn::TensorInfo outputInfo({1, 1, 1, 1}, armnn::DataType::Float32);
1666 
1669  desc.m_PadTop = 0;
1670  desc.m_PadBottom = 0;
1671  desc.m_PadLeft = 0;
1672  desc.m_PadRight = 0;
1673  desc.m_PoolType = armnn::PoolingAlgorithm::Average;
1674  desc.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
1675  desc.m_PaddingMethod = armnn::PaddingMethod::Exclude;
1676  desc.m_PoolHeight = 2;
1677  desc.m_PoolWidth = 2;
1678  desc.m_StrideX = 2;
1679  desc.m_StrideY = 2;
1680 
1682  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1683  armnn::IConnectableLayer* const pooling2dLayer = network->AddPooling2dLayer(desc, layerName.c_str());
1684  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1685 
1686  inputLayer->GetOutputSlot(0).Connect(pooling2dLayer->GetInputSlot(0));
1687  pooling2dLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1688 
1689  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1690  pooling2dLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1691 
1692  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1693  BOOST_CHECK(deserializedNetwork);
1694 
1696  layerName, {inputInfo}, {outputInfo}, desc);
1697  deserializedNetwork->ExecuteStrategy(verifier);
1698 }
1699 
1700 BOOST_AUTO_TEST_CASE(SerializeQuantize)
1701 {
1702  const std::string layerName("quantize");
1703  const armnn::TensorInfo info({ 1, 2, 2, 3 }, armnn::DataType::Float32);
1704 
1706  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1707  armnn::IConnectableLayer* const quantizeLayer = network->AddQuantizeLayer(layerName.c_str());
1708  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1709 
1710  inputLayer->GetOutputSlot(0).Connect(quantizeLayer->GetInputSlot(0));
1711  quantizeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1712 
1713  inputLayer->GetOutputSlot(0).SetTensorInfo(info);
1714  quantizeLayer->GetOutputSlot(0).SetTensorInfo(info);
1715 
1716  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1717  BOOST_CHECK(deserializedNetwork);
1718 
1719  LayerVerifierBase verifier(layerName, {info}, {info});
1720  deserializedNetwork->ExecuteStrategy(verifier);
1721 }
1722 
1723 BOOST_AUTO_TEST_CASE(SerializeRank)
1724 {
1725  const std::string layerName("rank");
1726  const armnn::TensorInfo inputInfo({1, 9}, armnn::DataType::Float32);
1727  const armnn::TensorInfo outputInfo({1}, armnn::DataType::Signed32);
1728 
1730  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1731  armnn::IConnectableLayer* const rankLayer = network->AddRankLayer(layerName.c_str());
1732  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1733 
1734  inputLayer->GetOutputSlot(0).Connect(rankLayer->GetInputSlot(0));
1735  rankLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1736 
1737  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1738  rankLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1739 
1740  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1741  BOOST_CHECK(deserializedNetwork);
1742 
1743  LayerVerifierBase verifier(layerName, {inputInfo}, {outputInfo});
1744  deserializedNetwork->ExecuteStrategy(verifier);
1745 }
1746 
1747 BOOST_AUTO_TEST_CASE(SerializeReduceSum)
1748 {
1749  const std::string layerName("Reduce_Sum");
1750  const armnn::TensorInfo inputInfo({1, 1, 3, 2}, armnn::DataType::Float32);
1751  const armnn::TensorInfo outputInfo({1, 1, 1, 2}, armnn::DataType::Float32);
1752 
1753  armnn::ReduceDescriptor descriptor;
1754  descriptor.m_vAxis = { 2 };
1755  descriptor.m_ReduceOperation = armnn::ReduceOperation::Sum;
1756 
1758  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1759  armnn::IConnectableLayer* const reduceSumLayer = network->AddReduceLayer(descriptor, layerName.c_str());
1760  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1761 
1762  inputLayer->GetOutputSlot(0).Connect(reduceSumLayer->GetInputSlot(0));
1763  reduceSumLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1764 
1765  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1766  reduceSumLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1767 
1768  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1769  BOOST_CHECK(deserializedNetwork);
1770 
1771  LayerVerifierBaseWithDescriptor<armnn::ReduceDescriptor> verifier(layerName, {inputInfo}, {outputInfo}, descriptor);
1772  deserializedNetwork->ExecuteStrategy(verifier);
1773 }
1774 
1775 BOOST_AUTO_TEST_CASE(SerializeReshape)
1776 {
1777  const std::string layerName("reshape");
1778  const armnn::TensorInfo inputInfo({1, 9}, armnn::DataType::Float32);
1779  const armnn::TensorInfo outputInfo({3, 3}, armnn::DataType::Float32);
1780 
1781  armnn::ReshapeDescriptor descriptor({3, 3});
1782 
1784  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1785  armnn::IConnectableLayer* const reshapeLayer = network->AddReshapeLayer(descriptor, layerName.c_str());
1786  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1787 
1788  inputLayer->GetOutputSlot(0).Connect(reshapeLayer->GetInputSlot(0));
1789  reshapeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1790 
1791  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1792  reshapeLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1793 
1794  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1795  BOOST_CHECK(deserializedNetwork);
1796 
1798  layerName, {inputInfo}, {outputInfo}, descriptor);
1799  deserializedNetwork->ExecuteStrategy(verifier);
1800 }
1801 
1802 BOOST_AUTO_TEST_CASE(SerializeResize)
1803 {
1804  const std::string layerName("resize");
1805  const armnn::TensorInfo inputInfo = armnn::TensorInfo({1, 3, 5, 5}, armnn::DataType::Float32);
1806  const armnn::TensorInfo outputInfo = armnn::TensorInfo({1, 3, 2, 4}, armnn::DataType::Float32);
1807 
1809  desc.m_TargetWidth = 4;
1810  desc.m_TargetHeight = 2;
1811  desc.m_Method = armnn::ResizeMethod::NearestNeighbor;
1812  desc.m_AlignCorners = true;
1813  desc.m_HalfPixelCenters = true;
1814 
1816  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1817  armnn::IConnectableLayer* const resizeLayer = network->AddResizeLayer(desc, layerName.c_str());
1818  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1819 
1820  inputLayer->GetOutputSlot(0).Connect(resizeLayer->GetInputSlot(0));
1821  resizeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1822 
1823  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1824  resizeLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1825 
1826  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1827  BOOST_CHECK(deserializedNetwork);
1828 
1829  LayerVerifierBaseWithDescriptor<armnn::ResizeDescriptor> verifier(layerName, {inputInfo}, {outputInfo}, desc);
1830  deserializedNetwork->ExecuteStrategy(verifier);
1831 }
1832 
1833 class ResizeBilinearLayerVerifier : public LayerVerifierBaseWithDescriptor<armnn::ResizeBilinearDescriptor>
1834 {
1835 public:
1836  ResizeBilinearLayerVerifier(const std::string& layerName,
1837  const std::vector<armnn::TensorInfo>& inputInfos,
1838  const std::vector<armnn::TensorInfo>& outputInfos,
1839  const armnn::ResizeBilinearDescriptor& descriptor)
1841  layerName, inputInfos, outputInfos, descriptor) {}
1842 
1843  void ExecuteStrategy(const armnn::IConnectableLayer* layer,
1844  const armnn::BaseDescriptor& descriptor,
1845  const std::vector<armnn::ConstTensor>& constants,
1846  const char* name,
1847  const armnn::LayerBindingId id = 0) override
1848  {
1849  armnn::IgnoreUnused(descriptor, constants, id);
1850  switch (layer->GetType())
1851  {
1852  case armnn::LayerType::Input: break;
1853  case armnn::LayerType::Output: break;
1855  {
1856  VerifyNameAndConnections(layer, name);
1857  const armnn::ResizeDescriptor& layerDescriptor =
1858  static_cast<const armnn::ResizeDescriptor&>(descriptor);
1859  BOOST_CHECK(layerDescriptor.m_Method == armnn::ResizeMethod::Bilinear);
1860  BOOST_CHECK(layerDescriptor.m_TargetWidth == m_Descriptor.m_TargetWidth);
1861  BOOST_CHECK(layerDescriptor.m_TargetHeight == m_Descriptor.m_TargetHeight);
1862  BOOST_CHECK(layerDescriptor.m_DataLayout == m_Descriptor.m_DataLayout);
1863  BOOST_CHECK(layerDescriptor.m_AlignCorners == m_Descriptor.m_AlignCorners);
1864  BOOST_CHECK(layerDescriptor.m_HalfPixelCenters == m_Descriptor.m_HalfPixelCenters);
1865  break;
1866  }
1867  default:
1868  {
1869  throw armnn::Exception("Unexpected layer type in test model. ResizeBiliniar "
1870  "should have translated to Resize");
1871  }
1872  }
1873  }
1874 };
1875 
1876 // NOTE: Until the deprecated AddResizeBilinearLayer disappears this test checks that
1877 // calling AddResizeBilinearLayer places a ResizeLayer into the serialized format
1878 // and that when this deserialises we have a ResizeLayer
1879 BOOST_AUTO_TEST_CASE(SerializeResizeBilinear)
1880 {
1881  const std::string layerName("resizeBilinear");
1882  const armnn::TensorInfo inputInfo = armnn::TensorInfo({1, 3, 5, 5}, armnn::DataType::Float32);
1883  const armnn::TensorInfo outputInfo = armnn::TensorInfo({1, 3, 2, 4}, armnn::DataType::Float32);
1884 
1886  desc.m_TargetWidth = 4u;
1887  desc.m_TargetHeight = 2u;
1888  desc.m_AlignCorners = true;
1889  desc.m_HalfPixelCenters = true;
1890 
1892  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1894  armnn::IConnectableLayer* const resizeLayer = network->AddResizeBilinearLayer(desc, layerName.c_str());
1896  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1897 
1898  inputLayer->GetOutputSlot(0).Connect(resizeLayer->GetInputSlot(0));
1899  resizeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1900 
1901  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1902  resizeLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1903 
1904  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1905  BOOST_CHECK(deserializedNetwork);
1906 
1907  ResizeBilinearLayerVerifier verifier(layerName, {inputInfo}, {outputInfo}, desc);
1908  deserializedNetwork->ExecuteStrategy(verifier);
1909 }
1910 
1911 BOOST_AUTO_TEST_CASE(EnsureResizeBilinearBackwardCompatibility)
1912 {
1913  // The hex data below is a flat buffer containing a simple network with an input,
1914  // a ResizeBilinearLayer (now deprecated) and an output
1915  //
1916  // This test verifies that we can still deserialize this old-style model by replacing
1917  // the ResizeBilinearLayer with an equivalent ResizeLayer
1918  const std::vector<uint8_t> resizeBilinearModel =
1919  {
1920  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x0A, 0x00,
1921  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1922  0x50, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
1923  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xD4, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0B,
1924  0x04, 0x00, 0x00, 0x00, 0xC2, 0xFE, 0xFF, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00,
1925  0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x8A, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00,
1926  0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
1927  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1928  0x38, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
1929  0x00, 0x1A, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0E, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00,
1930  0x34, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x12, 0x00, 0x08, 0x00, 0x0C, 0x00,
1931  0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1932  0x00, 0x00, 0x0E, 0x00, 0x18, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0E, 0x00,
1933  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
1934  0x20, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x72, 0x65, 0x73, 0x69, 0x7A, 0x65, 0x42, 0x69, 0x6C, 0x69,
1935  0x6E, 0x65, 0x61, 0x72, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1936  0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00,
1937  0x00, 0x00, 0x52, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1938  0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00,
1939  0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1940  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
1941  0x00, 0x09, 0x04, 0x00, 0x00, 0x00, 0xF6, 0xFF, 0xFF, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
1942  0x0A, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x14, 0x00,
1943  0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1944  0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1945  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0A, 0x00,
1946  0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00,
1947  0x08, 0x00, 0x07, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
1948  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00,
1949  0x00, 0x00, 0x05, 0x00, 0x00, 0x00
1950  };
1951 
1952  armnn::INetworkPtr deserializedNetwork =
1953  DeserializeNetwork(std::string(resizeBilinearModel.begin(), resizeBilinearModel.end()));
1954  BOOST_CHECK(deserializedNetwork);
1955 
1956  const armnn::TensorInfo inputInfo = armnn::TensorInfo({1, 3, 5, 5}, armnn::DataType::Float32);
1957  const armnn::TensorInfo outputInfo = armnn::TensorInfo({1, 3, 2, 4}, armnn::DataType::Float32);
1958 
1960  descriptor.m_TargetWidth = 4u;
1961  descriptor.m_TargetHeight = 2u;
1962 
1963  ResizeBilinearLayerVerifier verifier("resizeBilinear", { inputInfo }, { outputInfo }, descriptor);
1964  deserializedNetwork->ExecuteStrategy(verifier);
1965 }
1966 
1967 BOOST_AUTO_TEST_CASE(SerializeSlice)
1968 {
1969  const std::string layerName{"slice"};
1970 
1971  const armnn::TensorInfo inputInfo = armnn::TensorInfo({3, 2, 3, 1}, armnn::DataType::Float32);
1972  const armnn::TensorInfo outputInfo = armnn::TensorInfo({2, 2, 2, 1}, armnn::DataType::Float32);
1973 
1974  armnn::SliceDescriptor descriptor({ 0, 0, 1, 0}, {2, 2, 2, 1});
1975 
1977 
1978  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1979  armnn::IConnectableLayer* const sliceLayer = network->AddSliceLayer(descriptor, layerName.c_str());
1980  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1981 
1982  inputLayer->GetOutputSlot(0).Connect(sliceLayer->GetInputSlot(0));
1983  sliceLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1984 
1985  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1986  sliceLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1987 
1988  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1989  BOOST_CHECK(deserializedNetwork);
1990 
1991  LayerVerifierBaseWithDescriptor<armnn::SliceDescriptor> verifier(layerName, {inputInfo}, {outputInfo}, descriptor);
1992  deserializedNetwork->ExecuteStrategy(verifier);
1993 }
1994 
1995 BOOST_AUTO_TEST_CASE(SerializeSoftmax)
1996 {
1997  const std::string layerName("softmax");
1999 
2000  armnn::SoftmaxDescriptor descriptor;
2001  descriptor.m_Beta = 1.0f;
2002 
2004  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2005  armnn::IConnectableLayer* const softmaxLayer = network->AddSoftmaxLayer(descriptor, layerName.c_str());
2006  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
2007 
2008  inputLayer->GetOutputSlot(0).Connect(softmaxLayer->GetInputSlot(0));
2009  softmaxLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
2010 
2011  inputLayer->GetOutputSlot(0).SetTensorInfo(info);
2012  softmaxLayer->GetOutputSlot(0).SetTensorInfo(info);
2013 
2014  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2015  BOOST_CHECK(deserializedNetwork);
2016 
2017  LayerVerifierBaseWithDescriptor<armnn::SoftmaxDescriptor> verifier(layerName, {info}, {info}, descriptor);
2018  deserializedNetwork->ExecuteStrategy(verifier);
2019 }
2020 
2021 BOOST_AUTO_TEST_CASE(SerializeSpaceToBatchNd)
2022 {
2023  const std::string layerName("spaceToBatchNd");
2024  const armnn::TensorInfo inputInfo({2, 1, 2, 4}, armnn::DataType::Float32);
2025  const armnn::TensorInfo outputInfo({8, 1, 1, 3}, armnn::DataType::Float32);
2026 
2029  desc.m_BlockShape = {2, 2};
2030  desc.m_PadList = {{0, 0}, {2, 0}};
2031 
2033  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2034  armnn::IConnectableLayer* const spaceToBatchNdLayer = network->AddSpaceToBatchNdLayer(desc, layerName.c_str());
2035  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
2036 
2037  inputLayer->GetOutputSlot(0).Connect(spaceToBatchNdLayer->GetInputSlot(0));
2038  spaceToBatchNdLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
2039 
2040  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
2041  spaceToBatchNdLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
2042 
2043  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2044  BOOST_CHECK(deserializedNetwork);
2045 
2047  layerName, {inputInfo}, {outputInfo}, desc);
2048  deserializedNetwork->ExecuteStrategy(verifier);
2049 }
2050 
2051 BOOST_AUTO_TEST_CASE(SerializeSpaceToDepth)
2052 {
2053  const std::string layerName("spaceToDepth");
2054 
2055  const armnn::TensorInfo inputInfo ({ 1, 16, 8, 3 }, armnn::DataType::Float32);
2056  const armnn::TensorInfo outputInfo({ 1, 8, 4, 12 }, armnn::DataType::Float32);
2057 
2059  desc.m_BlockSize = 2;
2060  desc.m_DataLayout = armnn::DataLayout::NHWC;
2061 
2063  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2064  armnn::IConnectableLayer* const spaceToDepthLayer = network->AddSpaceToDepthLayer(desc, layerName.c_str());
2065  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
2066 
2067  inputLayer->GetOutputSlot(0).Connect(spaceToDepthLayer->GetInputSlot(0));
2068  spaceToDepthLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
2069 
2070  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
2071  spaceToDepthLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
2072 
2073  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2074  BOOST_CHECK(deserializedNetwork);
2075 
2077  layerName, {inputInfo}, {outputInfo}, desc);
2078  deserializedNetwork->ExecuteStrategy(verifier);
2079 }
2080 
2081 BOOST_AUTO_TEST_CASE(SerializeSplitter)
2082 {
2083  const unsigned int numViews = 3;
2084  const unsigned int numDimensions = 4;
2085  const unsigned int inputShape[] = {1, 18, 4, 4};
2086  const unsigned int outputShape[] = {1, 6, 4, 4};
2087 
2088  // This is modelled on how the caffe parser sets up a splitter layer to partition an input along dimension one.
2089  unsigned int splitterDimSizes[4] = {static_cast<unsigned int>(inputShape[0]),
2090  static_cast<unsigned int>(inputShape[1]),
2091  static_cast<unsigned int>(inputShape[2]),
2092  static_cast<unsigned int>(inputShape[3])};
2093  splitterDimSizes[1] /= numViews;
2094  armnn::ViewsDescriptor desc(numViews, numDimensions);
2095 
2096  for (unsigned int g = 0; g < numViews; ++g)
2097  {
2098  desc.SetViewOriginCoord(g, 1, splitterDimSizes[1] * g);
2099 
2100  for (unsigned int dimIdx=0; dimIdx < 4; dimIdx++)
2101  {
2102  desc.SetViewSize(g, dimIdx, splitterDimSizes[dimIdx]);
2103  }
2104  }
2105 
2106  const std::string layerName("splitter");
2107  const armnn::TensorInfo inputInfo(numDimensions, inputShape, armnn::DataType::Float32);
2108  const armnn::TensorInfo outputInfo(numDimensions, outputShape, armnn::DataType::Float32);
2109 
2111  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2112  armnn::IConnectableLayer* const splitterLayer = network->AddSplitterLayer(desc, layerName.c_str());
2113  armnn::IConnectableLayer* const outputLayer0 = network->AddOutputLayer(0);
2114  armnn::IConnectableLayer* const outputLayer1 = network->AddOutputLayer(1);
2115  armnn::IConnectableLayer* const outputLayer2 = network->AddOutputLayer(2);
2116 
2117  inputLayer->GetOutputSlot(0).Connect(splitterLayer->GetInputSlot(0));
2118  splitterLayer->GetOutputSlot(0).Connect(outputLayer0->GetInputSlot(0));
2119  splitterLayer->GetOutputSlot(1).Connect(outputLayer1->GetInputSlot(0));
2120  splitterLayer->GetOutputSlot(2).Connect(outputLayer2->GetInputSlot(0));
2121 
2122  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
2123  splitterLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
2124  splitterLayer->GetOutputSlot(1).SetTensorInfo(outputInfo);
2125  splitterLayer->GetOutputSlot(2).SetTensorInfo(outputInfo);
2126 
2127  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2128  BOOST_CHECK(deserializedNetwork);
2129 
2131  layerName, {inputInfo}, {outputInfo, outputInfo, outputInfo}, desc);
2132  deserializedNetwork->ExecuteStrategy(verifier);
2133 }
2134 
2135 BOOST_AUTO_TEST_CASE(SerializeStack)
2136 {
2137  const std::string layerName("stack");
2138 
2139  armnn::TensorInfo inputTensorInfo ({4, 3, 5}, armnn::DataType::Float32);
2140  armnn::TensorInfo outputTensorInfo({4, 3, 2, 5}, armnn::DataType::Float32);
2141 
2142  armnn::StackDescriptor descriptor(2, 2, {4, 3, 5});
2143 
2145  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(0);
2146  armnn::IConnectableLayer* const inputLayer2 = network->AddInputLayer(1);
2147  armnn::IConnectableLayer* const stackLayer = network->AddStackLayer(descriptor, layerName.c_str());
2148  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
2149 
2150  inputLayer1->GetOutputSlot(0).Connect(stackLayer->GetInputSlot(0));
2151  inputLayer2->GetOutputSlot(0).Connect(stackLayer->GetInputSlot(1));
2152  stackLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
2153 
2154  inputLayer1->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
2155  inputLayer2->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
2156  stackLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2157 
2158  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2159  BOOST_CHECK(deserializedNetwork);
2160 
2162  layerName, {inputTensorInfo, inputTensorInfo}, {outputTensorInfo}, descriptor);
2163  deserializedNetwork->ExecuteStrategy(verifier);
2164 }
2165 
2166 BOOST_AUTO_TEST_CASE(SerializeStandIn)
2167 {
2168  const std::string layerName("standIn");
2169 
2170  armnn::TensorInfo tensorInfo({ 1u }, armnn::DataType::Float32);
2171  armnn::StandInDescriptor descriptor(2u, 2u);
2172 
2174  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
2175  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
2176  armnn::IConnectableLayer* const standInLayer = network->AddStandInLayer(descriptor, layerName.c_str());
2177  armnn::IConnectableLayer* const outputLayer0 = network->AddOutputLayer(0);
2178  armnn::IConnectableLayer* const outputLayer1 = network->AddOutputLayer(1);
2179 
2180  inputLayer0->GetOutputSlot(0).Connect(standInLayer->GetInputSlot(0));
2181  inputLayer0->GetOutputSlot(0).SetTensorInfo(tensorInfo);
2182 
2183  inputLayer1->GetOutputSlot(0).Connect(standInLayer->GetInputSlot(1));
2184  inputLayer1->GetOutputSlot(0).SetTensorInfo(tensorInfo);
2185 
2186  standInLayer->GetOutputSlot(0).Connect(outputLayer0->GetInputSlot(0));
2187  standInLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
2188 
2189  standInLayer->GetOutputSlot(1).Connect(outputLayer1->GetInputSlot(0));
2190  standInLayer->GetOutputSlot(1).SetTensorInfo(tensorInfo);
2191 
2192  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2193  BOOST_CHECK(deserializedNetwork);
2194 
2196  layerName, { tensorInfo, tensorInfo }, { tensorInfo, tensorInfo }, descriptor);
2197  deserializedNetwork->ExecuteStrategy(verifier);
2198 }
2199 
2200 BOOST_AUTO_TEST_CASE(SerializeStridedSlice)
2201 {
2202  const std::string layerName("stridedSlice");
2203  const armnn::TensorInfo inputInfo = armnn::TensorInfo({3, 2, 3, 1}, armnn::DataType::Float32);
2204  const armnn::TensorInfo outputInfo = armnn::TensorInfo({3, 1}, armnn::DataType::Float32);
2205 
2206  armnn::StridedSliceDescriptor desc({0, 0, 1, 0}, {1, 1, 1, 1}, {1, 1, 1, 1});
2207  desc.m_EndMask = (1 << 4) - 1;
2208  desc.m_ShrinkAxisMask = (1 << 1) | (1 << 2);
2209  desc.m_DataLayout = armnn::DataLayout::NCHW;
2210 
2212  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2213  armnn::IConnectableLayer* const stridedSliceLayer = network->AddStridedSliceLayer(desc, layerName.c_str());
2214  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
2215 
2216  inputLayer->GetOutputSlot(0).Connect(stridedSliceLayer->GetInputSlot(0));
2217  stridedSliceLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
2218 
2219  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
2220  stridedSliceLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
2221 
2222  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2223  BOOST_CHECK(deserializedNetwork);
2224 
2226  layerName, {inputInfo}, {outputInfo}, desc);
2227  deserializedNetwork->ExecuteStrategy(verifier);
2228 }
2229 
2230 BOOST_AUTO_TEST_CASE(SerializeSubtraction)
2231 {
2232  const std::string layerName("subtraction");
2234 
2236  armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
2237  armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
2238  armnn::IConnectableLayer* const subtractionLayer = network->AddSubtractionLayer(layerName.c_str());
2239  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
2240 
2241  inputLayer0->GetOutputSlot(0).Connect(subtractionLayer->GetInputSlot(0));
2242  inputLayer1->GetOutputSlot(0).Connect(subtractionLayer->GetInputSlot(1));
2243  subtractionLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
2244 
2245  inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
2246  inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
2247  subtractionLayer->GetOutputSlot(0).SetTensorInfo(info);
2248 
2249  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2250  BOOST_CHECK(deserializedNetwork);
2251 
2252  LayerVerifierBase verifier(layerName, {info, info}, {info});
2253  deserializedNetwork->ExecuteStrategy(verifier);
2254 }
2255 
2256 BOOST_AUTO_TEST_CASE(SerializeSwitch)
2257 {
2258  class SwitchLayerVerifier : public LayerVerifierBase
2259  {
2260  public:
2261  SwitchLayerVerifier(const std::string& layerName,
2262  const std::vector<armnn::TensorInfo>& inputInfos,
2263  const std::vector<armnn::TensorInfo>& outputInfos)
2264  : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
2265 
2266  void ExecuteStrategy(const armnn::IConnectableLayer* layer,
2267  const armnn::BaseDescriptor& descriptor,
2268  const std::vector<armnn::ConstTensor>& constants,
2269  const char* name,
2270  const armnn::LayerBindingId id = 0) override
2271  {
2272  armnn::IgnoreUnused(descriptor, constants, id);
2273  switch (layer->GetType())
2274  {
2275  case armnn::LayerType::Input: break;
2276  case armnn::LayerType::Output: break;
2277  case armnn::LayerType::Constant: break;
2279  {
2280  VerifyNameAndConnections(layer, name);
2281  break;
2282  }
2283  default:
2284  {
2285  throw armnn::Exception("Unexpected layer type in Switch test model");
2286  }
2287  }
2288  }
2289  };
2290 
2291  const std::string layerName("switch");
2293 
2294  std::vector<float> constantData = GenerateRandomData<float>(info.GetNumElements());
2295  armnn::ConstTensor constTensor(info, constantData);
2296 
2298  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2299  armnn::IConnectableLayer* const constantLayer = network->AddConstantLayer(constTensor, "constant");
2300  armnn::IConnectableLayer* const switchLayer = network->AddSwitchLayer(layerName.c_str());
2301  armnn::IConnectableLayer* const trueOutputLayer = network->AddOutputLayer(0);
2302  armnn::IConnectableLayer* const falseOutputLayer = network->AddOutputLayer(1);
2303 
2304  inputLayer->GetOutputSlot(0).Connect(switchLayer->GetInputSlot(0));
2305  constantLayer->GetOutputSlot(0).Connect(switchLayer->GetInputSlot(1));
2306  switchLayer->GetOutputSlot(0).Connect(trueOutputLayer->GetInputSlot(0));
2307  switchLayer->GetOutputSlot(1).Connect(falseOutputLayer->GetInputSlot(0));
2308 
2309  inputLayer->GetOutputSlot(0).SetTensorInfo(info);
2310  constantLayer->GetOutputSlot(0).SetTensorInfo(info);
2311  switchLayer->GetOutputSlot(0).SetTensorInfo(info);
2312  switchLayer->GetOutputSlot(1).SetTensorInfo(info);
2313 
2314  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2315  BOOST_CHECK(deserializedNetwork);
2316 
2317  SwitchLayerVerifier verifier(layerName, {info, info}, {info, info});
2318  deserializedNetwork->ExecuteStrategy(verifier);
2319 }
2320 
2321 BOOST_AUTO_TEST_CASE(SerializeTranspose)
2322 {
2323  const std::string layerName("transpose");
2324  const armnn::TensorInfo inputTensorInfo({4, 3, 2, 1}, armnn::DataType::Float32);
2325  const armnn::TensorInfo outputTensorInfo({1, 2, 3, 4}, armnn::DataType::Float32);
2326 
2327  armnn::TransposeDescriptor descriptor(armnn::PermutationVector({3, 2, 1, 0}));
2328 
2330  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2331  armnn::IConnectableLayer* const transposeLayer = network->AddTransposeLayer(descriptor, layerName.c_str());
2332  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
2333 
2334  inputLayer->GetOutputSlot(0).Connect(transposeLayer->GetInputSlot(0));
2335  transposeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
2336 
2337  inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
2338  transposeLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2339 
2340  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2341  BOOST_CHECK(deserializedNetwork);
2342 
2344  layerName, {inputTensorInfo}, {outputTensorInfo}, descriptor);
2345  deserializedNetwork->ExecuteStrategy(verifier);
2346 }
2347 
2348 BOOST_AUTO_TEST_CASE(SerializeTransposeConvolution2d)
2349 {
2350  const std::string layerName("transposeConvolution2d");
2351  const armnn::TensorInfo inputInfo ({ 1, 7, 7, 1 }, armnn::DataType::Float32);
2352  const armnn::TensorInfo outputInfo({ 1, 9, 9, 1 }, armnn::DataType::Float32);
2353 
2354  const armnn::TensorInfo weightsInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
2355  const armnn::TensorInfo biasesInfo ({ 1 }, armnn::DataType::Float32);
2356 
2357  std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
2358  armnn::ConstTensor weights(weightsInfo, weightsData);
2359 
2360  std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
2361  armnn::ConstTensor biases(biasesInfo, biasesData);
2362 
2364  descriptor.m_PadLeft = 1;
2365  descriptor.m_PadRight = 1;
2366  descriptor.m_PadTop = 1;
2367  descriptor.m_PadBottom = 1;
2368  descriptor.m_StrideX = 1;
2369  descriptor.m_StrideY = 1;
2370  descriptor.m_BiasEnabled = true;
2372 
2374  armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2375  armnn::IConnectableLayer* const convLayer =
2376  network->AddTransposeConvolution2dLayer(descriptor,
2377  weights,
2379  layerName.c_str());
2380  armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
2381 
2382  inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
2383  convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
2384 
2385  inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
2386  convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
2387 
2388  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2389  BOOST_CHECK(deserializedNetwork);
2390 
2391  const std::vector<armnn::ConstTensor> constants {weights, biases};
2393  layerName, {inputInfo}, {outputInfo}, descriptor, constants);
2394  deserializedNetwork->ExecuteStrategy(verifier);
2395 }
2396 
2397 BOOST_AUTO_TEST_CASE(SerializeDeserializeNonLinearNetwork)
2398 {
2399  class ConstantLayerVerifier : public LayerVerifierBase
2400  {
2401  public:
2402  ConstantLayerVerifier(const std::string& layerName,
2403  const std::vector<armnn::TensorInfo>& inputInfos,
2404  const std::vector<armnn::TensorInfo>& outputInfos,
2405  const armnn::ConstTensor& layerInput)
2406  : LayerVerifierBase(layerName, inputInfos, outputInfos)
2407  , m_LayerInput(layerInput) {}
2408 
2409  void ExecuteStrategy(const armnn::IConnectableLayer* layer,
2410  const armnn::BaseDescriptor& descriptor,
2411  const std::vector<armnn::ConstTensor>& constants,
2412  const char* name,
2413  const armnn::LayerBindingId id = 0) override
2414  {
2415  armnn::IgnoreUnused(descriptor, constants, id);
2416  switch (layer->GetType())
2417  {
2418  case armnn::LayerType::Input: break;
2419  case armnn::LayerType::Output: break;
2420  case armnn::LayerType::Addition: break;
2422  {
2423  VerifyNameAndConnections(layer, name);
2424  CompareConstTensor(constants.at(0), m_LayerInput);
2425  break;
2426  }
2427  default:
2428  {
2429  throw armnn::Exception("Unexpected layer type in test model");
2430  }
2431  }
2432  }
2433 
2434  private:
2435  armnn::ConstTensor m_LayerInput;
2436  };
2437 
2438  const std::string layerName("constant");
2440 
2441  std::vector<float> constantData = GenerateRandomData<float>(info.GetNumElements());
2442  armnn::ConstTensor constTensor(info, constantData);
2443 
2445  armnn::IConnectableLayer* input = network->AddInputLayer(0);
2446  armnn::IConnectableLayer* add = network->AddAdditionLayer();
2447  armnn::IConnectableLayer* constant = network->AddConstantLayer(constTensor, layerName.c_str());
2448  armnn::IConnectableLayer* output = network->AddOutputLayer(0);
2449 
2450  input->GetOutputSlot(0).Connect(add->GetInputSlot(0));
2451  constant->GetOutputSlot(0).Connect(add->GetInputSlot(1));
2452  add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
2453 
2454  input->GetOutputSlot(0).SetTensorInfo(info);
2455  constant->GetOutputSlot(0).SetTensorInfo(info);
2456  add->GetOutputSlot(0).SetTensorInfo(info);
2457 
2458  armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2459  BOOST_CHECK(deserializedNetwork);
2460 
2461  ConstantLayerVerifier verifier(layerName, {}, {info}, constTensor);
2462  deserializedNetwork->ExecuteStrategy(verifier);
2463 }
2464 
BOOST_AUTO_TEST_SUITE(TensorflowLiteParser)
uint32_t m_PadBottom
Padding bottom value in the height dimension.
bool m_BiasEnabled
Enable/disable bias.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
A ViewsDescriptor for the SplitterLayer.
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:62
float m_ScaleW
Center size encoding scale weight.
bool m_BiasEnabled
Enable/disable bias.
A TransposeConvolution2dDescriptor for the TransposeConvolution2dLayer.
const TensorShape & GetShape() const
Definition: Tensor.hpp:187
uint32_t m_PadBottom
Padding bottom value in the height dimension.
A ReshapeDescriptor for the ReshapeLayer.
armnn::INetworkPtr DeserializeNetwork(const std::string &serializerString)
#define ARMNN_NO_DEPRECATE_WARN_BEGIN
Definition: Deprecated.hpp:33
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
A ComparisonDescriptor for the ComparisonLayer.
Definition: Descriptors.hpp:78
float m_ScaleX
Center size encoding scale x.
uint32_t m_TargetWidth
Target width value.
bool m_TransposeWeightMatrix
Enable/disable transpose weight matrix.
A Convolution2dDescriptor for the Convolution2dLayer.
uint32_t m_PadLeft
Padding left value in the width dimension.
bool m_BiasEnabled
Enable/disable bias.
ResizeMethod m_Method
The Interpolation method to use (Bilinear, NearestNeighbor).
float m_Gamma
Gamma, the scale scalar value applied for the normalized tensor. Defaults to 1.0. ...
float m_Beta
Exponentiation value.
The padding fields don&#39;t count and are ignored.
float m_Eps
Value to add to the variance. Used to avoid dividing by zero.
ArgMinMaxFunction m_Function
Specify if the function is to find Min or Max.
Definition: Descriptors.hpp:70
uint32_t m_DetectionsPerClass
Detections per classes, used in Regular NMS.
armnn::TensorInfo anchorsInfo({ 6, 4 }, armnn::DataType::Float32)
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
A LogicalBinaryDescriptor for the LogicalBinaryLayer.
uint32_t m_PadRight
Padding right value in the width dimension.
void ExecuteStrategy(const armnn::IConnectableLayer *layer, const armnn::BaseDescriptor &descriptor, const std::vector< armnn::ConstTensor > &constants, const char *name, const armnn::LayerBindingId id=0) override
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Copyright (c) 2021 ARM Limited and Contributors.
void IgnoreUnused(Ts &&...)
uint32_t m_PadBottom
Padding bottom value in the height dimension.
uint32_t m_DilationY
Dilation along y axis.
int32_t m_EndMask
End mask value.
A SpaceToDepthDescriptor for the SpaceToDepthLayer.
uint32_t m_DilationY
Dilation factor value for height dimension.
A BatchToSpaceNdDescriptor for the BatchToSpaceNdLayer.
int LayerBindingId
Type of identifiers for bindable layers (inputs, outputs).
Definition: Types.hpp:243
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
A ResizeDescriptor for the ResizeLayer.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
uint32_t m_MaxClassesPerDetection
Maximum numbers of classes per detection, used in Fast NMS.
Base class for all descriptors.
Definition: Descriptors.hpp:22
std::vector< unsigned int > m_Axis
Values for the dimensions to reduce.
A StackDescriptor for the StackLayer.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
uint32_t m_PadTop
Padding top value in the height dimension.
uint32_t m_MaxDetections
Maximum numbers of detections.
A PadDescriptor for the PadLayer.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
DataType
Definition: Types.hpp:36
float m_NmsIouThreshold
Intersection over union threshold.
#define ARMNN_NO_DEPRECATE_WARN_END
Definition: Deprecated.hpp:34
uint32_t m_DilationX
Dilation factor value for width dimension.
uint32_t m_PadTop
Padding top value in the height dimension.
Status SetViewSize(uint32_t view, uint32_t coord, uint32_t value)
Set the size of the views.
void ExecuteStrategy(const armnn::IConnectableLayer *layer, const armnn::BaseDescriptor &descriptor, const std::vector< armnn::ConstTensor > &constants, const char *name, const armnn::LayerBindingId id=0) override
A L2NormalizationDescriptor for the L2NormalizationLayer.
void VerifyNameAndConnections(const armnn::IConnectableLayer *layer, const char *name)
An ArgMinMaxDescriptor for ArgMinMaxLayer.
Definition: Descriptors.hpp:56
An OriginsDescriptor for the ConcatLayer.
A ReduceDescriptor for the REDUCE operators.
A FullyConnectedDescriptor for the FullyConnectedLayer.
bool m_BiasEnabled
Enable/disable bias.
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
Definition: Tensor.hpp:314
uint32_t m_TargetWidth
Target width value.
A GatherDescriptor for the GatherLayer.
uint32_t m_NumClasses
Number of classes.
bool m_HalfPixelCenters
Half Pixel Centers.
void SerializeArgMinMaxTest(armnn::DataType dataType)
uint32_t m_PadTop
Padding top value in the height dimension.
A StandInDescriptor for the StandIn layer.
LayerVerifierBase(const std::string &layerName, const std::vector< armnn::TensorInfo > &inputInfos, const std::vector< armnn::TensorInfo > &outputInfos)
bool m_UseRegularNms
Use Regular NMS.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
uint32_t m_TargetHeight
Target height value.
A SliceDescriptor for the SliceLayer.
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
virtual LayerType GetType() const =0
Returns the armnn::LayerType of this layer.
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).
std::vector< uint32_t > m_vAxis
The indices of the dimensions to reduce.
float m_ScaleH
Center size encoding scale height.
A SpaceToBatchNdDescriptor for the SpaceToBatchNdLayer.
uint32_t m_DilationX
Dilation along x axis.
BOOST_AUTO_TEST_SUITE_END()
uint32_t m_PadLeft
Padding left value in the width dimension.
EmptyOptional is used to initialize the Optional class in case we want to have default value for an O...
Definition: Optional.hpp:32
bool m_AlignCorners
Aligned corners.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
int32_t m_Axis
The axis in params to gather indices from.
A ElementwiseUnaryDescriptor for the ElementwiseUnaryLayer.
Definition: Descriptors.hpp:98
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
Base class for all ArmNN exceptions so that users can filter to just those.
Definition: Exceptions.hpp:46
void CompareConstTensor(const armnn::ConstTensor &tensor1, const armnn::ConstTensor &tensor2)
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
A MeanDescriptor for the MeanLayer.
uint32_t m_PadRight
Padding right value in the width dimension.
A TransposeDescriptor for the TransposeLayer.
A StridedSliceDescriptor for the StridedSliceLayer.
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
float m_ScaleY
Center size encoding scale y.
OriginsDescriptor CreateDescriptorForConcatenation(TensorShapeIt first, TensorShapeIt last, unsigned int concatenationDimension)
Convenience template to create an OriginsDescriptor to use when creating a ConcatLayer for performing...
float m_NmsScoreThreshold
NMS score threshold.
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
Definition: INetwork.hpp:173
virtual int Connect(IInputSlot &destination)=0
A Pooling2dDescriptor for the Pooling2dLayer.
std::string SerializeNetwork(const armnn::INetwork &network)
A NormalizationDescriptor for the NormalizationLayer.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
An InstanceNormalizationDescriptor for InstanceNormalizationLayer.
A ResizeBilinearDescriptor for the ResizeBilinearLayer.
static INetworkPtr Create(NetworkOptions networkOptions={})
Definition: Network.cpp:529
A SoftmaxDescriptor for the SoftmaxLayer.
Status SetViewOriginCoord(uint32_t view, uint32_t coord, uint32_t value)
Set the view origin coordinates.
BOOST_AUTO_TEST_CASE(SerializeAbs)
A DepthwiseConvolution2dDescriptor for the DepthwiseConvolution2dLayer.
A FillDescriptor for the FillLayer.
A BatchNormalizationDescriptor for the BatchNormalizationLayer.
uint32_t m_PadLeft
Padding left value in the width dimension.
void ExecuteStrategy(const armnn::IConnectableLayer *layer, const armnn::BaseDescriptor &descriptor, const std::vector< armnn::ConstTensor > &constants, const char *name, const armnn::LayerBindingId id=0) override
A PermuteDescriptor for the PermuteLayer.
uint32_t m_PadRight
Padding right value in the width dimension.
bool m_ConstantWeights
Enable/disable constant weights and biases.
std::vector< float > anchors({ 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 10.5f, 1.0f, 1.0f, 0.5f, 10.5f, 1.0f, 1.0f, 0.5f, 100.5f, 1.0f, 1.0f })