ArmNN
 24.08
Deserializer.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017,2019-2024 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "Deserializer.hpp"
7 
8 #include <armnn/Descriptors.hpp>
9 #include <armnn/Exceptions.hpp>
10 #include <armnn/TypesUtils.hpp>
11 #include <armnn/LstmParams.hpp>
13 #include <armnn/Logging.hpp>
14 
15 #include <armnnUtils/Permute.hpp>
16 #include <armnnUtils/Transpose.hpp>
17 #include <armnn/utility/Assert.hpp>
20 
21 #include <ParserHelper.hpp>
22 #include <VerificationHelpers.hpp>
23 
24 #include <fmt/format.h>
25 
26 #include <fstream>
27 #include <algorithm>
28 #include <limits>
29 #include <numeric>
30 
32 using namespace armnn;
33 using namespace armnnSerializer;
34 
35 namespace armnnDeserializer
36 {
37 
38 IDeserializer::IDeserializer() : pDeserializerImpl(new DeserializerImpl()){}
39 
40 IDeserializer::~IDeserializer() = default;
41 
42 IDeserializer *IDeserializer::CreateRaw()
43 {
44  return new IDeserializer();
45 }
46 
47 IDeserializerPtr IDeserializer::Create()
48 {
49  return IDeserializerPtr(CreateRaw(), &IDeserializer::Destroy);
50 }
51 
52 void IDeserializer::Destroy(IDeserializer *parser)
53 {
54  delete parser;
55 }
56 
57 armnn::INetworkPtr IDeserializer::CreateNetworkFromBinary(const std::vector<uint8_t> &binaryContent)
58 {
59  return pDeserializerImpl->CreateNetworkFromBinary(binaryContent);
60 }
61 
62 armnn::INetworkPtr IDeserializer::CreateNetworkFromBinary(std::istream &binaryContent)
63 {
64  return pDeserializerImpl->CreateNetworkFromBinary(binaryContent);
65 }
66 
67 BindingPointInfo IDeserializer::GetNetworkInputBindingInfo(unsigned int layerId, const std::string &name) const
68 {
69  return pDeserializerImpl->GetNetworkInputBindingInfo(layerId, name);
70 }
71 
72 BindingPointInfo IDeserializer::GetNetworkOutputBindingInfo(unsigned int layerId, const std::string &name) const
73 {
74  return pDeserializerImpl->GetNetworkOutputBindingInfo(layerId, name);
75 }
76 
77 namespace
78 {
79 
80 const uint32_t VIRTUAL_LAYER_ID = std::numeric_limits<uint32_t>::max();
81 
82  void CheckGraph(const GraphPtr& graph,
83  unsigned int layersIndex,
84  const CheckLocation& location)
85 {
86  if (graph->layers() == nullptr)
87  {
88  throw ParseException(fmt::format("{0} was called with invalid (null) graph. "
89  "Possible reason is that the graph is not yet loaded and Unpack(ed). "
90  "layers:{1} at {2}",
91  location.m_Function,
92  layersIndex,
93  location.FileLine()));
94  }
95  else if (layersIndex >= graph->layers()->size())
96  {
97  throw ParseException(fmt::format("{0} was called with an invalid layers index. layers:{1} at {2}",
98  location.m_Function,
99  layersIndex,
100  location.FileLine()));
101  }
102 }
103 
104 void CheckLayers(const GraphPtr& graph,
105  unsigned int layersIndex,
106  unsigned int layerIndex,
107  const CheckLocation& location)
108 {
109  if (graph->layers() == nullptr)
110  {
111  throw ParseException(fmt::format("{0} was called with invalid (null) graph. "
112  "Possible reason is that the graph is not yet loaded and Unpack(ed). "
113  "layers:{1} at {2}",
114  location.m_Function,
115  layersIndex,
116  location.FileLine()));
117  }
118  else if (layersIndex >= graph->layers()->size())
119  {
120  throw ParseException(fmt::format("{0} was called with an invalid layers index. "
121  "layers:{1} at {2}",
122  location.m_Function,
123  layersIndex,
124  location.FileLine()));
125  }
126  else if (layerIndex >= graph->layers()[layersIndex].size()
127  && layerIndex != VIRTUAL_LAYER_ID)
128  {
129  throw ParseException(fmt::format("{0} was called with an invalid layer index. "
130  "layers:{1} layer:{2} at {3}",
131  location.m_Function,
132  layersIndex,
133  layerIndex,
134  location.FileLine()));
135  }
136 }
137 
138 void CheckTensorPtr(TensorRawPtr rawPtr,
139  const CheckLocation& location)
140 {
141  if (rawPtr == nullptr)
142  {
143  throw ParseException(fmt::format("{0} was called with a null tensor pointer. at {1}",
144  location.m_Function,
145  location.FileLine()));
146  }
147 }
148 
149 void CheckConstTensorPtr(ConstTensorRawPtr rawPtr,
150  const CheckLocation& location)
151 {
152  if (rawPtr == nullptr)
153  {
154  throw ParseException(fmt::format("{0} was called with a null const tensor pointer. at {1}",
155  location.m_Function,
156  location.FileLine()));
157  }
158 }
159 
160 void CheckConstTensorSize(const unsigned int constTensorSize,
161  const unsigned int tensorSize,
162  const CheckLocation& location)
163 {
164  if (constTensorSize != tensorSize)
165  {
166  throw ParseException(fmt::format("{0} wrong number of components supplied to tensor. at:{1}",
167  location.m_Function,
168  location.FileLine()));
169  }
170 }
171 
172 #define CHECK_TENSOR_PTR(TENSOR_PTR) \
173  CheckTensorPtr(TENSOR_PTR, CHECK_LOCATION())
174 
175 #define CHECK_CONST_TENSOR_SIZE(CONST_TENSOR_SIZE, TENSOR_SIZE) \
176  CheckConstTensorSize(CONST_TENSOR_SIZE, TENSOR_SIZE, CHECK_LOCATION())
177 
178 #define CHECK_CONST_TENSOR_PTR(TENSOR_PTR) \
179  CheckConstTensorPtr(TENSOR_PTR, CHECK_LOCATION())
180 
181 #define CHECK_LAYERS(GRAPH, LAYERS_INDEX, LAYER_INDEX) \
182  CheckLayers(GRAPH, LAYERS_INDEX, LAYER_INDEX, CHECK_LOCATION())
183 
184 #define CHECK_GRAPH(GRAPH, LAYERS_INDEX) \
185  CheckGraph(GRAPH, LAYERS_INDEX, CHECK_LOCATION())
186 }
187 
188 bool CheckShape(const armnn::TensorShape& actual, const std::vector<uint32_t>& expected)
189 {
190  const unsigned int actualSize = actual.GetNumDimensions();
191  if (actualSize != expected.size())
192  {
193  return false;
194  }
195 
196  for (unsigned int i = 0u; i < actualSize; i++)
197  {
198  if (actual[i] != static_cast<unsigned int>(expected[i]))
199  {
200  return false;
201  }
202  }
203 
204  return true;
205 }
206 
207 IDeserializer::DeserializerImpl::DeserializerImpl()
208 : m_Network(nullptr, nullptr),
209 //May require LayerType_Max to be included
210 m_ParserFunctions(Layer_MAX+1, &IDeserializer::DeserializerImpl::ParseUnsupportedLayer)
211 {
212  // register supported layers
213  m_ParserFunctions[Layer_AbsLayer] = &DeserializerImpl::ParseAbs;
214  m_ParserFunctions[Layer_ActivationLayer] = &DeserializerImpl::ParseActivation;
215  m_ParserFunctions[Layer_AdditionLayer] = &DeserializerImpl::ParseAdd;
216  m_ParserFunctions[Layer_ArgMinMaxLayer] = &DeserializerImpl::ParseArgMinMax;
217  m_ParserFunctions[Layer_BatchMatMulLayer] = &DeserializerImpl::ParseBatchMatMul;
218  m_ParserFunctions[Layer_BatchToSpaceNdLayer] = &DeserializerImpl::ParseBatchToSpaceNd;
219  m_ParserFunctions[Layer_BatchNormalizationLayer] = &DeserializerImpl::ParseBatchNormalization;
220  m_ParserFunctions[Layer_CastLayer] = &DeserializerImpl::ParseCast;
221  m_ParserFunctions[Layer_ChannelShuffleLayer] = &DeserializerImpl::ParseChannelShuffle;
222  m_ParserFunctions[Layer_ComparisonLayer] = &DeserializerImpl::ParseComparison;
223  m_ParserFunctions[Layer_ConcatLayer] = &DeserializerImpl::ParseConcat;
224  m_ParserFunctions[Layer_ConstantLayer] = &DeserializerImpl::ParseConstant;
225  m_ParserFunctions[Layer_Convolution2dLayer] = &DeserializerImpl::ParseConvolution2d;
226  m_ParserFunctions[Layer_Convolution3dLayer] = &DeserializerImpl::ParseConvolution3d;
227  m_ParserFunctions[Layer_DepthToSpaceLayer] = &DeserializerImpl::ParseDepthToSpace;
228  m_ParserFunctions[Layer_DepthwiseConvolution2dLayer] = &DeserializerImpl::ParseDepthwiseConvolution2d;
229  m_ParserFunctions[Layer_DequantizeLayer] = &DeserializerImpl::ParseDequantize;
230  m_ParserFunctions[Layer_DetectionPostProcessLayer] = &DeserializerImpl::ParseDetectionPostProcess;
231  m_ParserFunctions[Layer_DivisionLayer] = &DeserializerImpl::ParseDivision;
232  m_ParserFunctions[Layer_ElementwiseBinaryLayer] = &DeserializerImpl::ParseElementwiseBinary;
233  m_ParserFunctions[Layer_ElementwiseUnaryLayer] = &DeserializerImpl::ParseElementwiseUnary;
234  m_ParserFunctions[Layer_EqualLayer] = &DeserializerImpl::ParseEqual;
235  m_ParserFunctions[Layer_FullyConnectedLayer] = &DeserializerImpl::ParseFullyConnected;
236  m_ParserFunctions[Layer_FillLayer] = &DeserializerImpl::ParseFill;
237  m_ParserFunctions[Layer_FloorLayer] = &DeserializerImpl::ParseFloor;
238  m_ParserFunctions[Layer_GatherLayer] = &DeserializerImpl::ParseGather;
239  m_ParserFunctions[Layer_GatherNdLayer] = &DeserializerImpl::ParseGatherNd;
240  m_ParserFunctions[Layer_GreaterLayer] = &DeserializerImpl::ParseGreater;
241  m_ParserFunctions[Layer_InstanceNormalizationLayer] = &DeserializerImpl::ParseInstanceNormalization;
242  m_ParserFunctions[Layer_L2NormalizationLayer] = &DeserializerImpl::ParseL2Normalization;
243  m_ParserFunctions[Layer_LogicalBinaryLayer] = &DeserializerImpl::ParseLogicalBinary;
244  m_ParserFunctions[Layer_LogSoftmaxLayer] = &DeserializerImpl::ParseLogSoftmax;
245  m_ParserFunctions[Layer_LstmLayer] = &DeserializerImpl::ParseLstm;
246  m_ParserFunctions[Layer_MaximumLayer] = &DeserializerImpl::ParseMaximum;
247  m_ParserFunctions[Layer_MeanLayer] = &DeserializerImpl::ParseMean;
248  m_ParserFunctions[Layer_MinimumLayer] = &DeserializerImpl::ParseMinimum;
249  m_ParserFunctions[Layer_MergeLayer] = &DeserializerImpl::ParseMerge;
250  m_ParserFunctions[Layer_MergerLayer] = &DeserializerImpl::ParseConcat;
251  m_ParserFunctions[Layer_MultiplicationLayer] = &DeserializerImpl::ParseMultiplication;
252  m_ParserFunctions[Layer_NormalizationLayer] = &DeserializerImpl::ParseNormalization;
253  m_ParserFunctions[Layer_PadLayer] = &DeserializerImpl::ParsePad;
254  m_ParserFunctions[Layer_PermuteLayer] = &DeserializerImpl::ParsePermute;
255  m_ParserFunctions[Layer_Pooling2dLayer] = &DeserializerImpl::ParsePooling2d;
256  m_ParserFunctions[Layer_Pooling3dLayer] = &DeserializerImpl::ParsePooling3d;
257  m_ParserFunctions[Layer_PreluLayer] = &DeserializerImpl::ParsePrelu;
258  m_ParserFunctions[Layer_QLstmLayer] = &DeserializerImpl::ParseQLstm;
259  m_ParserFunctions[Layer_QuantizeLayer] = &DeserializerImpl::ParseQuantize;
260  m_ParserFunctions[Layer_QuantizedLstmLayer] = &DeserializerImpl::ParseQuantizedLstm;
261  m_ParserFunctions[Layer_RankLayer] = &DeserializerImpl::ParseRank;
262  m_ParserFunctions[Layer_ReduceLayer] = &DeserializerImpl::ParseReduce;
263  m_ParserFunctions[Layer_ReshapeLayer] = &DeserializerImpl::ParseReshape;
264  m_ParserFunctions[Layer_ResizeBilinearLayer] = &DeserializerImpl::ParseResizeBilinear;
265  m_ParserFunctions[Layer_ResizeLayer] = &DeserializerImpl::ParseResize;
266  m_ParserFunctions[Layer_ReverseV2Layer] = &DeserializerImpl::ParseReverseV2;
267  m_ParserFunctions[Layer_RsqrtLayer] = &DeserializerImpl::ParseRsqrt;
268  m_ParserFunctions[Layer_ScatterNdLayer] = &DeserializerImpl::ParseScatterNd;
269  m_ParserFunctions[Layer_ShapeLayer] = &DeserializerImpl::ParseShape;
270  m_ParserFunctions[Layer_SliceLayer] = &DeserializerImpl::ParseSlice;
271  m_ParserFunctions[Layer_SoftmaxLayer] = &DeserializerImpl::ParseSoftmax;
272  m_ParserFunctions[Layer_SpaceToBatchNdLayer] = &DeserializerImpl::ParseSpaceToBatchNd;
273  m_ParserFunctions[Layer_SpaceToDepthLayer] = &DeserializerImpl::ParseSpaceToDepth;
274  m_ParserFunctions[Layer_SplitterLayer] = &DeserializerImpl::ParseSplitter;
275  m_ParserFunctions[Layer_StackLayer] = &DeserializerImpl::ParseStack;
276  m_ParserFunctions[Layer_StandInLayer] = &DeserializerImpl::ParseStandIn;
277  m_ParserFunctions[Layer_StridedSliceLayer] = &DeserializerImpl::ParseStridedSlice;
278  m_ParserFunctions[Layer_SubtractionLayer] = &DeserializerImpl::ParseSubtraction;
279  m_ParserFunctions[Layer_SwitchLayer] = &DeserializerImpl::ParseSwitch;
280  m_ParserFunctions[Layer_TileLayer] = &DeserializerImpl::ParseTile;
281  m_ParserFunctions[Layer_TransposeConvolution2dLayer] = &DeserializerImpl::ParseTransposeConvolution2d;
282  m_ParserFunctions[Layer_TransposeLayer] = &DeserializerImpl::ParseTranspose;
283  m_ParserFunctions[Layer_UnidirectionalSequenceLstmLayer] = &DeserializerImpl::ParseUnidirectionalSequenceLstm;
284 }
285 
287 {
288  auto layerType = graphPtr->layers()->Get(layerIndex)->layer_type();
289 
290  switch(layerType)
291  {
292  case Layer::Layer_AbsLayer:
293  return graphPtr->layers()->Get(layerIndex)->layer_as_AbsLayer()->base();
294  case Layer::Layer_ActivationLayer:
295  return graphPtr->layers()->Get(layerIndex)->layer_as_ActivationLayer()->base();
296  case Layer::Layer_AdditionLayer:
297  return graphPtr->layers()->Get(layerIndex)->layer_as_AdditionLayer()->base();
298  case Layer::Layer_ArgMinMaxLayer:
299  return graphPtr->layers()->Get(layerIndex)->layer_as_ArgMinMaxLayer()->base();
300  case Layer::Layer_BatchMatMulLayer:
301  return graphPtr->layers()->Get(layerIndex)->layer_as_BatchMatMulLayer()->base();
302  case Layer::Layer_BatchToSpaceNdLayer:
303  return graphPtr->layers()->Get(layerIndex)->layer_as_BatchToSpaceNdLayer()->base();
304  case Layer::Layer_BatchNormalizationLayer:
305  return graphPtr->layers()->Get(layerIndex)->layer_as_BatchNormalizationLayer()->base();
306  case Layer::Layer_CastLayer:
307  return graphPtr->layers()->Get(layerIndex)->layer_as_CastLayer()->base();
308  case Layer::Layer_ChannelShuffleLayer:
309  return graphPtr->layers()->Get(layerIndex)->layer_as_ChannelShuffleLayer()->base();
310  case Layer::Layer_ComparisonLayer:
311  return graphPtr->layers()->Get(layerIndex)->layer_as_ComparisonLayer()->base();
312  case Layer::Layer_ConcatLayer:
313  return graphPtr->layers()->Get(layerIndex)->layer_as_ConcatLayer()->base();
314  case Layer::Layer_ConstantLayer:
315  return graphPtr->layers()->Get(layerIndex)->layer_as_ConstantLayer()->base();
316  case Layer::Layer_Convolution2dLayer:
317  return graphPtr->layers()->Get(layerIndex)->layer_as_Convolution2dLayer()->base();
318  case Layer::Layer_Convolution3dLayer:
319  return graphPtr->layers()->Get(layerIndex)->layer_as_Convolution3dLayer()->base();
320  case Layer::Layer_DepthToSpaceLayer:
321  return graphPtr->layers()->Get(layerIndex)->layer_as_DepthToSpaceLayer()->base();
322  case Layer::Layer_DepthwiseConvolution2dLayer:
323  return graphPtr->layers()->Get(layerIndex)->layer_as_DepthwiseConvolution2dLayer()->base();
324  case Layer::Layer_DequantizeLayer:
325  return graphPtr->layers()->Get(layerIndex)->layer_as_DequantizeLayer()->base();
326  case Layer::Layer_DetectionPostProcessLayer:
327  return graphPtr->layers()->Get(layerIndex)->layer_as_DetectionPostProcessLayer()->base();
328  case Layer::Layer_DivisionLayer:
329  return graphPtr->layers()->Get(layerIndex)->layer_as_DivisionLayer()->base();
330  case Layer::Layer_EqualLayer:
331  return graphPtr->layers()->Get(layerIndex)->layer_as_EqualLayer()->base();
332  case Layer::Layer_ElementwiseBinaryLayer:
333  return graphPtr->layers()->Get(layerIndex)->layer_as_ElementwiseBinaryLayer()->base();
334  case Layer::Layer_ElementwiseUnaryLayer:
335  return graphPtr->layers()->Get(layerIndex)->layer_as_ElementwiseUnaryLayer()->base();
336  case Layer::Layer_FullyConnectedLayer:
337  return graphPtr->layers()->Get(layerIndex)->layer_as_FullyConnectedLayer()->base();
338  case Layer::Layer_FillLayer:
339  return graphPtr->layers()->Get(layerIndex)->layer_as_FillLayer()->base();
340  case Layer::Layer_FloorLayer:
341  return graphPtr->layers()->Get(layerIndex)->layer_as_FloorLayer()->base();
342  case Layer::Layer_GatherLayer:
343  return graphPtr->layers()->Get(layerIndex)->layer_as_GatherLayer()->base();
344  case Layer::Layer_GatherNdLayer:
345  return graphPtr->layers()->Get(layerIndex)->layer_as_GatherNdLayer()->base();
346  case Layer::Layer_GreaterLayer:
347  return graphPtr->layers()->Get(layerIndex)->layer_as_GreaterLayer()->base();
348  case Layer::Layer_InputLayer:
349  return graphPtr->layers()->Get(layerIndex)->layer_as_InputLayer()->base()->base();
350  case Layer::Layer_InstanceNormalizationLayer:
351  return graphPtr->layers()->Get(layerIndex)->layer_as_InstanceNormalizationLayer()->base();
352  case Layer::Layer_L2NormalizationLayer:
353  return graphPtr->layers()->Get(layerIndex)->layer_as_L2NormalizationLayer()->base();
354  case Layer::Layer_LogicalBinaryLayer:
355  return graphPtr->layers()->Get(layerIndex)->layer_as_LogicalBinaryLayer()->base();
356  case Layer::Layer_LogSoftmaxLayer:
357  return graphPtr->layers()->Get(layerIndex)->layer_as_LogSoftmaxLayer()->base();
358  case Layer::Layer_LstmLayer:
359  return graphPtr->layers()->Get(layerIndex)->layer_as_LstmLayer()->base();
360  case Layer::Layer_MeanLayer:
361  return graphPtr->layers()->Get(layerIndex)->layer_as_MeanLayer()->base();
362  case Layer::Layer_MinimumLayer:
363  return graphPtr->layers()->Get(layerIndex)->layer_as_MinimumLayer()->base();
364  case Layer::Layer_MaximumLayer:
365  return graphPtr->layers()->Get(layerIndex)->layer_as_MaximumLayer()->base();
366  case Layer::Layer_MergeLayer:
367  return graphPtr->layers()->Get(layerIndex)->layer_as_MergeLayer()->base();
368  case Layer::Layer_MergerLayer:
369  return graphPtr->layers()->Get(layerIndex)->layer_as_MergerLayer()->base();
370  case Layer::Layer_MultiplicationLayer:
371  return graphPtr->layers()->Get(layerIndex)->layer_as_MultiplicationLayer()->base();
372  case Layer::Layer_NormalizationLayer:
373  return graphPtr->layers()->Get(layerIndex)->layer_as_NormalizationLayer()->base();
374  case Layer::Layer_OutputLayer:
375  return graphPtr->layers()->Get(layerIndex)->layer_as_OutputLayer()->base()->base();
376  case Layer::Layer_PadLayer:
377  return graphPtr->layers()->Get(layerIndex)->layer_as_PadLayer()->base();
378  case Layer::Layer_PermuteLayer:
379  return graphPtr->layers()->Get(layerIndex)->layer_as_PermuteLayer()->base();
380  case Layer::Layer_Pooling2dLayer:
381  return graphPtr->layers()->Get(layerIndex)->layer_as_Pooling2dLayer()->base();
382  case Layer::Layer_Pooling3dLayer:
383  return graphPtr->layers()->Get(layerIndex)->layer_as_Pooling3dLayer()->base();
384  case Layer::Layer_PreluLayer:
385  return graphPtr->layers()->Get(layerIndex)->layer_as_PreluLayer()->base();
386  case Layer::Layer_QLstmLayer:
387  return graphPtr->layers()->Get(layerIndex)->layer_as_QLstmLayer()->base();
388  case Layer::Layer_QuantizeLayer:
389  return graphPtr->layers()->Get(layerIndex)->layer_as_QuantizeLayer()->base();
390  case Layer::Layer_QuantizedLstmLayer:
391  return graphPtr->layers()->Get(layerIndex)->layer_as_QuantizedLstmLayer()->base();
392  case Layer::Layer_RankLayer:
393  return graphPtr->layers()->Get(layerIndex)->layer_as_RankLayer()->base();
394  case Layer::Layer_ReduceLayer:
395  return graphPtr->layers()->Get(layerIndex)->layer_as_ReduceLayer()->base();
396  case Layer::Layer_ReshapeLayer:
397  return graphPtr->layers()->Get(layerIndex)->layer_as_ReshapeLayer()->base();
398  case Layer::Layer_ResizeBilinearLayer:
399  return graphPtr->layers()->Get(layerIndex)->layer_as_ResizeBilinearLayer()->base();
400  case Layer::Layer_ResizeLayer:
401  return graphPtr->layers()->Get(layerIndex)->layer_as_ResizeLayer()->base();
402  case Layer::Layer_ReverseV2Layer:
403  return graphPtr->layers()->Get(layerIndex)->layer_as_ReverseV2Layer()->base();
404  case Layer::Layer_RsqrtLayer:
405  return graphPtr->layers()->Get(layerIndex)->layer_as_RsqrtLayer()->base();
406  case Layer::Layer_ScatterNdLayer:
407  return graphPtr->layers()->Get(layerIndex)->layer_as_ScatterNdLayer()->base();
408  case Layer::Layer_ShapeLayer:
409  return graphPtr->layers()->Get(layerIndex)->layer_as_ShapeLayer()->base();
410  case Layer::Layer_SliceLayer:
411  return graphPtr->layers()->Get(layerIndex)->layer_as_SliceLayer()->base();
412  case Layer::Layer_SoftmaxLayer:
413  return graphPtr->layers()->Get(layerIndex)->layer_as_SoftmaxLayer()->base();
414  case Layer::Layer_SpaceToBatchNdLayer:
415  return graphPtr->layers()->Get(layerIndex)->layer_as_SpaceToBatchNdLayer()->base();
416  case Layer::Layer_SpaceToDepthLayer:
417  return graphPtr->layers()->Get(layerIndex)->layer_as_SpaceToDepthLayer()->base();
418  case Layer::Layer_SplitterLayer:
419  return graphPtr->layers()->Get(layerIndex)->layer_as_SplitterLayer()->base();
420  case Layer::Layer_StackLayer:
421  return graphPtr->layers()->Get(layerIndex)->layer_as_StackLayer()->base();
422  case Layer::Layer_StandInLayer:
423  return graphPtr->layers()->Get(layerIndex)->layer_as_StandInLayer()->base();
424  case Layer::Layer_StridedSliceLayer:
425  return graphPtr->layers()->Get(layerIndex)->layer_as_StridedSliceLayer()->base();
426  case Layer::Layer_SubtractionLayer:
427  return graphPtr->layers()->Get(layerIndex)->layer_as_SubtractionLayer()->base();
428  case Layer::Layer_SwitchLayer:
429  return graphPtr->layers()->Get(layerIndex)->layer_as_SwitchLayer()->base();
430  case Layer::Layer_TileLayer:
431  return graphPtr->layers()->Get(layerIndex)->layer_as_TileLayer()->base();
432  case Layer::Layer_TransposeConvolution2dLayer:
433  return graphPtr->layers()->Get(layerIndex)->layer_as_TransposeConvolution2dLayer()->base();
434  case Layer::Layer_TransposeLayer:
435  return graphPtr->layers()->Get(layerIndex)->layer_as_TransposeLayer()->base();
436  case Layer::Layer_UnidirectionalSequenceLstmLayer:
437  return graphPtr->layers()->Get(layerIndex)->layer_as_UnidirectionalSequenceLstmLayer()->base();
438  case Layer::Layer_NONE:
439  default:
440  throw ParseException(fmt::format("Layer type {} not recognized", layerType));
441  }
442 }
443 
444 std::string IDeserializer::DeserializerImpl::GetLayerName(const GraphPtr& graph, unsigned int index)
445 {
446  auto layer = GetBaseLayer(graph, index);
447  assert(layer);
448  return layer->layerName()->str();
449 }
450 
451 int32_t IDeserializer::DeserializerImpl::GetBindingLayerInfo(const GraphPtr& graphPtr, unsigned int layerIndex)
452 {
453  auto layerType = graphPtr->layers()->Get(layerIndex)->layer_type();
454 
455  if (layerType == Layer::Layer_InputLayer)
456  {
457  return graphPtr->layers()->Get(layerIndex)->layer_as_InputLayer()->base()->layerBindingId();
458  }
459  else if ( layerType == Layer::Layer_OutputLayer )
460  {
461  return graphPtr->layers()->Get(layerIndex)->layer_as_OutputLayer()->base()->layerBindingId();
462  }
463  return 0;
464 }
465 
467 {
468  switch (dataLayout)
469  {
470  case armnnSerializer::DataLayout::DataLayout_NHWC:
472  case armnnSerializer::DataLayout::DataLayout_NDHWC:
474  case armnnSerializer::DataLayout::DataLayout_NCDHW:
476  case armnnSerializer::DataLayout::DataLayout_NCHW:
477  default:
479  }
480 }
481 
483 {
484  switch (function)
485  {
486  case armnnSerializer::ActivationFunction_Sigmoid:
488  case armnnSerializer::ActivationFunction_TanH:
490  case armnnSerializer::ActivationFunction_Linear:
492  case armnnSerializer::ActivationFunction_ReLu:
494  case armnnSerializer::ActivationFunction_BoundedReLu:
496  case armnnSerializer::ActivationFunction_LeakyReLu:
498  case armnnSerializer::ActivationFunction_Abs:
500  case armnnSerializer::ActivationFunction_Sqrt:
502  case armnnSerializer::ActivationFunction_Square:
504  case armnnSerializer::ActivationFunction_Elu:
506  case armnnSerializer::ActivationFunction_HardSwish:
508  case armnnSerializer::ActivationFunction_Gelu:
510  default:
512  }
513 }
514 
516 {
517  switch (function)
518  {
519  case armnnSerializer::ArgMinMaxFunction::ArgMinMaxFunction_Max:
521  case armnnSerializer::ArgMinMaxFunction::ArgMinMaxFunction_Min:
522  default:
524  }
525 }
526 
528 {
529  switch (function)
530  {
531  case armnnSerializer::ScatterNdFunction_Update:
533  case armnnSerializer::ScatterNdFunction_Add:
535  case armnnSerializer::ScatterNdFunction_Sub:
537  case armnnSerializer::ScatterNdFunction_Max:
539  case armnnSerializer::ScatterNdFunction_Min:
541  default:
543  }
544 }
545 
547 {
548  switch (operation)
549  {
550  case armnnSerializer::ComparisonOperation::ComparisonOperation_Equal:
552  case armnnSerializer::ComparisonOperation::ComparisonOperation_Greater:
554  case armnnSerializer::ComparisonOperation::ComparisonOperation_GreaterOrEqual:
556  case armnnSerializer::ComparisonOperation::ComparisonOperation_Less:
558  case armnnSerializer::ComparisonOperation::ComparisonOperation_LessOrEqual:
560  case armnnSerializer::ComparisonOperation::ComparisonOperation_NotEqual:
561  default:
563  }
564 }
565 
567 {
568  switch (operation)
569  {
570  case armnnSerializer::ReduceOperation::ReduceOperation_Sum:
572  case armnnSerializer::ReduceOperation::ReduceOperation_Max:
574  case armnnSerializer::ReduceOperation::ReduceOperation_Mean:
576  case armnnSerializer::ReduceOperation::ReduceOperation_Min:
578  case armnnSerializer::ReduceOperation::ReduceOperation_Prod:
580  default:
582  }
583 }
584 
586 {
587  switch (operation)
588  {
589  case armnnSerializer::LogicalBinaryOperation::LogicalBinaryOperation_LogicalAnd:
591  case armnnSerializer::LogicalBinaryOperation::LogicalBinaryOperation_LogicalOr:
593  default:
594  throw armnn::InvalidArgumentException("Logical Binary operation unknown");
595  }
596 }
597 
599 {
600  switch (operation)
601  {
602  case armnnSerializer::BinaryOperation::BinaryOperation_Add:
604  case armnnSerializer::BinaryOperation::BinaryOperation_Div:
606  case armnnSerializer::BinaryOperation::BinaryOperation_Maximum:
608  case armnnSerializer::BinaryOperation::BinaryOperation_Minimum:
610  case armnnSerializer::BinaryOperation::BinaryOperation_Mul:
612  case armnnSerializer::BinaryOperation::BinaryOperation_Sub:
614  case armnnSerializer::BinaryOperation::BinaryOperation_SqDiff:
616  case armnnSerializer::BinaryOperation::BinaryOperation_Power:
618  default:
619  throw armnn::InvalidArgumentException("Binary operation unknown");
620  }
621 }
622 
624 {
625  switch (operation)
626  {
627  case armnnSerializer::UnaryOperation::UnaryOperation_Abs:
629  case armnnSerializer::UnaryOperation::UnaryOperation_Ceil:
631  case armnnSerializer::UnaryOperation::UnaryOperation_Rsqrt:
633  case armnnSerializer::UnaryOperation::UnaryOperation_Sqrt:
635  case armnnSerializer::UnaryOperation::UnaryOperation_Exp:
637  case armnnSerializer::UnaryOperation::UnaryOperation_Neg:
639  case armnnSerializer::UnaryOperation::UnaryOperation_LogicalNot:
641  case armnnSerializer::UnaryOperation::UnaryOperation_Log:
643  case armnnSerializer::UnaryOperation::UnaryOperation_Sin:
645  default:
646  throw armnn::InvalidArgumentException("Unary operation unknown");
647  }
648 }
649 
651 {
652  switch (paddingMode)
653  {
654  case armnnSerializer::PaddingMode::PaddingMode_Reflect:
656  case armnnSerializer::PaddingMode::PaddingMode_Symmetric:
658  default:
660  }
661 }
662 
664 {
665  switch (method)
666  {
667  case armnnSerializer::ResizeMethod_NearestNeighbor:
669  case armnnSerializer::ResizeMethod_Bilinear:
671  default:
673  }
674 }
675 
677 {
678  armnn::DataType type;
679  CHECK_TENSOR_PTR(tensorPtr);
680 
681  switch (tensorPtr->dataType())
682  {
683  case DataType_QAsymmS8:
685  break;
686  case DataType_QSymmS8:
688  break;
689  case DataType_QuantisedAsymm8:
690  case DataType_QAsymmU8:
692  break;
693  case DataType_QSymmS16:
694  case DataType_QuantisedSymm16:
696  break;
697  case DataType_Signed32:
699  break;
700  case DataType_Signed64:
702  break;
703  case DataType_Float32:
705  break;
706  case DataType_Float16:
708  break;
709  case DataType_Boolean:
711  break;
712  default:
713  {
714  CheckLocation location = CHECK_LOCATION();
715  throw ParseException(fmt::format("Unsupported data type {0} = {1}. {2}",
716  tensorPtr->dataType(),
717  EnumNameDataType(tensorPtr->dataType()),
718  location.AsString()));
719  }
720  }
721 
722  float quantizationScale = tensorPtr->quantizationScale();
723  int32_t quantizationOffset = tensorPtr->quantizationOffset();
724 
725  if (tensorPtr->dimensionality() == static_cast<unsigned int>(Dimensionality::Scalar))
726  {
728  type,
729  quantizationScale,
730  quantizationOffset);
731  }
732  else if (tensorPtr->dimensionality() == static_cast<unsigned int>(Dimensionality::NotSpecified))
733  {
734  armnn::TensorInfo result(TensorShape{Dimensionality::NotSpecified},
735  type,
736  quantizationScale,
737  quantizationOffset);
738  return result;
739  }
740 
741  auto dimensions = tensorPtr->dimensions();
742  unsigned int size = dimensions->size();
743  std::vector<unsigned int> outputDims(dimensions->begin(), dimensions->begin() + size);
744  bool dimensionsSpecificity[armnn::MaxNumOfTensorDimensions];
745  std::fill_n(dimensionsSpecificity, armnn::MaxNumOfTensorDimensions, true);
746  // For backwards compatibility check if the dimensionSpecificity vector is present first.
747  // The default is to have dimensionSpecificity set to all true's anyway.
748  if (tensorPtr->dimensionSpecificity() != nullptr)
749  {
750  auto dimensionSpecificity = tensorPtr->dimensionSpecificity();
751  size = dimensionSpecificity->size();
752  for (unsigned int i = 0; i < size; ++i)
753  {
754  dimensionsSpecificity[i] = dimensionSpecificity->Get(i);
755  }
756  }
757  // Construct a TensorShape
758  TensorShape shape(size, outputDims.data(), dimensionsSpecificity);
759 
760  auto quantizationScales = tensorPtr->quantizationScales();
761  if (quantizationScales)
762  {
763  unsigned int quantizationScalesSize = quantizationScales->size();
764  std::vector<float> scales(quantizationScales->begin(), quantizationScales->begin() + quantizationScalesSize);
765  unsigned int quantizationDim = tensorPtr->quantizationDim();
766  armnn::TensorInfo result(shape,
767  type,
768  scales,
769  quantizationDim);
770  return result;
771  }
772 
773  // two statements (on purpose) for easier debugging:
774  armnn::TensorInfo result(shape,
775  type,
776  quantizationScale,
777  quantizationOffset);
778 
779  return result;
780 }
781 
783 {
784  CHECK_CONST_TENSOR_PTR(constTensorPtr);
785  armnn::TensorInfo tensorInfo = ToTensorInfo(constTensorPtr->info());
786  tensorInfo.SetConstant();
787 
788  switch (constTensorPtr->data_type())
789  {
790  case ConstTensorData_ByteData:
791  {
792  auto byteData = constTensorPtr->data_as_ByteData()->data();
793  CHECK_CONST_TENSOR_SIZE(byteData->size(), tensorInfo.GetNumElements());
794  return armnn::ConstTensor(tensorInfo, byteData->data());
795  }
796  case ConstTensorData_ShortData:
797  {
798  auto shortData = constTensorPtr->data_as_ShortData()->data();
799  CHECK_CONST_TENSOR_SIZE(shortData->size(), tensorInfo.GetNumElements());
800  return armnn::ConstTensor(tensorInfo, shortData->data());
801  }
802  case ConstTensorData_IntData:
803  {
804  auto intData = constTensorPtr->data_as_IntData()->data();
805  CHECK_CONST_TENSOR_SIZE(intData->size(), tensorInfo.GetNumElements());
806  return armnn::ConstTensor(tensorInfo, intData->data());
807  }
808  case ConstTensorData_LongData:
809  {
810  auto longData = constTensorPtr->data_as_LongData()->data();
811  CHECK_CONST_TENSOR_SIZE(longData->size(), tensorInfo.GetNumElements());
812  return armnn::ConstTensor(tensorInfo, longData->data());
813  }
814  default:
815  {
816  CheckLocation location = CHECK_LOCATION();
817  throw ParseException(fmt::format("Unsupported data type {0} = {1}. {2}",
818  constTensorPtr->data_type(),
819  EnumNameConstTensorData(constTensorPtr->data_type()),
820  location.AsString()));
821  }
822  }
823 }
824 
826 {
827  CHECK_LAYERS(graphPtr, 0, layerIndex);
828  auto layer = GetBaseLayer(graphPtr, layerIndex);
829  const auto& numInputs = layer->inputSlots()->size();
830 
831  TensorRawPtrVector result(numInputs);
832 
833  for (unsigned int i=0; i<numInputs; ++i)
834  {
835  auto inputId = CHECKED_NON_NEGATIVE(static_cast<int32_t>
836  (layer->inputSlots()->Get(i)->connection()->sourceLayerIndex()));
837  result[i] = GetBaseLayer(graphPtr, inputId)->outputSlots()->Get(0)->tensorInfo();
838  }
839  return result;
840 }
841 
843 {
844  CHECK_LAYERS(graphPtr, 0, layerIndex);
845  auto layer = GetBaseLayer(graphPtr, layerIndex);
846  const auto& numOutputs = layer->outputSlots()->size();
847 
848  TensorRawPtrVector result(numOutputs);
849 
850  for (unsigned int i=0; i<numOutputs; ++i)
851  {
852  result[i] = layer->outputSlots()->Get(i)->tensorInfo();
853  }
854  return result;
855 }
856 
857 void IDeserializer::DeserializerImpl::ParseUnsupportedLayer(GraphPtr graph, unsigned int layerIndex)
858 {
859  CHECK_LAYERS(graph, 0, layerIndex);
860  const auto layerName = GetBaseLayer(graph, layerIndex)->layerName()->c_str();
861  throw ParseException(fmt::format("Layer not supported. layerIndex: {0} "
862  "layerName: {1} / {2}",
863  layerIndex,
864  layerName,
865  CHECK_LOCATION().AsString()));
866 }
867 
868 void IDeserializer::DeserializerImpl::ResetParser()
869 {
870  m_Network = armnn::INetworkPtr(nullptr, nullptr);
871  m_InputBindings.clear();
872  m_OutputBindings.clear();
873 }
874 
875 
877 {
878  ResetParser();
879  GraphPtr graph = LoadGraphFromBinary(binaryContent.data(), binaryContent.size());
880  return CreateNetworkFromGraph(graph);
881 }
882 
884 {
885  ResetParser();
886  if (binaryContent.fail()) {
887  ARMNN_LOG(error) << (std::string("Cannot read input"));
888  throw ParseException("Unable to read Input stream data");
889  }
890  binaryContent.seekg(0, std::ios::end);
891  const std::streamoff size = binaryContent.tellg();
892  std::vector<char> content(static_cast<size_t>(size));
893  binaryContent.seekg(0);
894  binaryContent.read(content.data(), static_cast<std::streamsize>(size));
895  GraphPtr graph = LoadGraphFromBinary(reinterpret_cast<uint8_t*>(content.data()), static_cast<size_t>(size));
896  return CreateNetworkFromGraph(graph);
897 }
898 
899 GraphPtr IDeserializer::DeserializerImpl::LoadGraphFromBinary(const uint8_t* binaryContent, size_t len)
900 {
901  if (binaryContent == nullptr)
902  {
903  throw InvalidArgumentException(fmt::format("Invalid (null) binary content {}",
904  CHECK_LOCATION().AsString()));
905  }
906  flatbuffers::Verifier verifier(binaryContent, len);
907  if (verifier.VerifyBuffer<SerializedGraph>() == false)
908  {
909  throw ParseException(fmt::format("Buffer doesn't conform to the expected Armnn "
910  "flatbuffers format. size:{0} {1}",
911  len,
912  CHECK_LOCATION().AsString()));
913  }
914  return GetSerializedGraph(binaryContent);
915 }
916 
917 INetworkPtr IDeserializer::DeserializerImpl::CreateNetworkFromGraph(GraphPtr graph)
918 {
919  if (graph == nullptr)
920  {
921  throw armnn::InvalidArgumentException("CreateNetworkFromGraph: graph pointer is null");
922  }
923  m_Network = INetwork::Create();
924  unsigned int layerIndex = 0;
925  for (AnyLayer const* layer : *graph->layers())
926  {
927  if (layer->layer_type() != Layer_InputLayer &&
928  layer->layer_type() != Layer_OutputLayer)
929  {
930  // lookup and call the parser function
931  auto& parserFunction = m_ParserFunctions[layer->layer_type()];
932  (this->*parserFunction)(graph, layerIndex);
933  }
934  ++layerIndex;
935  }
936 
937  SetupInputLayers(graph);
938  SetupOutputLayers(graph);
939 
940  // establish the connections from the layer outputs to the inputs of the subsequent layers
941  for (auto&& graphIt : m_GraphConnections)
942  {
943  Connections& connections = graphIt.second;
944  for (auto&& outputIt : connections.outputSlots)
945  {
946  const unsigned int outputSlotIndex = outputIt.first;
947  IOutputSlot* outputSlot = outputIt.second;
948  if (connections.inputSlots.find(outputSlotIndex) != connections.inputSlots.end())
949  {
950  for (IInputSlot* inputSlot : connections.inputSlots[outputSlotIndex])
951  {
952  outputSlot->Connect(*inputSlot);
953  }
954  }
955  }
956  }
957 
958  return std::move(m_Network);
959 }
960 
962  const std::string& name) const
963 {
964  IgnoreUnused(layerIndex);
965  for (auto inputBinding : m_InputBindings)
966  {
967  if (inputBinding.first == name)
968  {
969  return inputBinding.second;
970  }
971  }
972  throw ParseException(fmt::format("No input binding found for layer:{0} / {1}",
973  name,
974  CHECK_LOCATION().AsString()));
975 }
976 
978  const std::string& name) const
979 {
980  IgnoreUnused(layerIndex);
981  for (auto outputBinding : m_OutputBindings)
982  {
983  if (outputBinding.first == name)
984  {
985  return outputBinding.second;
986  }
987  }
988  throw ParseException(fmt::format("No output binding found for layer:{0} / {1}",
989  name,
990  CHECK_LOCATION().AsString()));
991 }
992 
993 unsigned int IDeserializer::DeserializerImpl::GetInputLayerInVector(GraphPtr graph, int targetId)
994 {
995  for (unsigned int i = 0; i < graph->layers()->size(); i++)
996  {
997  auto layer = graph->layers()->Get(i);
998  if (layer->layer_type() == Layer::Layer_InputLayer)
999  {
1000  auto layerBindingId = layer->layer_as_InputLayer()->base()->layerBindingId();
1001  if (layerBindingId == targetId)
1002  {
1003  return i;
1004  }
1005  }
1006  }
1007  throw ParseException("Input layer with given layerBindingId not found");
1008 }
1009 
1010 unsigned int IDeserializer::DeserializerImpl::GetOutputLayerInVector(GraphPtr graph, int targetId)
1011 {
1012  for (unsigned int i = 0; i < graph->layers()->size(); i++)
1013  {
1014  auto layer = graph->layers()->Get(i);
1015  if (layer->layer_type() == Layer::Layer_OutputLayer)
1016  {
1017  auto layerBindingId = layer->layer_as_OutputLayer()->base()->layerBindingId();
1018  if (layerBindingId == targetId)
1019  {
1020  return i;
1021  }
1022  }
1023  }
1024  throw ParseException("Output layer with given layerBindingId not found");
1025 }
1026 
1027 unsigned int IDeserializer::DeserializerImpl::GetLayerIndexInVector(GraphPtr graph, unsigned int targetIndex)
1028 {
1029  for (unsigned int i = 0; i < graph->layers()->size(); i++)
1030  {
1031  LayerBaseRawPtr layer = GetBaseLayer(graph, i);
1032  if (layer->index() == targetIndex)
1033  {
1034  return i;
1035  }
1036  }
1037  throw ParseException("Layer with given index not found");
1038 }
1039 
1040 IDeserializer::DeserializerImpl::FeatureVersions IDeserializer::DeserializerImpl::GetFeatureVersions(GraphPtr graph)
1041 {
1042  IDeserializer::DeserializerImpl::FeatureVersions versions;
1043 
1044  if (graph->featureVersions())
1045  {
1046  versions.m_BindingIdScheme = graph->featureVersions()->bindingIdsScheme();
1047  versions.m_WeightsLayoutScheme = graph->featureVersions()->weightsLayoutScheme();
1048  versions.m_ConstTensorsAsInputs = graph->featureVersions()->constantTensorsAsInputs();
1049  }
1050 
1051  return versions;
1052 }
1053 
1054 void IDeserializer::DeserializerImpl::SetupInputLayers(GraphPtr graph)
1055 {
1056  CHECK_GRAPH(graph, 0);
1057  const unsigned int numInputs = graph->inputIds()->size();
1058  m_InputBindings.clear();
1059  m_InputBindings.reserve(numInputs);
1060 
1061  for (unsigned int i = 0; i < numInputs; i++)
1062  {
1063  unsigned int inputLayerIndex = 0xFFFFFFFF;
1064  if (GetFeatureVersions(graph).m_BindingIdScheme == 0)
1065  {
1066  const unsigned int inputId = armnn::numeric_cast<unsigned int>(graph->inputIds()->Get(i));
1067  inputLayerIndex = GetLayerIndexInVector(graph, inputId);
1068  }
1069  else
1070  {
1071  const int inputId = graph->inputIds()->Get(i);
1072  inputLayerIndex = GetInputLayerInVector(graph, inputId);
1073  }
1074 
1075  LayerBaseRawPtr baseLayer = GetBaseLayer(graph, inputLayerIndex);
1076 
1077  // GetBindingLayerInfo expect the index to be index in the vector not index property on each layer base
1078  LayerBindingId bindingId = GetBindingLayerInfo(graph, inputLayerIndex);
1079  if (baseLayer->layerName()->c_str() == nullptr)
1080  {
1081  throw ParseException(fmt::format("Input with layer index [{0}] has no name", inputLayerIndex));
1082  }
1083 
1084  IConnectableLayer* inputLayer =
1085  m_Network->AddInputLayer(bindingId, baseLayer->layerName()->c_str());
1086 
1087  const armnn::TensorInfo& tensorInfo = ToTensorInfo(baseLayer->outputSlots()->Get(0)->tensorInfo());
1088  inputLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1089  RegisterOutputSlots(graph, inputLayerIndex, inputLayer);
1090 
1091  BindingPointInfo bindingInfo = {bindingId, tensorInfo};
1092  m_InputBindings.push_back(std::make_pair(baseLayer->layerName()->c_str(), bindingInfo));
1093  }
1094 }
1095 
1096 void IDeserializer::DeserializerImpl::SetupOutputLayers(GraphPtr graph)
1097 {
1098  CHECK_GRAPH(graph, 0);
1099  const unsigned int numOutputs = graph->outputIds()->size();
1100  m_OutputBindings.clear();
1101  m_OutputBindings.reserve(numOutputs);
1102 
1103  for (unsigned int i = 0; i < numOutputs; i++)
1104  {
1105  unsigned int outputLayerIndex = 0xFFFFFFFF;
1106  if (GetFeatureVersions(graph).m_BindingIdScheme == 0)
1107  {
1108  const unsigned int outputId = armnn::numeric_cast<unsigned int>(graph->outputIds()->Get(i));
1109  outputLayerIndex = GetLayerIndexInVector(graph, outputId);
1110  }
1111  else
1112  {
1113  const int outputId = graph->outputIds()->Get(i);
1114  outputLayerIndex = GetOutputLayerInVector(graph, outputId);
1115  }
1116 
1117  LayerBaseRawPtr baseLayer = GetBaseLayer(graph, outputLayerIndex);
1118 
1119  // GetBindingLayerInfo expect the index to be index in the vector not index property on each layer base
1120  LayerBindingId bindingId = GetBindingLayerInfo(graph, outputLayerIndex);
1121  if (baseLayer->layerName()->c_str() == nullptr)
1122  {
1123  throw ParseException(fmt::format("Output with layer index [{0}] has no name", outputLayerIndex));
1124  }
1125 
1126  IConnectableLayer* outputLayer =
1127  m_Network->AddOutputLayer(bindingId, baseLayer->layerName()->c_str());
1128 
1129  RegisterInputSlots(graph, outputLayerIndex, outputLayer);
1130  unsigned int sourceLayerIndex =
1131  GetLayerIndexInVector(graph, baseLayer->inputSlots()->Get(0)->connection()->sourceLayerIndex());
1132  unsigned int outputSlotIndex =
1133  GetLayerIndexInVector(graph, baseLayer->inputSlots()->Get(0)->connection()->outputSlotIndex());
1134  LayerBaseRawPtr sourceBaseLayer = GetBaseLayer(graph, sourceLayerIndex);
1135  const armnn::TensorInfo& tensorInfo = ToTensorInfo(
1136  sourceBaseLayer->outputSlots()->Get(outputSlotIndex)->tensorInfo());
1137  BindingPointInfo bindingInfo = {bindingId, tensorInfo};
1138  m_OutputBindings.push_back(std::make_pair(baseLayer->layerName()->c_str(), bindingInfo));
1139  }
1140 }
1141 
1142 void IDeserializer::DeserializerImpl::RegisterOutputSlots(GraphPtr graph,
1143  uint32_t layerIndex,
1144  IConnectableLayer* layer)
1145 {
1146  if (layer == nullptr)
1147  {
1148  throw ParseException(fmt::format(
1149  "RegisterOutputSlots: pointer to layer with index [{0}] is null", layerIndex));
1150  }
1151  CHECK_LAYERS(graph, 0, layerIndex);
1152  LayerBaseRawPtr baseLayer = GetBaseLayer(graph, layerIndex);
1153  if (baseLayer->outputSlots()->size() != layer->GetNumOutputSlots())
1154  {
1155  throw ParseException(fmt::format("The number of outputslots ({0}) does not match the number expected ({1})"
1156  " for layer index: {2} {3}",
1157  baseLayer->outputSlots()->size(),
1158  layer->GetNumOutputSlots(),
1159  layerIndex,
1160  CHECK_LOCATION().AsString()));
1161  }
1162 
1163  for (unsigned int i = 0; i < layer->GetNumOutputSlots(); ++i)
1164  {
1165  const unsigned int slotIndex = baseLayer->outputSlots()->Get(i)->index();
1166  armnn::IOutputSlot* outputSlot = &(layer->GetOutputSlot(slotIndex));
1167  // layerIndex is not necessarily the same as baseLayer->index(). The latter is needed here
1168  RegisterOutputSlotOfConnection(baseLayer->index(), slotIndex, outputSlot);
1169  }
1170 }
1171 
1172 void IDeserializer::DeserializerImpl::RegisterInputSlots(GraphPtr graph,
1173  uint32_t layerIndex,
1174  armnn::IConnectableLayer* layer,
1175  std::vector<unsigned int> ignoreSlots)
1176 {
1177  if (layer == nullptr)
1178  {
1179  throw ParseException(fmt::format(
1180  "RegisterInputSlots: pointer to layer with index [{0}] is null", layerIndex));
1181  }
1182  CHECK_LAYERS(graph, 0, layerIndex);
1183  LayerBaseRawPtr baseLayer = GetBaseLayer(graph, layerIndex);
1184 
1185  if (baseLayer->inputSlots()->size() != (layer->GetNumInputSlots() - ignoreSlots.size()))
1186  {
1187  throw ParseException(fmt::format("The number of inputslots ({0}) does not match the number expected ({1})"
1188  " for layer index:{2} {3}",
1189  baseLayer->inputSlots()->size(),
1190  layer->GetNumInputSlots(),
1191  layerIndex,
1192  CHECK_LOCATION().AsString()));
1193  }
1194 
1195  for (unsigned int i = 0; i < layer->GetNumInputSlots(); ++i)
1196  {
1197  // Check if slot should be ignored.
1198  if (std::find(ignoreSlots.begin(), ignoreSlots.end(), i) == ignoreSlots.end())
1199  {
1200  auto fbInputSlot = baseLayer->inputSlots()->Get(i);
1201  auto fbConnection = fbInputSlot->connection();
1202  armnn::IInputSlot* inputSlot = &(layer->GetInputSlot(fbInputSlot->index()));
1203 
1204  // If the slot has an Overridden tensorInfo then extract it
1205  if (fbInputSlot->isOverridden())
1206  {
1207  armnn::TensorInfo overriddenTensorInfo = ToTensorInfo(fbInputSlot->overriddenTensorInfo());
1208  inputSlot->SetTensorInfo(overriddenTensorInfo);
1209  }
1210  RegisterInputSlotOfConnection(fbConnection->sourceLayerIndex(), fbConnection->outputSlotIndex(), inputSlot);
1211  }
1212  }
1213 }
1214 
1215 void IDeserializer::DeserializerImpl::RegisterInputSlotOfConnection(uint32_t sourceLayerIndex,
1216  uint32_t outputSlotIndex,
1217  armnn::IInputSlot* inputSlot)
1218 {
1219  if (m_GraphConnections.find(sourceLayerIndex) == m_GraphConnections.end())
1220  {
1221  m_GraphConnections[sourceLayerIndex] = Connections();
1222  }
1223 
1224  Connections& connections = m_GraphConnections[sourceLayerIndex];
1225  if (connections.inputSlots.find(outputSlotIndex) == connections.inputSlots.end())
1226  {
1227  connections.inputSlots[outputSlotIndex] = {inputSlot};
1228  }
1229  else
1230  {
1231  connections.inputSlots[outputSlotIndex].push_back(inputSlot);
1232  }
1233 }
1234 
1235 void IDeserializer::DeserializerImpl::RegisterOutputSlotOfConnection(uint32_t sourceLayerIndex,
1236  uint32_t outputSlotIndex,
1237  armnn::IOutputSlot* outputSlot)
1238 {
1239  if (m_GraphConnections.find(sourceLayerIndex) == m_GraphConnections.end())
1240  {
1241  m_GraphConnections[sourceLayerIndex] = Connections();
1242  }
1243 
1244  Connections& connections = m_GraphConnections[sourceLayerIndex];
1245  if (connections.outputSlots.find(outputSlotIndex) != connections.outputSlots.end())
1246  {
1247  throw ParseException("Same output slot index processed twice");
1248  }
1249 
1250  connections.outputSlots[outputSlotIndex] = outputSlot;
1251 }
1252 
1253 void IDeserializer::DeserializerImpl::ParseAbs(GraphPtr graph, unsigned int layerIndex)
1254 {
1255  CHECK_LAYERS(graph, 0, layerIndex);
1256  auto inputs = GetInputs(graph, layerIndex);
1257  CHECK_LOCATION();
1258  CHECK_VALID_SIZE(inputs.size(), 1);
1259 
1260  auto outputs = GetOutputs(graph, layerIndex);
1261  CHECK_VALID_SIZE(outputs.size(), 1);
1262 
1263  auto layerName = GetLayerName(graph, layerIndex);
1264 
1266  IConnectableLayer* layer = m_Network->AddElementwiseUnaryLayer(descriptor, layerName.c_str());
1267  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1268  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1269 
1270  RegisterInputSlots(graph, layerIndex, layer);
1271  RegisterOutputSlots(graph, layerIndex, layer);
1272 }
1273 
1274 void IDeserializer::DeserializerImpl::ParseActivation(GraphPtr graph, unsigned int layerIndex)
1275 {
1276  CHECK_LAYERS(graph, 0, layerIndex);
1277  auto inputs = GetInputs(graph, layerIndex);
1278  CHECK_LOCATION();
1279  CHECK_VALID_SIZE(inputs.size(), 1);
1280 
1281  auto outputs = GetOutputs(graph, layerIndex);
1282  CHECK_VALID_SIZE(outputs.size(), 1);
1283 
1284  auto serializerLayer = graph->layers()->Get(layerIndex)->layer_as_ActivationLayer();
1285  auto layerName = GetLayerName(graph, layerIndex);
1286  auto serializerDescriptor = serializerLayer->descriptor();
1287 
1288  armnn::ActivationDescriptor descriptor;
1289  descriptor.m_Function = ToActivationFunction(serializerDescriptor->activationFunction());
1290  descriptor.m_A = serializerDescriptor->a();
1291  descriptor.m_B = serializerDescriptor->b();
1292 
1293  IConnectableLayer* layer = m_Network->AddActivationLayer(descriptor,
1294  layerName.c_str());
1295  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1296  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1297 
1298  RegisterInputSlots(graph, layerIndex, layer);
1299  RegisterOutputSlots(graph, layerIndex, layer);
1300 }
1301 
1302 void IDeserializer::DeserializerImpl::ParseAdd(GraphPtr graph, unsigned int layerIndex)
1303 {
1304  CHECK_LAYERS(graph, 0, layerIndex);
1305  auto inputs = GetInputs(graph, layerIndex);
1306  CHECK_LOCATION();
1307  CHECK_VALID_SIZE(inputs.size(), 2);
1308 
1309  auto outputs = GetOutputs(graph, layerIndex);
1310  CHECK_VALID_SIZE(outputs.size(), 1);
1311 
1312  auto layerName = GetLayerName(graph, layerIndex);
1314  IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(descriptor, layerName.c_str());
1315 
1316  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1317  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1318 
1319  RegisterInputSlots(graph, layerIndex, layer);
1320  RegisterOutputSlots(graph, layerIndex, layer);
1321 }
1322 
1323 void IDeserializer::DeserializerImpl::ParseArgMinMax(GraphPtr graph, unsigned int layerIndex)
1324 {
1325  CHECK_LAYERS(graph, 0, layerIndex);
1326  auto inputs = GetInputs(graph, layerIndex);
1327  CHECK_LOCATION();
1328  CHECK_VALID_SIZE(inputs.size(), 1);
1329 
1330  auto outputs = GetOutputs(graph, layerIndex);
1331  CHECK_VALID_SIZE(outputs.size(), 1);
1332 
1333  auto serializerLayer = graph->layers()->Get(layerIndex)->layer_as_ArgMinMaxLayer();
1334  auto serializerDescriptor = serializerLayer->descriptor();
1335 
1336  armnn::ArgMinMaxDescriptor descriptor;
1337  descriptor.m_Function = ToArgMinMaxFunction(serializerDescriptor->argMinMaxFunction());
1338  descriptor.m_Axis = serializerDescriptor->axis();
1339  auto layerName = GetLayerName(graph, layerIndex);
1340  IConnectableLayer* layer = m_Network->AddArgMinMaxLayer(descriptor, layerName.c_str());
1341 
1342  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1343  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1344 
1345  RegisterInputSlots(graph, layerIndex, layer);
1346  RegisterOutputSlots(graph, layerIndex, layer);
1347 }
1348 
1349 void IDeserializer::DeserializerImpl::ParseBatchMatMul(GraphPtr graph, unsigned int layerIndex)
1350 {
1351  CHECK_LAYERS(graph, 0, layerIndex);
1352 
1353  auto inputs = GetInputs(graph, layerIndex);
1354  CHECK_LOCATION();
1355  CHECK_VALID_SIZE(inputs.size(), 2);
1356 
1357  auto outputs = GetOutputs(graph, layerIndex);
1358  CHECK_VALID_SIZE(outputs.size(), 1);
1359 
1360  auto serializerLayer = graph->layers()->Get(layerIndex)->layer_as_BatchMatMulLayer();
1361  auto serializerDescriptor = serializerLayer->descriptor();
1362 
1363  armnn::BatchMatMulDescriptor descriptor(serializerDescriptor->transposeX(),
1364  serializerDescriptor->transposeY(),
1365  serializerDescriptor->adjointX(),
1366  serializerDescriptor->adjointY(),
1367  ToDataLayout(serializerDescriptor->dataLayoutX()),
1368  ToDataLayout(serializerDescriptor->dataLayoutY()));
1369 
1370  auto layerName = GetLayerName(graph, layerIndex);
1371  IConnectableLayer* layer = m_Network->AddBatchMatMulLayer(descriptor, layerName.c_str());
1372 
1373  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1374  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1375 
1376  RegisterInputSlots(graph, layerIndex, layer);
1377  RegisterOutputSlots(graph, layerIndex, layer);
1378 }
1379 
1380 void IDeserializer::DeserializerImpl::ParseBatchToSpaceNd(GraphPtr graph, unsigned int layerIndex)
1381 {
1382  CHECK_LAYERS(graph, 0, layerIndex);
1383 
1384  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
1385  CHECK_VALID_SIZE(inputs.size(), 1);
1386 
1387  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
1388  CHECK_VALID_SIZE(outputs.size(), 1);
1389 
1390  auto flatBufferDescriptor = graph->layers()->Get(layerIndex)->layer_as_BatchToSpaceNdLayer()->descriptor();
1391  auto flatBufferCrops = flatBufferDescriptor->crops();
1392  auto flatBufferBlockShape = flatBufferDescriptor->blockShape();
1393 
1394  if (flatBufferCrops->size() % 2 != 0)
1395  {
1396  throw ParseException(fmt::format("The size of crops must be divisible by 2 {}", CHECK_LOCATION().AsString()));
1397  }
1398 
1399  std::vector<std::pair<unsigned int, unsigned int>> crops;
1400  crops.reserve(flatBufferCrops->size() / 2);
1401  for (unsigned int i = 0; i < flatBufferCrops->size() - 1; i += 2)
1402  {
1403  crops.emplace_back(flatBufferCrops->Get(i), flatBufferCrops->Get(i+1));
1404  }
1405 
1407  descriptor.m_DataLayout = ToDataLayout(flatBufferDescriptor->dataLayout());
1408  descriptor.m_BlockShape =
1409  std::vector<unsigned int>(flatBufferBlockShape->begin(), flatBufferBlockShape->end());
1410  descriptor.m_Crops = crops;
1411 
1412  auto layerName = GetLayerName(graph, layerIndex);
1413  IConnectableLayer* layer = m_Network->AddBatchToSpaceNdLayer(descriptor, layerName.c_str());
1414 
1415  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1416  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1417 
1418  RegisterInputSlots(graph, layerIndex, layer);
1419  RegisterOutputSlots(graph, layerIndex, layer);
1420 }
1421 
1422 void IDeserializer::DeserializerImpl::ParseBatchNormalization(GraphPtr graph, unsigned int layerIndex)
1423 {
1424  CHECK_LAYERS(graph, 0, layerIndex);
1425 
1426  auto inputs = GetInputs(graph, layerIndex);
1427  CHECK_VALID_SIZE(inputs.size(), 1);
1428 
1429  auto outputs = GetOutputs(graph, layerIndex);
1430  CHECK_VALID_SIZE(outputs.size(), 1);
1431  auto outputInfo = ToTensorInfo(outputs[0]);
1432 
1433  auto layerName = GetLayerName(graph, layerIndex);
1434 
1435  auto serializerLayer = graph->layers()->Get(layerIndex)->layer_as_BatchNormalizationLayer();
1436  auto serializerDescriptor = serializerLayer->descriptor();
1437 
1439  descriptor.m_Eps = serializerDescriptor->eps();
1440  descriptor.m_DataLayout = ToDataLayout(serializerDescriptor->dataLayout());
1441 
1442  armnn::ConstTensor mean = ToConstTensor(serializerLayer->mean());
1443  armnn::ConstTensor variance = ToConstTensor(serializerLayer->variance());
1444  armnn::ConstTensor beta = ToConstTensor(serializerLayer->beta());
1445  armnn::ConstTensor gamma = ToConstTensor(serializerLayer->gamma());
1446 
1447  IConnectableLayer* layer = m_Network->AddBatchNormalizationLayer(descriptor,
1448  mean,
1449  variance,
1450  beta,
1451  gamma,
1452  layerName.c_str());
1453  layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1454 
1455  RegisterInputSlots(graph, layerIndex, layer);
1456  RegisterOutputSlots(graph, layerIndex, layer);
1457 }
1458 
1459 void IDeserializer::DeserializerImpl::ParseCast(GraphPtr graph, unsigned int layerIndex)
1460 {
1461  CHECK_LAYERS(graph, 0, layerIndex);
1462  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
1463  CHECK_LOCATION();
1464  CHECK_VALID_SIZE(inputs.size(), 1);
1465 
1466  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
1467  CHECK_VALID_SIZE(outputs.size(), 1);
1468 
1469  auto layerName = GetLayerName(graph, layerIndex);
1470 
1471  IConnectableLayer* layer = m_Network->AddCastLayer(layerName.c_str());
1472 
1473  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1474  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1475 
1476  RegisterInputSlots(graph, layerIndex, layer);
1477  RegisterOutputSlots(graph, layerIndex, layer);
1478 }
1479 
1480 void IDeserializer::DeserializerImpl::ParseConstant(GraphPtr graph, unsigned int layerIndex)
1481 {
1482  CHECK_LAYERS(graph, 0, layerIndex);
1483  CHECK_LOCATION();
1484 
1485  auto outputs = GetOutputs(graph, layerIndex);
1486  CHECK_VALID_SIZE(outputs.size(), 1);
1487 
1488  auto layerName = GetLayerName(graph, layerIndex);
1489 
1490  auto serializerLayer = graph->layers()->Get(layerIndex)->layer_as_ConstantLayer();
1491  auto serializerInput = serializerLayer->input();
1492 
1493  armnn::ConstTensor input = ToConstTensor(serializerInput);
1494  IConnectableLayer* layer;
1495 
1496  // Required for when Constant Layer is used as an inputs to DepthwiseConvolution2d Layer.
1497  // Running a model that was created before weights layout scheme version was added to our flatbuffers
1498  // file ensuring older models can still be read and executed. featureVersion weights layout scheme 1
1499  // indicates a change in the depthwise weights layout within ArmNN from [M,I,H,W] --> [1,H,W,I*M]
1500  if (this->GetFeatureVersions(graph).m_WeightsLayoutScheme <= 0)
1501  {
1502  // Permute weights [ H, W, M, I ] --> [ 1, H, W, I*M ]
1503  // Step1: [ M, I, H, W ] --> [ H, W, I, M]
1504  PermutationVector permutationVector = { 3, 2, 0, 1 };
1505  armnn::TensorInfo weightsInfo = input.GetInfo();
1506  std::unique_ptr<unsigned char[]> permuteBuffer(new unsigned char[weightsInfo.GetNumBytes()]);
1507  weightsInfo = armnnUtils::Permuted(weightsInfo, permutationVector);
1508  armnnUtils::Permute(weightsInfo.GetShape(), permutationVector,
1509  input.GetMemoryArea(), permuteBuffer.get(),
1510  GetDataTypeSize(weightsInfo.GetDataType()));
1511 
1512  // Step2: Reshape [ H, W, I, M] --> [ 1, H, W, I*M ]
1513  auto weightsShape = weightsInfo.GetShape();
1514  weightsInfo.SetShape({1,
1515  weightsShape[0],
1516  weightsShape[1],
1517  weightsShape[2]*weightsShape[3]});
1518  weightsInfo.SetConstant(true);
1519 
1520  armnn::ConstTensor weightsPermuted(weightsInfo, permuteBuffer.get());
1521 
1522  layer = m_Network->AddConstantLayer(weightsPermuted, layerName.c_str());
1523 
1524  layer->GetOutputSlot(0).SetTensorInfo(weightsPermuted.GetInfo());
1525 
1526  RegisterOutputSlots(graph, layerIndex, layer);
1527 
1528  return;
1529  }
1530  else
1531  {
1532  layer = m_Network->AddConstantLayer(input, layerName.c_str());
1533 
1534  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1535  outputTensorInfo.SetConstant(true);
1536  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1537  }
1538 
1539  RegisterOutputSlots(graph, layerIndex, layer);
1540 }
1541 
1542 void IDeserializer::DeserializerImpl::ParseConvolution2d(GraphPtr graph, unsigned int layerIndex)
1543 {
1544  CHECK_LAYERS(graph, 0, layerIndex);
1545  auto inputs = GetInputs(graph, layerIndex);
1546  CHECK_LOCATION();
1547 
1548  auto outputs = GetOutputs(graph, layerIndex);
1549  CHECK_VALID_SIZE(outputs.size(), 1);
1550 
1551  auto flatBufferLayer = graph->layers()->Get(layerIndex)->layer_as_Convolution2dLayer();
1552 
1553  auto layerName = GetLayerName(graph, layerIndex);
1554  auto flatbufferDescriptor = flatBufferLayer->descriptor();
1555 
1556  armnn::Convolution2dDescriptor descriptor;
1557  descriptor.m_PadLeft = flatbufferDescriptor->padLeft();
1558  descriptor.m_PadRight = flatbufferDescriptor->padRight();
1559  descriptor.m_PadTop = flatbufferDescriptor->padTop();
1560  descriptor.m_PadBottom = flatbufferDescriptor->padBottom();
1561  descriptor.m_StrideX = flatbufferDescriptor->strideX();
1562  descriptor.m_StrideY = flatbufferDescriptor->strideY();;
1563  descriptor.m_DilationX = flatbufferDescriptor->dilationX();
1564  descriptor.m_DilationY = flatbufferDescriptor->dilationY();;
1565  descriptor.m_BiasEnabled = flatbufferDescriptor->biasEnabled();;
1566  descriptor.m_DataLayout = ToDataLayout(flatbufferDescriptor->dataLayout());
1567 
1568  armnn::IConnectableLayer* layer;
1569  std::vector<unsigned int> ignoreSlots {};
1570 
1571  armnn::ConstTensor biasTensor;
1572  // Weights and biases used to be always constant and were stored as members of the layer. This has changed and
1573  // they are now passed as inputs. If they are constant then they will be stored in a ConstantLayer.
1574  if (this->GetFeatureVersions(graph).m_ConstTensorsAsInputs <= 0)
1575  {
1576  // If the model stores weights and biases as members of the layer we have to read them from there
1577  // but add them to their own ConstantLayer for compatibility
1578  CHECK_VALID_SIZE(inputs.size(), 1);
1579 
1580  layer = m_Network->AddConvolution2dLayer(descriptor,
1581  layerName.c_str());
1582 
1583  armnn::ConstTensor weightsTensor = ToConstTensor(flatBufferLayer->weights());
1584  auto weightsLayer = m_Network->AddConstantLayer(weightsTensor);
1585  weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u));
1586  weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsTensor.GetInfo());
1587  ignoreSlots.emplace_back(1u);
1588 
1589  if (descriptor.m_BiasEnabled)
1590  {
1591  biasTensor = ToConstTensor(flatBufferLayer->biases());
1592  auto biasLayer = m_Network->AddConstantLayer(biasTensor);
1593  biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2u));
1594  biasLayer->GetOutputSlot(0).SetTensorInfo(biasTensor.GetInfo());
1595  ignoreSlots.emplace_back(2u);
1596  }
1597  }
1598  else
1599  {
1600  layer = m_Network->AddConvolution2dLayer(descriptor,
1601  layerName.c_str());
1602  uint32_t numInputs = descriptor.GetNumInputs();
1603  CHECK_VALID_SIZE(inputs.size(), numInputs);
1604  }
1605 
1606  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1607  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1608 
1609  RegisterInputSlots(graph, layerIndex, layer, ignoreSlots);
1610  RegisterOutputSlots(graph, layerIndex, layer);
1611 }
1612 
1613 void IDeserializer::DeserializerImpl::ParseConvolution3d(GraphPtr graph, unsigned int layerIndex)
1614 {
1615  CHECK_LAYERS(graph, 0, layerIndex);
1616  auto inputs = GetInputs(graph, layerIndex);
1617  CHECK_LOCATION();
1618 
1619  auto outputs = GetOutputs(graph, layerIndex);
1620  CHECK_VALID_SIZE(outputs.size(), 1);
1621 
1622  auto serializerLayer = graph->layers()->Get(layerIndex)->layer_as_Convolution3dLayer();
1623  auto layerName = GetLayerName(graph, layerIndex);
1624  auto serializerDescriptor = serializerLayer->descriptor();
1625 
1626  armnn::Convolution3dDescriptor descriptor;
1627  descriptor.m_PadLeft = serializerDescriptor->padLeft();
1628  descriptor.m_PadRight = serializerDescriptor->padRight();
1629  descriptor.m_PadTop = serializerDescriptor->padTop();
1630  descriptor.m_PadBottom = serializerDescriptor->padBottom();
1631  descriptor.m_PadFront = serializerDescriptor->padFront();
1632  descriptor.m_PadBack = serializerDescriptor->padBack();
1633  descriptor.m_StrideX = serializerDescriptor->strideX();
1634  descriptor.m_StrideY = serializerDescriptor->strideY();
1635  descriptor.m_StrideZ = serializerDescriptor->strideZ();
1636  descriptor.m_DilationX = serializerDescriptor->dilationX();
1637  descriptor.m_DilationY = serializerDescriptor->dilationY();
1638  descriptor.m_DilationZ = serializerDescriptor->dilationZ();
1639  descriptor.m_BiasEnabled = serializerDescriptor->biasEnabled();
1640  descriptor.m_DataLayout = ToDataLayout(serializerDescriptor->dataLayout());
1641 
1642  uint32_t numInputs = descriptor.GetNumInputs();
1643  CHECK_VALID_SIZE(inputs.size(), numInputs);
1644 
1645  IConnectableLayer* layer = m_Network->AddConvolution3dLayer(descriptor, layerName.c_str());
1646 
1647  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1648  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1649 
1650  RegisterInputSlots(graph, layerIndex, layer);
1651  RegisterOutputSlots(graph, layerIndex, layer);
1652 }
1653 
1654 void IDeserializer::DeserializerImpl::ParseDepthToSpace(GraphPtr graph, unsigned int layerIndex)
1655 {
1656  CHECK_LAYERS(graph, 0, layerIndex);
1657 
1658  auto inputs = GetInputs(graph, layerIndex);
1659  CHECK_VALID_SIZE(inputs.size(), 1);
1660 
1661  auto outputs = GetOutputs(graph, layerIndex);
1662  CHECK_VALID_SIZE(outputs.size(), 1);
1663 
1664  auto fbDescriptor = graph->layers()->Get(layerIndex)->layer_as_DepthToSpaceLayer()->descriptor();
1665 
1666  armnn::DepthToSpaceDescriptor descriptor;
1667  descriptor.m_BlockSize = fbDescriptor->blockSize();
1668  descriptor.m_DataLayout = ToDataLayout(fbDescriptor->dataLayout());
1669 
1670  auto layerName = GetLayerName(graph, layerIndex);
1671  IConnectableLayer* layer = m_Network->AddDepthToSpaceLayer(descriptor, layerName.c_str());
1672 
1673  armnn::TensorInfo outputInfo = ToTensorInfo(outputs[0]);
1674  layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1675 
1676  RegisterInputSlots(graph, layerIndex, layer);
1677  RegisterOutputSlots(graph, layerIndex, layer);
1678 }
1679 
1680 void IDeserializer::DeserializerImpl::ParseDepthwiseConvolution2d(GraphPtr graph, unsigned int layerIndex)
1681 {
1682  CHECK_LAYERS(graph, 0, layerIndex);
1683  auto inputs = GetInputs(graph, layerIndex);
1684  CHECK_LOCATION();
1685 
1686  auto outputs = GetOutputs(graph, layerIndex);
1687  CHECK_VALID_SIZE(outputs.size(), 1);
1688 
1689  auto serializerLayer = graph->layers()->Get(layerIndex)->layer_as_DepthwiseConvolution2dLayer();
1690  auto layerName = GetLayerName(graph, layerIndex);
1691  auto serializerDescriptor = serializerLayer->descriptor();
1692 
1694  descriptor.m_PadLeft = serializerDescriptor->padLeft();
1695  descriptor.m_PadRight = serializerDescriptor->padRight();
1696  descriptor.m_PadTop = serializerDescriptor->padTop();
1697  descriptor.m_PadBottom = serializerDescriptor->padBottom();
1698  descriptor.m_StrideX = serializerDescriptor->strideX();
1699  descriptor.m_StrideY = serializerDescriptor->strideY();
1700  descriptor.m_DilationX = serializerDescriptor->dilationX();
1701  descriptor.m_DilationY = serializerDescriptor->dilationY();
1702  descriptor.m_BiasEnabled = serializerDescriptor->biasEnabled();
1703  descriptor.m_DataLayout = ToDataLayout(serializerDescriptor->dataLayout());
1704 
1705  IConnectableLayer* layer;
1706  std::vector<unsigned int> ignoreSlots {};
1707 
1708  // Weights and biases used to be always constant and were stored as members of the layer. This has changed and
1709  // they are now passed as inputs. If they are constant then they will be stored in a ConstantLayer.
1710  if (this->GetFeatureVersions(graph).m_ConstTensorsAsInputs <= 0)
1711  {
1712  CHECK_VALID_SIZE(inputs.size(), 1);
1713 
1714  // If the model stores weights and biases as members of the layer we have to read them from there
1715  // but add them to their own ConstantLayer for compatibility
1716  armnn::ConstTensor weights = ToConstTensor(serializerLayer->weights());
1717  ignoreSlots.emplace_back(1u);
1718 
1719  layer = m_Network->AddDepthwiseConvolution2dLayer(descriptor,
1720  layerName.c_str());
1721 
1723  if (descriptor.m_BiasEnabled)
1724  {
1725  armnn::ConstTensor biases = ToConstTensor(serializerLayer->biases());
1726  ignoreSlots.emplace_back(2u);
1727 
1728  auto biasLayer = m_Network->AddConstantLayer(biases);
1729  biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2u));
1730  biasLayer->GetOutputSlot(0).SetTensorInfo(biases.GetInfo());
1731  }
1732 
1733  if (this->GetFeatureVersions(graph).m_WeightsLayoutScheme <= 0)
1734  {
1735  // Permute weights [ H, W, M, I ] --> [ 1, H, W, I*M ]
1736  // Step1: [ M, I, H, W ] --> [ H, W, I, M]
1737  PermutationVector permutationVector = { 3, 2, 0, 1 };
1738  armnn::TensorInfo weightsInfo = weights.GetInfo();
1739  std::unique_ptr<unsigned char[]> permuteBuffer(new unsigned char[weightsInfo.GetNumBytes()]);
1740  weightsInfo = armnnUtils::Permuted(weightsInfo, permutationVector);
1741  armnnUtils::Permute(weightsInfo.GetShape(), permutationVector,
1742  weights.GetMemoryArea(), permuteBuffer.get(),
1743  GetDataTypeSize(weightsInfo.GetDataType()));
1744 
1745  // Step2: Reshape [ H, W, I, M] --> [ 1, H, W, I*M ]
1746  auto weightsShape = weightsInfo.GetShape();
1747  weightsInfo.SetShape({1,
1748  weightsShape[0],
1749  weightsShape[1],
1750  weightsShape[2]*weightsShape[3]});
1751 
1752  armnn::ConstTensor weightsPermuted(weightsInfo, permuteBuffer.get());
1753 
1754  auto weightsLayer = m_Network->AddConstantLayer(weightsPermuted);
1755  weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u));
1756  weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsPermuted.GetInfo());
1757  }
1758  else
1759  {
1760  auto weightsLayer = m_Network->AddConstantLayer(weights);
1761  weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u));
1762  weightsLayer->GetOutputSlot(0).SetTensorInfo(weights.GetInfo());
1763  }
1764  }
1765  else
1766  {
1767  layer = m_Network->AddDepthwiseConvolution2dLayer(descriptor,
1768  layerName.c_str());
1769  uint32_t numInputs = descriptor.GetNumInputs();
1770  CHECK_VALID_SIZE(inputs.size(), numInputs);
1771  }
1772 
1773  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1774  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1775 
1776  RegisterInputSlots(graph, layerIndex, layer, ignoreSlots);
1777  RegisterOutputSlots(graph, layerIndex, layer);
1778 }
1779 
1780 void IDeserializer::DeserializerImpl::ParseDetectionPostProcess(GraphPtr graph, unsigned int layerIndex)
1781 {
1782  CHECK_LAYERS(graph, 0, layerIndex);
1783  auto inputs = GetInputs(graph, layerIndex);
1784  CHECK_LOCATION();
1785  CHECK_VALID_SIZE(inputs.size(), 2);
1786 
1787  auto outputs = GetOutputs(graph, layerIndex);
1788  CHECK_VALID_SIZE(outputs.size(), 4);
1789 
1790  auto flatBufferLayer = graph->layers()->Get(layerIndex)->layer_as_DetectionPostProcessLayer();
1791  auto layerName = GetLayerName(graph, layerIndex);
1792  auto flatBufferDescriptor = flatBufferLayer->descriptor();
1793 
1795  descriptor.m_MaxDetections = flatBufferDescriptor->maxDetections();
1796  descriptor.m_MaxClassesPerDetection = flatBufferDescriptor->maxClassesPerDetection();
1797  descriptor.m_DetectionsPerClass = flatBufferDescriptor->detectionsPerClass();
1798  descriptor.m_NmsScoreThreshold = flatBufferDescriptor->nmsScoreThreshold();
1799  descriptor.m_NmsIouThreshold = flatBufferDescriptor->nmsIouThreshold();
1800  descriptor.m_NumClasses = flatBufferDescriptor->numClasses();
1801  descriptor.m_UseRegularNms = flatBufferDescriptor->useRegularNms();
1802  descriptor.m_ScaleX = flatBufferDescriptor->scaleX();
1803  descriptor.m_ScaleY = flatBufferDescriptor->scaleY();
1804  descriptor.m_ScaleW = flatBufferDescriptor->scaleW();
1805  descriptor.m_ScaleH = flatBufferDescriptor->scaleH();
1806 
1807  armnn::ConstTensor anchors = ToConstTensor(flatBufferLayer->anchors());
1808 
1809  IConnectableLayer* layer = m_Network->AddDetectionPostProcessLayer(descriptor,
1810  anchors,
1811  layerName.c_str());
1812 
1813  for (unsigned int i = 0; i < 4; i++)
1814  {
1815  layer->GetOutputSlot(i).SetTensorInfo(ToTensorInfo(outputs[i]));
1816  }
1817 
1818  RegisterInputSlots(graph, layerIndex, layer);
1819  RegisterOutputSlots(graph, layerIndex, layer);
1820 }
1821 
1822 void IDeserializer::DeserializerImpl::ParseDivision(GraphPtr graph, unsigned int layerIndex)
1823 {
1824  CHECK_LAYERS(graph, 0, layerIndex);
1825  auto inputs = GetInputs(graph, layerIndex);
1826  CHECK_LOCATION();
1827  CHECK_VALID_SIZE(inputs.size(), 2);
1828 
1829  auto outputs = GetOutputs(graph, layerIndex);
1830  CHECK_VALID_SIZE(outputs.size(), 1);
1831 
1832  auto layerName = GetLayerName(graph, layerIndex);
1834  IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(descriptor, layerName.c_str());
1835 
1836  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1837  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1838 
1839  RegisterInputSlots(graph, layerIndex, layer);
1840  RegisterOutputSlots(graph, layerIndex, layer);
1841 }
1842 
1843 void IDeserializer::DeserializerImpl::ParseEqual(GraphPtr graph, unsigned int layerIndex)
1844 {
1845  CHECK_LAYERS(graph, 0, layerIndex);
1846  auto inputs = GetInputs(graph, layerIndex);
1847  CHECK_LOCATION();
1848  CHECK_VALID_SIZE(inputs.size(), 2);
1849 
1850  auto outputs = GetOutputs(graph, layerIndex);
1851  CHECK_VALID_SIZE(outputs.size(), 1);
1852 
1853  auto layerName = GetLayerName(graph, layerIndex);
1855  IConnectableLayer* layer = m_Network->AddComparisonLayer(descriptor, layerName.c_str());
1856 
1857  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1858  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1859 
1860  RegisterInputSlots(graph, layerIndex, layer);
1861  RegisterOutputSlots(graph, layerIndex, layer);
1862 }
1863 
1864 void IDeserializer::DeserializerImpl::ParseFill(GraphPtr graph, unsigned int layerIndex)
1865 {
1866  CHECK_LAYERS(graph, 0, layerIndex);
1867  auto inputs = GetInputs(graph, layerIndex);
1868  CHECK_LOCATION();
1869  CHECK_VALID_SIZE(inputs.size(), 1);
1870 
1871  auto outputs = GetOutputs(graph, layerIndex);
1872  CHECK_VALID_SIZE(outputs.size(), 1);
1873 
1874  auto layerName = GetLayerName(graph, layerIndex);
1875  armnn::FillDescriptor descriptor;
1876  descriptor.m_Value = graph->layers()->Get(layerIndex)->layer_as_FillLayer()->descriptor()->value();
1877  IConnectableLayer* layer = m_Network->AddFillLayer(descriptor, layerName.c_str());
1878 
1879  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1880  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1881 
1882  RegisterInputSlots(graph, layerIndex, layer);
1883  RegisterOutputSlots(graph, layerIndex, layer);
1884 }
1885 
1886 void IDeserializer::DeserializerImpl::ParseGreater(GraphPtr graph, unsigned int layerIndex)
1887 {
1888  CHECK_LAYERS(graph, 0, layerIndex);
1889  auto inputs = GetInputs(graph, layerIndex);
1890  CHECK_LOCATION();
1891  CHECK_VALID_SIZE(inputs.size(), 2);
1892 
1893  auto outputs = GetOutputs(graph, layerIndex);
1894  CHECK_VALID_SIZE(outputs.size(), 1);
1895 
1896  auto layerName = GetLayerName(graph, layerIndex);
1898  IConnectableLayer* layer = m_Network->AddComparisonLayer(descriptor, layerName.c_str());
1899 
1900  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1901  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1902 
1903  RegisterInputSlots(graph, layerIndex, layer);
1904  RegisterOutputSlots(graph, layerIndex, layer);
1905 }
1906 
1907 void IDeserializer::DeserializerImpl::ParseInstanceNormalization(GraphPtr graph, unsigned int layerIndex)
1908 {
1909  CHECK_LAYERS(graph, 0, layerIndex);
1910 
1911  auto inputs = GetInputs(graph, layerIndex);
1912  CHECK_VALID_SIZE(inputs.size(), 1);
1913 
1914  auto outputs = GetOutputs(graph, layerIndex);
1915  CHECK_VALID_SIZE(outputs.size(), 1);
1916 
1917  auto fbLayer = graph->layers()->Get(layerIndex)->layer_as_InstanceNormalizationLayer();
1918  auto fbDescriptor = fbLayer->descriptor();
1919 
1921  descriptor.m_Gamma = fbDescriptor->gamma();
1922  descriptor.m_Beta = fbDescriptor->beta();
1923  descriptor.m_Eps = fbDescriptor->eps();
1924  descriptor.m_DataLayout = ToDataLayout(fbDescriptor->dataLayout());
1925 
1926  const std::string layerName = GetLayerName(graph, layerIndex);
1927  const armnn::TensorInfo outputInfo = ToTensorInfo(outputs[0]);
1928 
1929  IConnectableLayer* layer = m_Network->AddInstanceNormalizationLayer(descriptor, layerName.c_str());
1930  layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1931 
1932  RegisterInputSlots(graph, layerIndex, layer);
1933  RegisterOutputSlots(graph, layerIndex, layer);
1934 }
1935 
1936 void IDeserializer::DeserializerImpl::ParseL2Normalization(GraphPtr graph, unsigned int layerIndex)
1937 {
1938  CHECK_LAYERS(graph, 0, layerIndex);
1939 
1940  auto inputs = GetInputs(graph, layerIndex);
1941  CHECK_VALID_SIZE(inputs.size(), 1);
1942 
1943  auto outputs = GetOutputs(graph, layerIndex);
1944  CHECK_VALID_SIZE(outputs.size(), 1);
1945  auto outputInfo = ToTensorInfo(outputs[0]);
1946 
1947  auto flatBufferLayer = graph->layers()->Get(layerIndex)->layer_as_L2NormalizationLayer();
1948  auto flatBufferDescriptor = flatBufferLayer->descriptor();
1949 
1950  auto layerName = GetLayerName(graph, layerIndex);
1952  descriptor.m_DataLayout = ToDataLayout(flatBufferDescriptor->dataLayout());
1953  descriptor.m_Eps = flatBufferDescriptor->eps();
1954 
1955  IConnectableLayer* layer = m_Network->AddL2NormalizationLayer(descriptor, layerName.c_str());
1956  layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1957 
1958  RegisterInputSlots(graph, layerIndex, layer);
1959  RegisterOutputSlots(graph, layerIndex, layer);
1960 }
1961 
1962 void IDeserializer::DeserializerImpl::ParseLogicalBinary(GraphPtr graph, unsigned int layerIndex)
1963 {
1964  CHECK_LAYERS(graph, 0, layerIndex);
1965  CHECK_LOCATION();
1966 
1967  auto inputs = GetInputs(graph, layerIndex);
1968  CHECK_VALID_SIZE(inputs.size(), 2);
1969 
1970  auto outputs = GetOutputs(graph, layerIndex);
1971  CHECK_VALID_SIZE(outputs.size(), 1);
1972 
1973  auto fbLayer = graph->layers()->Get(layerIndex)->layer_as_LogicalBinaryLayer();
1974  auto fbDescriptor = fbLayer->descriptor();
1975 
1976  armnn::LogicalBinaryDescriptor descriptor;
1977  descriptor.m_Operation = ToLogicalBinaryOperation(fbDescriptor->operation());
1978 
1979  const std::string& layerName = GetLayerName(graph, layerIndex);
1980  IConnectableLayer* layer = m_Network->AddLogicalBinaryLayer(descriptor, layerName.c_str());
1981 
1982  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
1983  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1984 
1985  RegisterInputSlots(graph, layerIndex, layer);
1986  RegisterOutputSlots(graph, layerIndex, layer);
1987 }
1988 
1989 void IDeserializer::DeserializerImpl::ParseLogSoftmax(GraphPtr graph, unsigned int layerIndex)
1990 {
1991  CHECK_LAYERS(graph, 0, layerIndex);
1992 
1993  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
1994  CHECK_VALID_SIZE(inputs.size(), 1);
1995 
1996  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
1997  CHECK_VALID_SIZE(outputs.size(), 1);
1998 
1999  armnn::LogSoftmaxDescriptor descriptor;
2000  descriptor.m_Beta = graph->layers()->Get(layerIndex)->layer_as_LogSoftmaxLayer()->descriptor()->beta();
2001  descriptor.m_Axis = graph->layers()->Get(layerIndex)->layer_as_LogSoftmaxLayer()->descriptor()->axis();
2002  auto layerName = GetLayerName(graph, layerIndex);
2003 
2004  IConnectableLayer* layer = m_Network->AddLogSoftmaxLayer(descriptor, layerName.c_str());
2005 
2006  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2007  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2008 
2009  RegisterInputSlots(graph, layerIndex, layer);
2010  RegisterOutputSlots(graph, layerIndex, layer);
2011 }
2012 
2013 void IDeserializer::DeserializerImpl::ParseMinimum(GraphPtr graph, unsigned int layerIndex)
2014 {
2015  CHECK_LAYERS(graph, 0, layerIndex);
2016  auto inputs = GetInputs(graph, layerIndex);
2017  CHECK_LOCATION();
2018  CHECK_VALID_SIZE(inputs.size(), 2);
2019 
2020  auto outputs = GetOutputs(graph, layerIndex);
2021  CHECK_VALID_SIZE(outputs.size(), 1);
2022 
2023  auto layerName = GetLayerName(graph, layerIndex);
2025  IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(descriptor, layerName.c_str());
2026 
2027  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2028  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2029 
2030  RegisterInputSlots(graph, layerIndex, layer);
2031  RegisterOutputSlots(graph, layerIndex, layer);
2032 }
2033 
2034 void IDeserializer::DeserializerImpl::ParseMaximum(GraphPtr graph, unsigned int layerIndex)
2035 {
2036  CHECK_LAYERS(graph, 0, layerIndex);
2037  auto inputs = GetInputs(graph, layerIndex);
2038  CHECK_LOCATION();
2039  CHECK_VALID_SIZE(inputs.size(), 2);
2040 
2041  auto outputs = GetOutputs(graph, layerIndex);
2042  CHECK_VALID_SIZE(outputs.size(), 1);
2043 
2044  auto layerName = GetLayerName(graph, layerIndex);
2046  IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(descriptor, layerName.c_str());
2047 
2048  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2049  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2050 
2051  RegisterInputSlots(graph, layerIndex, layer);
2052  RegisterOutputSlots(graph, layerIndex, layer);
2053 }
2054 
2055 const armnnSerializer::OriginsDescriptor* GetOriginsDescriptor(const armnnSerializer::SerializedGraph* graph,
2056  unsigned int layerIndex)
2057 {
2058  auto layerType = graph->layers()->Get(layerIndex)->layer_type();
2059 
2060  switch (layerType)
2061  {
2062  case Layer::Layer_ConcatLayer:
2063  return graph->layers()->Get(layerIndex)->layer_as_ConcatLayer()->descriptor();
2064  case Layer::Layer_MergerLayer:
2065  return graph->layers()->Get(layerIndex)->layer_as_MergerLayer()->descriptor();
2066  default:
2067  throw armnn::Exception("unknown layer type, should be concat or merger");
2068  }
2069 }
2070 void IDeserializer::DeserializerImpl::ParseChannelShuffle(GraphPtr graph, unsigned int layerIndex)
2071 {
2072  CHECK_LAYERS(graph, 0, layerIndex);
2073 
2074  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
2075  CHECK_VALID_SIZE(inputs.size(), 1);
2076 
2077  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
2078  CHECK_VALID_SIZE(outputs.size(), 1);
2079 
2081  descriptor.m_Axis = graph->layers()->Get(layerIndex)->layer_as_ChannelShuffleLayer()->descriptor()->axis();
2082  descriptor.m_NumGroups =
2083  graph->layers()->Get(layerIndex)->layer_as_ChannelShuffleLayer()->descriptor()->numGroups();
2084 
2085  auto layerName = GetLayerName(graph, layerIndex);
2086  IConnectableLayer* layer = m_Network->AddChannelShuffleLayer(descriptor, layerName.c_str());
2087 
2088  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2089  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2090 
2091  RegisterInputSlots(graph, layerIndex, layer);
2092  RegisterOutputSlots(graph, layerIndex, layer);
2093 }
2094 void IDeserializer::DeserializerImpl::ParseComparison(GraphPtr graph, unsigned int layerIndex)
2095 {
2096  CHECK_LAYERS(graph, 0, layerIndex);
2097  CHECK_LOCATION();
2098 
2099  auto inputs = GetInputs(graph, layerIndex);
2100  CHECK_VALID_SIZE(inputs.size(), 2);
2101 
2102  auto outputs = GetOutputs(graph, layerIndex);
2103  CHECK_VALID_SIZE(outputs.size(), 1);
2104 
2105  auto fbLayer = graph->layers()->Get(layerIndex)->layer_as_ComparisonLayer();
2106  auto fbDescriptor = fbLayer->descriptor();
2107 
2108  armnn::ComparisonDescriptor descriptor;
2109  descriptor.m_Operation = ToComparisonOperation(fbDescriptor->operation());
2110 
2111  const std::string& layerName = GetLayerName(graph, layerIndex);
2112  IConnectableLayer* layer = m_Network->AddComparisonLayer(descriptor, layerName.c_str());
2113 
2114  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2115  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2116 
2117  RegisterInputSlots(graph, layerIndex, layer);
2118  RegisterOutputSlots(graph, layerIndex, layer);
2119 }
2120 
2121 void IDeserializer::DeserializerImpl::ParseElementwiseBinary(GraphPtr graph, unsigned int layerIndex)
2122 {
2123  CHECK_LAYERS(graph, 0, layerIndex);
2124  CHECK_LOCATION();
2125 
2126  auto inputs = GetInputs(graph, layerIndex);
2127  CHECK_VALID_SIZE(inputs.size(), 2);
2128 
2129  auto outputs = GetOutputs(graph, layerIndex);
2130  CHECK_VALID_SIZE(outputs.size(), 1);
2131 
2132  auto fbLayer = graph->layers()->Get(layerIndex)->layer_as_ElementwiseBinaryLayer();
2133  auto fbDescriptor = fbLayer->descriptor();
2134 
2136  descriptor.m_Operation = ToElementwiseBinaryOperation(fbDescriptor->operation());
2137 
2138  const std::string& layerName = GetLayerName(graph, layerIndex);
2139  IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(descriptor, layerName.c_str());
2140 
2141  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2142  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2143 
2144  RegisterInputSlots(graph, layerIndex, layer);
2145  RegisterOutputSlots(graph, layerIndex, layer);
2146 }
2147 
2148 void IDeserializer::DeserializerImpl::ParseElementwiseUnary(GraphPtr graph, unsigned int layerIndex)
2149 {
2150  CHECK_LAYERS(graph, 0, layerIndex);
2151  CHECK_LOCATION();
2152 
2153  auto inputs = GetInputs(graph, layerIndex);
2154  CHECK_VALID_SIZE(inputs.size(), 1);
2155 
2156  auto outputs = GetOutputs(graph, layerIndex);
2157  CHECK_VALID_SIZE(outputs.size(), 1);
2158 
2159  auto fbLayer = graph->layers()->Get(layerIndex)->layer_as_ElementwiseUnaryLayer();
2160  auto fbDescriptor = fbLayer->descriptor();
2161 
2163  descriptor.m_Operation = ToElementwiseUnaryOperation(fbDescriptor->operation());
2164 
2165  const std::string& layerName = GetLayerName(graph, layerIndex);
2166  IConnectableLayer* layer = m_Network->AddElementwiseUnaryLayer(descriptor, layerName.c_str());
2167 
2168  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2169  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2170 
2171  RegisterInputSlots(graph, layerIndex, layer);
2172  RegisterOutputSlots(graph, layerIndex, layer);
2173 }
2174 
2175 void IDeserializer::DeserializerImpl::ParseConcat(GraphPtr graph, unsigned int layerIndex)
2176 {
2177  CHECK_LAYERS(graph, 0, layerIndex);
2178  CHECK_LOCATION();
2179 
2180  auto outputs = GetOutputs(graph, layerIndex);
2181  CHECK_VALID_SIZE(outputs.size(), 1);
2182 
2183  auto layerName = GetLayerName(graph, layerIndex);
2184  auto originsDescriptor = GetOriginsDescriptor(graph, layerIndex);
2185  unsigned int numViews = originsDescriptor->numViews();
2186  unsigned int numDimensions = originsDescriptor->numDimensions();
2187 
2188  // can now check the number of inputs == number of views
2189  auto inputs = GetInputs(graph, layerIndex);
2190  CHECK_VALID_SIZE(inputs.size(), numViews);
2191 
2192  armnn::OriginsDescriptor descriptor(numViews, numDimensions);
2193  auto originsPtr = originsDescriptor->viewOrigins();
2194  for (unsigned int v = 0; v < numViews; ++v)
2195  {
2196  auto originPtr = originsPtr->Get(v);
2197  for (unsigned int d = 0; d < numDimensions; ++d)
2198  {
2199  uint32_t value = originPtr->data()->Get(d);
2200  descriptor.SetViewOriginCoord(v, d, value);
2201  }
2202  }
2203  descriptor.SetConcatAxis(originsDescriptor->concatAxis());
2204 
2205  IConnectableLayer* layer = m_Network->AddConcatLayer(descriptor, layerName.c_str());
2206  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2207  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2208 
2209  RegisterInputSlots(graph, layerIndex, layer);
2210  RegisterOutputSlots(graph, layerIndex, layer);
2211 }
2212 
2213 void IDeserializer::DeserializerImpl::ParseMultiplication(GraphPtr graph, unsigned int layerIndex)
2214 {
2215  CHECK_LAYERS(graph, 0, layerIndex);
2216  auto inputs = GetInputs(graph, layerIndex);
2217  CHECK_LOCATION();
2218  CHECK_VALID_SIZE(inputs.size(), 2);
2219 
2220  auto outputs = GetOutputs(graph, layerIndex);
2221  CHECK_VALID_SIZE(outputs.size(), 1);
2222 
2223  auto layerName = GetLayerName(graph, layerIndex);
2225  IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(descriptor, layerName.c_str());
2226 
2227  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2228  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2229 
2230  RegisterInputSlots(graph, layerIndex, layer);
2231  RegisterOutputSlots(graph, layerIndex, layer);
2232 }
2233 
2234 void IDeserializer::DeserializerImpl::ParseFloor(GraphPtr graph, unsigned int layerIndex)
2235 {
2236  CHECK_LAYERS(graph, 0, layerIndex);
2237  CHECK_LOCATION();
2238 
2239  auto inputs = GetInputs(graph, layerIndex);
2240  CHECK_VALID_SIZE(inputs.size(), 1);
2241 
2242  auto outputs = GetOutputs(graph, layerIndex);
2243  CHECK_VALID_SIZE(outputs.size(), 1);
2244 
2245  auto layerName = GetLayerName(graph, layerIndex);
2246 
2247  armnn::IConnectableLayer* layer;
2248 
2249  layer = m_Network->AddFloorLayer(layerName.c_str());
2250 
2251  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2252  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2253 
2254  RegisterInputSlots(graph, layerIndex, layer);
2255  RegisterOutputSlots(graph, layerIndex, layer);
2256 }
2257 
2258 void IDeserializer::DeserializerImpl::ParseFullyConnected(GraphPtr graph, unsigned int layerIndex)
2259 {
2260  CHECK_LAYERS(graph, 0, layerIndex);
2261  auto inputs = GetInputs(graph, layerIndex);
2262  CHECK_LOCATION();
2263 
2264  auto outputs = GetOutputs(graph, layerIndex);
2265  CHECK_VALID_SIZE(outputs.size(), 1);
2266 
2267  auto flatBufferLayer = graph->layers()->Get(layerIndex)->layer_as_FullyConnectedLayer();
2268  auto layerName = GetLayerName(graph, layerIndex);
2269  auto flatBufferDescriptor = flatBufferLayer->descriptor();
2270 
2271  armnn::FullyConnectedDescriptor fullyConnectedDescriptor;
2272  fullyConnectedDescriptor.m_BiasEnabled = flatBufferDescriptor->biasEnabled();
2273  fullyConnectedDescriptor.m_TransposeWeightMatrix = flatBufferDescriptor->transposeWeightsMatrix();
2274  fullyConnectedDescriptor.m_ConstantWeights = flatBufferDescriptor->constantWeights();
2275 
2276  armnn::IConnectableLayer* layer;
2277  std::vector<unsigned int> ignoreSlots {};
2278 
2279  // Weights and biases used to be always constant and were stored as members of the layer. This has changed and
2280  // they are now passed as inputs. If they are constant then they will be stored in a ConstantLayer.
2281  if (this->GetFeatureVersions(graph).m_ConstTensorsAsInputs <= 0)
2282  {
2283  // If the model stores weights and biases as members of the layer we have to read them from there
2284  // but add them to their own ConstantLayer for compatibility
2285  CHECK_VALID_SIZE(inputs.size(), 1);
2286  layer = m_Network->AddFullyConnectedLayer(fullyConnectedDescriptor,
2287  layerName.c_str());
2288 
2289  armnn::ConstTensor weightsTensor = ToConstTensor(flatBufferLayer->weights());
2290  auto weightsLayer = m_Network->AddConstantLayer(weightsTensor);
2291  weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u));
2292  weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsTensor.GetInfo());
2293  ignoreSlots.emplace_back(1u);
2294 
2295  if (fullyConnectedDescriptor.m_BiasEnabled)
2296  {
2297  armnn::ConstTensor biasTensor = ToConstTensor(flatBufferLayer->biases());
2298  auto biasLayer = m_Network->AddConstantLayer(biasTensor);
2299  biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2u));
2300  biasLayer->GetOutputSlot(0).SetTensorInfo(biasTensor.GetInfo());
2301  ignoreSlots.emplace_back(2u);
2302  }
2303  }
2304  else
2305  {
2306  layer = m_Network->AddFullyConnectedLayer(fullyConnectedDescriptor,
2307  layerName.c_str());
2308  uint32_t numInputs = fullyConnectedDescriptor.GetNumInputs();
2309  CHECK_VALID_SIZE(inputs.size(), numInputs);
2310  }
2311 
2312  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2313  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2314 
2315  RegisterInputSlots(graph, layerIndex, layer, ignoreSlots);
2316  RegisterOutputSlots(graph, layerIndex, layer);
2317 }
2318 
2319 void IDeserializer::DeserializerImpl::ParsePad(GraphPtr graph, unsigned int layerIndex)
2320 {
2321  CHECK_LAYERS(graph, 0, layerIndex);
2322 
2323  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
2324  CHECK_VALID_SIZE(inputs.size(), 1);
2325 
2326  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
2327  CHECK_VALID_SIZE(outputs.size(), 1);
2328 
2329  auto flatBufferDescriptor = graph->layers()->Get(layerIndex)->layer_as_PadLayer()->descriptor();
2330  auto flatBufferPadList = flatBufferDescriptor->padList();
2331  auto paddingMode = flatBufferDescriptor->paddingMode();
2332  float padValue = flatBufferDescriptor->padValue();
2333 
2334  if (flatBufferPadList->size() % 2 != 0)
2335  {
2336  throw ParseException(fmt::format("The size of the pad list must be divisible by 2 {}",
2337  CHECK_LOCATION().AsString()));
2338  }
2339 
2340  std::vector<std::pair<unsigned int, unsigned int>> padList;
2341  padList.reserve(flatBufferPadList->size() / 2);
2342  for (unsigned int i = 0; i < flatBufferPadList->size() - 1; i += 2)
2343  {
2344  padList.emplace_back(flatBufferPadList->Get(i), flatBufferPadList->Get(i+1));
2345  }
2346 
2347  armnn::PadDescriptor descriptor(padList, padValue, ToPaddingMode(paddingMode));
2348 
2349  auto layerName = GetLayerName(graph, layerIndex);
2350  IConnectableLayer* layer = m_Network->AddPadLayer(descriptor, layerName.c_str());
2351 
2352  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2353  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2354 
2355  RegisterInputSlots(graph, layerIndex, layer);
2356  RegisterOutputSlots(graph, layerIndex, layer);
2357 }
2358 
2359 void IDeserializer::DeserializerImpl::ParsePermute(GraphPtr graph, unsigned int layerIndex)
2360 {
2361  CHECK_LAYERS(graph, 0, layerIndex);
2362 
2363  auto dimsMapping =
2364  graph->layers()->Get(layerIndex)->layer_as_PermuteLayer()->descriptor()->dimMappings();
2365 
2366  auto inputs = GetInputs(graph, layerIndex);
2367  CHECK_VALID_SIZE(inputs.size(), 1);
2368 
2369  auto outputs = GetOutputs(graph, layerIndex);
2370  CHECK_VALID_SIZE(outputs.size(), 1);
2371  auto outputInfo = ToTensorInfo(outputs[0]);
2372 
2373  auto layerName = GetLayerName(graph, layerIndex);
2374  const armnn::PermuteDescriptor descriptor(armnn::PermutationVector(dimsMapping->data(), dimsMapping->size()));
2375 
2376  IConnectableLayer* layer = m_Network->AddPermuteLayer(descriptor, layerName.c_str());
2377  layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
2378 
2379  RegisterInputSlots(graph, layerIndex, layer);
2380  RegisterOutputSlots(graph, layerIndex, layer);
2381 }
2382 
2384  unsigned int layerIndex)
2385 {
2386  IgnoreUnused(layerIndex);
2388 
2389  switch (pooling2dDesc->poolType())
2390  {
2391  case PoolingAlgorithm_Average:
2392  {
2394  break;
2395  }
2396  case PoolingAlgorithm_Max:
2397  {
2399  break;
2400  }
2401  case PoolingAlgorithm_L2:
2402  {
2404  break;
2405  }
2406  default:
2407  {
2408  throw ParseException("Unsupported pooling algorithm");
2409  }
2410  }
2411 
2412  switch (pooling2dDesc->outputShapeRounding())
2413  {
2414  case OutputShapeRounding_Floor:
2415  {
2417  break;
2418  }
2419  case OutputShapeRounding_Ceiling:
2420  {
2422  break;
2423  }
2424  default:
2425  {
2426  throw ParseException("Unsupported output shape rounding");
2427  }
2428  }
2429 
2430  switch (pooling2dDesc->paddingMethod())
2431  {
2432  case PaddingMethod_Exclude:
2433  {
2435  break;
2436  }
2437  case PaddingMethod_IgnoreValue:
2438  {
2440  break;
2441  }
2442  default:
2443  {
2444  throw ParseException("Unsupported padding method");
2445  }
2446  }
2447 
2448  switch (pooling2dDesc->dataLayout())
2449  {
2450  case DataLayout_NCHW:
2451  {
2453  break;
2454  }
2455  case DataLayout_NHWC:
2456  {
2458  break;
2459  }
2460  default:
2461  {
2462  throw ParseException("Unsupported data layout");
2463  }
2464  }
2465 
2466  desc.m_PadRight = pooling2dDesc->padRight();
2467  desc.m_PadLeft = pooling2dDesc->padLeft();
2468  desc.m_PadBottom = pooling2dDesc->padBottom();
2469  desc.m_PadTop = pooling2dDesc->padTop();
2470  desc.m_StrideX = pooling2dDesc->strideX();
2471  desc.m_StrideY = pooling2dDesc->strideY();
2472  desc.m_PoolWidth = pooling2dDesc->poolWidth();
2473  desc.m_PoolHeight = pooling2dDesc->poolHeight();
2474 
2475  return desc;
2476 }
2477 
2479  unsigned int layerIndex)
2480 {
2481  IgnoreUnused(layerIndex);
2483 
2484  switch (pooling3dDesc->poolType())
2485  {
2486  case PoolingAlgorithm_Average:
2487  {
2489  break;
2490  }
2491  case PoolingAlgorithm_Max:
2492  {
2494  break;
2495  }
2496  case PoolingAlgorithm_L2:
2497  {
2499  break;
2500  }
2501  default:
2502  {
2503  throw ParseException("Unsupported pooling algorithm");
2504  }
2505  }
2506 
2507  switch (pooling3dDesc->outputShapeRounding())
2508  {
2509  case OutputShapeRounding_Floor:
2510  {
2512  break;
2513  }
2514  case OutputShapeRounding_Ceiling:
2515  {
2517  break;
2518  }
2519  default:
2520  {
2521  throw ParseException("Unsupported output shape rounding");
2522  }
2523  }
2524 
2525  switch (pooling3dDesc->paddingMethod())
2526  {
2527  case PaddingMethod_Exclude:
2528  {
2530  break;
2531  }
2532  case PaddingMethod_IgnoreValue:
2533  {
2535  break;
2536  }
2537  default:
2538  {
2539  throw ParseException("Unsupported padding method");
2540  }
2541  }
2542 
2543  switch (pooling3dDesc->dataLayout())
2544  {
2545  case DataLayout_NCDHW:
2546  {
2548  break;
2549  }
2550  case DataLayout_NDHWC:
2551  {
2553  break;
2554  }
2555  default:
2556  {
2557  throw ParseException("Unsupported data layout");
2558  }
2559  }
2560 
2561  desc.m_PadRight = pooling3dDesc->padRight();
2562  desc.m_PadLeft = pooling3dDesc->padLeft();
2563  desc.m_PadBottom = pooling3dDesc->padBottom();
2564  desc.m_PadTop = pooling3dDesc->padTop();
2565  desc.m_PadFront = pooling3dDesc->padFront();
2566  desc.m_PadBack = pooling3dDesc->padBack();
2567  desc.m_StrideX = pooling3dDesc->strideX();
2568  desc.m_StrideY = pooling3dDesc->strideY();
2569  desc.m_StrideZ = pooling3dDesc->strideZ();
2570  desc.m_PoolWidth = pooling3dDesc->poolWidth();
2571  desc.m_PoolHeight = pooling3dDesc->poolHeight();
2572  desc.m_PoolDepth = pooling3dDesc->poolDepth();
2573 
2574  return desc;
2575 }
2576 
2577 void IDeserializer::DeserializerImpl::ParsePooling2d(GraphPtr graph, unsigned int layerIndex)
2578 {
2579  CHECK_LAYERS(graph, 0, layerIndex);
2580 
2581  auto pooling2dDes = graph->layers()->Get(layerIndex)->layer_as_Pooling2dLayer()->descriptor();
2582  auto inputs = GetInputs(graph, layerIndex);
2583  CHECK_VALID_SIZE(inputs.size(), 1);
2584 
2585  auto outputs = GetOutputs(graph, layerIndex);
2586  CHECK_VALID_SIZE(outputs.size(), 1);
2587  auto outputInfo = ToTensorInfo(outputs[0]);
2588 
2589  auto pooling2dDescriptor = GetPooling2dDescriptor(pooling2dDes, layerIndex);
2590  auto layerName = GetLayerName(graph, layerIndex);
2591  IConnectableLayer* layer = m_Network->AddPooling2dLayer(pooling2dDescriptor, layerName.c_str());
2592  layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
2593 
2594  RegisterInputSlots(graph, layerIndex, layer);
2595  RegisterOutputSlots(graph, layerIndex, layer);
2596 }
2597 
2598 void IDeserializer::DeserializerImpl::ParsePooling3d(GraphPtr graph, unsigned int layerIndex)
2599 {
2600  CHECK_LAYERS(graph, 0, layerIndex);
2601 
2602  auto pooling3dDes = graph->layers()->Get(layerIndex)->layer_as_Pooling3dLayer()->descriptor();
2603  auto inputs = GetInputs(graph, layerIndex);
2604  CHECK_VALID_SIZE(inputs.size(), 1);
2605 
2606  auto outputs = GetOutputs(graph, layerIndex);
2607  CHECK_VALID_SIZE(outputs.size(), 1);
2608  auto outputInfo = ToTensorInfo(outputs[0]);
2609 
2610  auto pooling3dDescriptor = GetPooling3dDescriptor(pooling3dDes, layerIndex);
2611  auto layerName = GetLayerName(graph, layerIndex);
2612  IConnectableLayer* layer = m_Network->AddPooling3dLayer(pooling3dDescriptor, layerName.c_str());
2613  layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
2614 
2615  RegisterInputSlots(graph, layerIndex, layer);
2616  RegisterOutputSlots(graph, layerIndex, layer);
2617 }
2618 
2619 void IDeserializer::DeserializerImpl::ParseQuantize(GraphPtr graph, unsigned int layerIndex)
2620 {
2621  CHECK_LAYERS(graph, 0, layerIndex);
2622 
2623  auto inputs = GetInputs(graph, layerIndex);
2624  CHECK_VALID_SIZE(inputs.size(), 1);
2625 
2626  auto outputs = GetOutputs(graph, layerIndex);
2627  CHECK_VALID_SIZE(outputs.size(), 1);
2628  auto outputInfo = ToTensorInfo(outputs[0]);
2629 
2630  auto layerName = GetLayerName(graph, layerIndex);
2631  IConnectableLayer* layer = m_Network->AddQuantizeLayer(layerName.c_str());
2632  layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
2633 
2634  RegisterInputSlots(graph, layerIndex, layer);
2635  RegisterOutputSlots(graph, layerIndex, layer);
2636 }
2637 
2639  const std::vector<uint32_t>& targetDimsIn)
2640 {
2641  std::vector<unsigned int> outputDims(targetDimsIn.begin(), targetDimsIn.end());
2642  const auto stretchDim = std::find(targetDimsIn.begin(), targetDimsIn.end(), -1);
2643 
2644  if (stretchDim != targetDimsIn.end())
2645  {
2646  if (std::find(std::next(stretchDim), targetDimsIn.end(), -1) != targetDimsIn.end())
2647  {
2648  throw ParseException(fmt::format("At most one component of shape can be -1 {}",
2649  CHECK_LOCATION().AsString()));
2650  }
2651 
2652  auto targetNumElements =
2653  armnn::numeric_cast<unsigned int>(
2654  std::accumulate(targetDimsIn.begin(), targetDimsIn.end(), -1, std::multiplies<int32_t>()));
2655 
2656  auto stretchIndex = static_cast<size_t>(std::distance(targetDimsIn.begin(), stretchDim));
2657  if (targetNumElements == 0)
2658  {
2659  if (inputTensorInfo.GetNumElements() == 0)
2660  {
2661  outputDims[stretchIndex] = 0;
2662  }
2663  else
2664  {
2665  throw ParseException(
2666  fmt::format("Input to reshape is a tensor with elements, but the requested shape has 0. {}",
2667  CHECK_LOCATION().AsString()));
2668  }
2669  }
2670  else
2671  {
2672  outputDims[stretchIndex] = inputTensorInfo.GetNumElements() / targetNumElements;
2673  }
2674  }
2675 
2676  TensorShape outputShape = TensorShape(static_cast<unsigned int>(outputDims.size()), outputDims.data());
2677 
2678  armnn::TensorInfo reshapeInfo = inputTensorInfo;
2679  reshapeInfo.SetShape(outputShape);
2680 
2681  return reshapeInfo;
2682 }
2683 
2684 void IDeserializer::DeserializerImpl::ParseRank(GraphPtr graph, unsigned int layerIndex)
2685 {
2686  CHECK_LAYERS(graph, 0, layerIndex);
2687 
2688  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
2689  CHECK_VALID_SIZE(inputs.size(), 1);
2690 
2691  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
2692  CHECK_VALID_SIZE(outputs.size(), 1);
2693 
2694  auto layerName = GetLayerName(graph, layerIndex);
2695  IConnectableLayer* layer = m_Network->AddRankLayer( layerName.c_str());
2696 
2697  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2698  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2699 
2700  RegisterInputSlots(graph, layerIndex, layer);
2701  RegisterOutputSlots(graph, layerIndex, layer);
2702 }
2703 
2704 void IDeserializer::DeserializerImpl::ParseReduce(GraphPtr graph, unsigned int layerIndex)
2705 {
2706  CHECK_LAYERS(graph, 0, layerIndex);
2707  CHECK_LOCATION();
2708 
2709  auto inputs = GetInputs(graph, layerIndex);
2710  CHECK_VALID_SIZE(inputs.size(), 1);
2711 
2712  auto outputs = GetOutputs(graph, layerIndex);
2713  CHECK_VALID_SIZE(outputs.size(), 1);
2714 
2715  auto fbLayer = graph->layers()->Get(layerIndex)->layer_as_ReduceLayer();
2716  auto fbDescriptor = fbLayer->descriptor();
2717  auto flatBufferAxis = fbDescriptor->axis();
2718 
2719  armnn::ReduceDescriptor descriptor;
2720  descriptor.m_KeepDims = fbDescriptor->keepDims();
2721  descriptor.m_vAxis = std::vector<unsigned int>(flatBufferAxis->begin(), flatBufferAxis->end());
2722  descriptor.m_ReduceOperation = ToReduceOperation(fbDescriptor->reduceOperation());
2723 
2724  const std::string& layerName = GetLayerName(graph, layerIndex);
2725  IConnectableLayer* layer = m_Network->AddReduceLayer(descriptor, layerName.c_str());
2726 
2727  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2728  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2729 
2730  RegisterInputSlots(graph, layerIndex, layer);
2731  RegisterOutputSlots(graph, layerIndex, layer);
2732 }
2733 
2734 void IDeserializer::DeserializerImpl::ParseReshape(GraphPtr graph, unsigned int layerIndex)
2735 {
2736  CHECK_LAYERS(graph, 0, layerIndex);
2737  auto inputs = GetInputs(graph, layerIndex);
2738 
2739  auto outputs = GetOutputs(graph, layerIndex);
2740  CHECK_VALID_SIZE(outputs.size(), 1);
2741 
2742  armnn::TensorInfo inputTensorInfo = ToTensorInfo(inputs[0]);
2743  armnn::TensorInfo actualOutputTensorInfo = ToTensorInfo(outputs[0]);
2744 
2745  const auto targetDims = graph->layers()->Get(layerIndex)->layer_as_ReshapeLayer()->descriptor()->targetShape();
2746  std::vector<uint32_t> outputDims(targetDims->begin(), targetDims->begin() + targetDims->size());
2747 
2748  armnn::TensorInfo reshapeOutputTensorInfo = DeserializerImpl::OutputShapeOfReshape(inputTensorInfo, outputDims);
2749  const armnn::TensorShape& reshapeOutputTensorShape = reshapeOutputTensorInfo.GetShape();
2750 
2751  const std::vector<uint32_t> expectedDims(outputs[0]->dimensions()->begin(),
2752  outputs[0]->dimensions()->begin() + outputs[0]->dimensions()->size());
2753 
2754  if (inputs.size() > 1 && !CheckShape(reshapeOutputTensorShape, expectedDims))
2755  {
2756  std::stringstream ss;
2757  ss << "New shape defined in reshape parameters "
2758  << reshapeOutputTensorShape
2759  << " does not equal output shape "
2760  << actualOutputTensorInfo.GetShape()
2761  << ": "
2762  << CHECK_LOCATION().AsString();
2763  throw ParseException(ss.str());
2764  }
2765 
2766  armnn::ReshapeDescriptor reshapeDesc;
2767  reshapeDesc.m_TargetShape = reshapeOutputTensorShape;
2768 
2769  auto layerName = GetLayerName(graph, layerIndex);
2770  IConnectableLayer* layer = m_Network->AddReshapeLayer(reshapeDesc, layerName.c_str());
2771  layer->GetOutputSlot(0).SetTensorInfo(reshapeOutputTensorInfo);
2772 
2773  RegisterInputSlots(graph, layerIndex, layer);
2774  RegisterOutputSlots(graph, layerIndex, layer);
2775 }
2776 
2777 void IDeserializer::DeserializerImpl::ParseResize(GraphPtr graph, unsigned int layerIndex)
2778 {
2779  CHECK_LAYERS(graph, 0, layerIndex);
2780 
2781  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
2782  CHECK_VALID_SIZE(inputs.size(), 1);
2783 
2784  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
2785  CHECK_VALID_SIZE(outputs.size(), 1);
2786 
2787  auto flatBufferDescriptor = graph->layers()->Get(layerIndex)->layer_as_ResizeLayer()->descriptor();
2788 
2789  armnn::ResizeDescriptor descriptor;
2790  descriptor.m_TargetWidth = flatBufferDescriptor->targetWidth();
2791  descriptor.m_TargetHeight = flatBufferDescriptor->targetHeight();
2792  descriptor.m_Method = ToResizeMethod(flatBufferDescriptor->method());
2793  descriptor.m_DataLayout = ToDataLayout(flatBufferDescriptor->dataLayout());
2794  descriptor.m_AlignCorners = flatBufferDescriptor->alignCorners();
2795  descriptor.m_HalfPixelCenters = flatBufferDescriptor->halfPixelCenters();
2796 
2797  auto layerName = GetLayerName(graph, layerIndex);
2798  IConnectableLayer* layer = m_Network->AddResizeLayer(descriptor, layerName.c_str());
2799 
2800  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2801  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2802 
2803  RegisterInputSlots(graph, layerIndex, layer);
2804  RegisterOutputSlots(graph, layerIndex, layer);
2805 }
2806 
2807 void IDeserializer::DeserializerImpl::ParseReverseV2(GraphPtr graph, unsigned int layerIndex)
2808 {
2809  CHECK_LAYERS(graph, 0, layerIndex);
2810 
2811  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
2812  CHECK_VALID_SIZE(inputs.size(), 2);
2813 
2814  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
2815  CHECK_VALID_SIZE(outputs.size(), 1);
2816 
2817  auto layerName = GetLayerName(graph, layerIndex);
2818  IConnectableLayer* layer = m_Network->AddReverseV2Layer(layerName.c_str());
2819 
2820  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2821  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2822 
2823  RegisterInputSlots(graph, layerIndex, layer);
2824  RegisterOutputSlots(graph, layerIndex, layer);
2825 }
2826 
2827 /// @Note The ResizeBiliniar operation was deprecated and removed in favor of the Resize operation.
2828 /// This function is kept for backwards compatibility.
2829 void IDeserializer::DeserializerImpl::ParseResizeBilinear(GraphPtr graph, unsigned int layerIndex)
2830 {
2831  CHECK_LAYERS(graph, 0, layerIndex);
2832 
2833  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
2834  CHECK_VALID_SIZE(inputs.size(), 1);
2835 
2836  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
2837  CHECK_VALID_SIZE(outputs.size(), 1);
2838 
2839  auto flatBufferDescriptor = graph->layers()->Get(layerIndex)->layer_as_ResizeBilinearLayer()->descriptor();
2840 
2841  armnn::ResizeDescriptor descriptor;
2842  descriptor.m_TargetWidth = flatBufferDescriptor->targetWidth();
2843  descriptor.m_TargetHeight = flatBufferDescriptor->targetHeight();
2845  descriptor.m_DataLayout = ToDataLayout(flatBufferDescriptor->dataLayout());
2846  descriptor.m_AlignCorners = flatBufferDescriptor->alignCorners();
2847  descriptor.m_HalfPixelCenters = flatBufferDescriptor->halfPixelCenters();
2848 
2849  auto layerName = GetLayerName(graph, layerIndex);
2850  IConnectableLayer* layer = m_Network->AddResizeLayer(descriptor, layerName.c_str());
2851 
2852  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2853  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2854 
2855  RegisterInputSlots(graph, layerIndex, layer);
2856  RegisterOutputSlots(graph, layerIndex, layer);
2857 }
2858 
2859 void IDeserializer::DeserializerImpl::ParseShape(GraphPtr graph, unsigned int layerIndex)
2860 {
2861  CHECK_LAYERS(graph, 0, layerIndex);
2862 
2863  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
2864  CHECK_VALID_SIZE(inputs.size(), 1);
2865 
2866  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
2867  CHECK_VALID_SIZE(outputs.size(), 1);
2868 
2869  auto layerName = GetLayerName(graph, layerIndex);
2870  IConnectableLayer* layer = m_Network->AddShapeLayer( layerName.c_str());
2871 
2872  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2873  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2874 
2875  RegisterInputSlots(graph, layerIndex, layer);
2876  RegisterOutputSlots(graph, layerIndex, layer);
2877 }
2878 
2879 void IDeserializer::DeserializerImpl::ParseSoftmax(GraphPtr graph, unsigned int layerIndex)
2880 {
2881  CHECK_LAYERS(graph, 0, layerIndex);
2882 
2883  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
2884  CHECK_VALID_SIZE(inputs.size(), 1);
2885 
2886  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
2887  CHECK_VALID_SIZE(outputs.size(), 1);
2888 
2889  armnn::SoftmaxDescriptor descriptor;
2890  descriptor.m_Beta = graph->layers()->Get(layerIndex)->layer_as_SoftmaxLayer()->descriptor()->beta();
2891  descriptor.m_Axis = graph->layers()->Get(layerIndex)->layer_as_SoftmaxLayer()->descriptor()->axis();
2892  auto layerName = GetLayerName(graph, layerIndex);
2893 
2894  IConnectableLayer* layer = m_Network->AddSoftmaxLayer(descriptor, layerName.c_str());
2895 
2896  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2897  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2898 
2899  RegisterInputSlots(graph, layerIndex, layer);
2900  RegisterOutputSlots(graph, layerIndex, layer);
2901 }
2902 
2903 void IDeserializer::DeserializerImpl::ParseSpaceToBatchNd(GraphPtr graph, unsigned int layerIndex)
2904 {
2905  CHECK_LAYERS(graph, 0, layerIndex);
2906 
2907  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
2908  CHECK_VALID_SIZE(inputs.size(), 1);
2909 
2910  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
2911  CHECK_VALID_SIZE(outputs.size(), 1);
2912 
2913  auto flatBufferDescriptor = graph->layers()->Get(layerIndex)->layer_as_SpaceToBatchNdLayer()->descriptor();
2914  auto flatBufferPadList = flatBufferDescriptor->padList();
2915  auto flatBufferBlockShape = flatBufferDescriptor->blockShape();
2916 
2917  if (flatBufferPadList->size() % 2 != 0)
2918  {
2919  throw ParseException(fmt::format("The size of the pad list must be divisible by 2 {}",
2920  CHECK_LOCATION().AsString()));
2921  }
2922 
2923  std::vector<std::pair<unsigned int, unsigned int>> padList;
2924  padList.reserve(flatBufferPadList->size() / 2);
2925  for (unsigned int i = 0; i < flatBufferPadList->size() - 1; i += 2)
2926  {
2927  padList.emplace_back(flatBufferPadList->Get(i), flatBufferPadList->Get(i+1));
2928  }
2929 
2931  descriptor.m_DataLayout = ToDataLayout(flatBufferDescriptor->dataLayout());
2932  descriptor.m_BlockShape =
2933  std::vector<unsigned int>(flatBufferBlockShape->begin(), flatBufferBlockShape->end());
2934  descriptor.m_PadList = padList;
2935 
2936  auto layerName = GetLayerName(graph, layerIndex);
2937  IConnectableLayer* layer = m_Network->AddSpaceToBatchNdLayer(descriptor, layerName.c_str());
2938 
2939  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2940  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2941 
2942  RegisterInputSlots(graph, layerIndex, layer);
2943  RegisterOutputSlots(graph, layerIndex, layer);
2944 }
2945 
2946 void IDeserializer::DeserializerImpl::ParseSpaceToDepth(GraphPtr graph, unsigned int layerIndex)
2947 {
2948  CHECK_LAYERS(graph, 0, layerIndex);
2949 
2950  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
2951  CHECK_VALID_SIZE(inputs.size(), 1);
2952 
2953  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
2954  CHECK_VALID_SIZE(outputs.size(), 1);
2955 
2956  auto flatBufferDescriptor = graph->layers()->Get(layerIndex)->layer_as_SpaceToDepthLayer()->descriptor();
2957 
2958  armnn::SpaceToDepthDescriptor descriptor;
2959  descriptor.m_BlockSize = flatBufferDescriptor->blockSize();
2960  descriptor.m_DataLayout = ToDataLayout(flatBufferDescriptor->dataLayout());
2961 
2962  auto layerName = GetLayerName(graph, layerIndex);
2963  IConnectableLayer* layer = m_Network->AddSpaceToDepthLayer(descriptor, layerName.c_str());
2964 
2965  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
2966  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
2967 
2968  RegisterInputSlots(graph, layerIndex, layer);
2969  RegisterOutputSlots(graph, layerIndex, layer);
2970 }
2971 
2973  NormalizationDescriptorPtr normalizationDescriptor,
2974  unsigned int layerIndex)
2975 {
2976  IgnoreUnused(layerIndex);
2978 
2979  switch (normalizationDescriptor->normChannelType())
2980  {
2981  case NormalizationAlgorithmChannel_Across:
2982  {
2984  break;
2985  }
2986  case NormalizationAlgorithmChannel_Within:
2987  {
2989  break;
2990  }
2991  default:
2992  {
2993  throw ParseException("Unsupported normalization channel type");
2994  }
2995  }
2996 
2997  switch (normalizationDescriptor->normMethodType())
2998  {
2999  case NormalizationAlgorithmMethod_LocalBrightness:
3000  {
3002  break;
3003  }
3004  case NormalizationAlgorithmMethod_LocalContrast:
3005  {
3007  break;
3008  }
3009  default:
3010  {
3011  throw ParseException("Unsupported normalization method type");
3012  }
3013  }
3014 
3015  switch (normalizationDescriptor->dataLayout())
3016  {
3017  case DataLayout_NCHW:
3018  {
3020  break;
3021  }
3022  case DataLayout_NHWC:
3023  {
3025  break;
3026  }
3027  default:
3028  {
3029  throw ParseException("Unsupported data layout");
3030  }
3031  }
3032 
3033  desc.m_Alpha = normalizationDescriptor->alpha();
3034  desc.m_Beta = normalizationDescriptor->beta();
3035  desc.m_K = normalizationDescriptor->k();
3036  desc.m_NormSize = normalizationDescriptor->normSize();
3037 
3038  return desc;
3039 }
3040 
3041 void IDeserializer::DeserializerImpl::ParseNormalization(GraphPtr graph, unsigned int layerIndex)
3042 {
3043  CHECK_LAYERS(graph, 0, layerIndex);
3044 
3045  auto normalizationDes = graph->layers()->Get(layerIndex)->layer_as_NormalizationLayer()->descriptor();
3046 
3047  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
3048  CHECK_VALID_SIZE(inputs.size(), 1);
3049 
3050  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
3051  CHECK_VALID_SIZE(outputs.size(), 1);
3052 
3053  auto outputInfo = ToTensorInfo(outputs[0]);
3054 
3055  auto normalizationDescriptor = GetNormalizationDescriptor(normalizationDes, layerIndex);
3056  auto layerName = GetLayerName(graph, layerIndex);
3057 
3058  IConnectableLayer* layer = m_Network->AddNormalizationLayer(normalizationDescriptor, layerName.c_str());
3059  layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
3060 
3061  RegisterInputSlots(graph, layerIndex, layer);
3062  RegisterOutputSlots(graph, layerIndex, layer);
3063 }
3064 
3065 void IDeserializer::DeserializerImpl::ParseRsqrt(GraphPtr graph, unsigned int layerIndex)
3066 {
3067  CHECK_LAYERS(graph, 0, layerIndex);
3068  auto inputs = GetInputs(graph, layerIndex);
3069  CHECK_LOCATION();
3070  CHECK_VALID_SIZE(inputs.size(), 1);
3071 
3072  auto outputs = GetOutputs(graph, layerIndex);
3073  CHECK_VALID_SIZE(outputs.size(), 1);
3074 
3075  auto layerName = GetLayerName(graph, layerIndex);
3076 
3078  IConnectableLayer* layer = m_Network->AddElementwiseUnaryLayer(descriptor, layerName.c_str());
3079  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3080  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3081 
3082  RegisterInputSlots(graph, layerIndex, layer);
3083  RegisterOutputSlots(graph, layerIndex, layer);
3084 }
3085 
3086 void IDeserializer::DeserializerImpl::ParseSlice(GraphPtr graph, unsigned int layerIndex)
3087 {
3088  CHECK_LAYERS(graph, 0, layerIndex);
3089 
3090  auto inputs = GetInputs(graph, layerIndex);
3091  CHECK_VALID_SIZE(inputs.size(), 1);
3092 
3093  auto outputs = GetOutputs(graph, layerIndex);
3094  CHECK_VALID_SIZE(outputs.size(), 1);
3095 
3096  auto fbDescriptor = graph->layers()->Get(layerIndex)->layer_as_SliceLayer()->descriptor();
3097 
3098  auto fbBegin = fbDescriptor->begin();
3099  auto fbSize = fbDescriptor->size();
3100 
3101  if (fbBegin->size() != fbSize->size())
3102  {
3103  throw ParseException(fmt::format("Begin and size descriptors must have the same length {}",
3104  CHECK_LOCATION().AsString()));
3105  }
3106 
3107  armnn::SliceDescriptor descriptor;
3108  descriptor.m_Begin.insert(descriptor.m_Begin.end(), fbBegin->begin(), fbBegin->end());
3109  descriptor.m_Size.insert(descriptor.m_Size.end(), fbSize->begin(), fbSize->end());
3110 
3111  auto layerName = GetLayerName(graph, layerIndex);
3112  IConnectableLayer* layer = m_Network->AddSliceLayer(descriptor, layerName.c_str());
3113 
3114  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3115  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3116 
3117  RegisterInputSlots(graph, layerIndex, layer);
3118  RegisterOutputSlots(graph, layerIndex, layer);
3119 }
3120 
3121 void IDeserializer::DeserializerImpl::ParseStridedSlice(GraphPtr graph, unsigned int layerIndex)
3122 {
3123  CHECK_LAYERS(graph, 0, layerIndex);
3124 
3125  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
3126  CHECK_VALID_SIZE(inputs.size(), 1);
3127 
3128  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
3129  CHECK_VALID_SIZE(outputs.size(), 1);
3130 
3131  auto flatBufferDescriptor = graph->layers()->Get(layerIndex)->layer_as_StridedSliceLayer()->descriptor();
3132 
3133  auto flatBufferBegin = flatBufferDescriptor->begin();
3134  auto flatBufferEnd = flatBufferDescriptor->end();
3135  auto flatBufferStride = flatBufferDescriptor->stride();
3136 
3137  if (!(flatBufferBegin->size() == flatBufferEnd->size() &&
3138  flatBufferBegin->size() == flatBufferStride->size()))
3139  {
3140  throw ParseException(fmt::format("The size of the begin, end, and stride must be equal {}",
3141  CHECK_LOCATION().AsString()));
3142  }
3143 
3144  std::vector<int> begin(flatBufferBegin->begin(), flatBufferBegin->end());
3145  std::vector<int> end(flatBufferEnd->begin(), flatBufferEnd->end());
3146  std::vector<int> stride(flatBufferStride->begin(), flatBufferStride->end());
3147 
3148  armnn::StridedSliceDescriptor descriptor(begin, end, stride);
3149  descriptor.m_BeginMask = flatBufferDescriptor->beginMask();
3150  descriptor.m_EndMask = flatBufferDescriptor->endMask();
3151  descriptor.m_ShrinkAxisMask = flatBufferDescriptor->shrinkAxisMask();
3152  descriptor.m_EllipsisMask = flatBufferDescriptor->ellipsisMask();
3153  descriptor.m_NewAxisMask = flatBufferDescriptor->newAxisMask();
3154  descriptor.m_DataLayout = ToDataLayout(flatBufferDescriptor->dataLayout());
3155 
3156  auto layerName = GetLayerName(graph, layerIndex);
3157  IConnectableLayer* layer = m_Network->AddStridedSliceLayer(descriptor, layerName.c_str());
3158 
3159  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3160  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3161 
3162  RegisterInputSlots(graph, layerIndex, layer);
3163  RegisterOutputSlots(graph, layerIndex, layer);
3164 }
3165 
3166 void IDeserializer::DeserializerImpl::ParseSubtraction(GraphPtr graph, unsigned int layerIndex)
3167 {
3168  CHECK_LAYERS(graph, 0, layerIndex);
3169  auto inputs = GetInputs(graph, layerIndex);
3170  CHECK_LOCATION();
3171  CHECK_VALID_SIZE(inputs.size(), 2);
3172 
3173  auto outputs = GetOutputs(graph, layerIndex);
3174  CHECK_VALID_SIZE(outputs.size(), 1);
3175 
3176  auto layerName = GetLayerName(graph, layerIndex);
3178  IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(descriptor, layerName.c_str());
3179 
3180  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3181  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3182 
3183  RegisterInputSlots(graph, layerIndex, layer);
3184  RegisterOutputSlots(graph, layerIndex, layer);
3185 }
3186 
3187 void IDeserializer::DeserializerImpl::ParseGather(GraphPtr graph, unsigned int layerIndex)
3188 {
3189  CHECK_LAYERS(graph, 0, layerIndex);
3190 
3191  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
3192  CHECK_VALID_SIZE(inputs.size(), 2);
3193 
3194  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
3195  CHECK_VALID_SIZE(outputs.size(), 1);
3196 
3197  armnn::GatherDescriptor descriptor;
3198  descriptor.m_Axis = graph->layers()->Get(layerIndex)->layer_as_GatherLayer()->descriptor()->axis();
3199 
3200  auto layerName = GetLayerName(graph, layerIndex);
3201  IConnectableLayer* layer = m_Network->AddGatherLayer(descriptor, layerName.c_str());
3202 
3203  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3204  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3205 
3206  RegisterInputSlots(graph, layerIndex, layer);
3207  RegisterOutputSlots(graph, layerIndex, layer);
3208 }
3209 
3210 void IDeserializer::DeserializerImpl::ParseGatherNd(GraphPtr graph, unsigned int layerIndex)
3211 {
3212  CHECK_LAYERS(graph, 0, layerIndex);
3213 
3214  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
3215  CHECK_VALID_SIZE(inputs.size(), 2);
3216 
3217  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
3218  CHECK_VALID_SIZE(outputs.size(), 1);
3219 
3220  auto layerName = GetLayerName(graph, layerIndex);
3221  IConnectableLayer* layer = m_Network->AddGatherNdLayer(layerName.c_str());
3222 
3223  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3224  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3225 
3226  RegisterInputSlots(graph, layerIndex, layer);
3227  RegisterOutputSlots(graph, layerIndex, layer);
3228 }
3229 
3230 void IDeserializer::DeserializerImpl::ParseMean(GraphPtr graph, unsigned int layerIndex)
3231 {
3232  CHECK_LAYERS(graph, 0, layerIndex);
3233 
3234  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
3235  CHECK_VALID_SIZE(inputs.size(), 1);
3236 
3237  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
3238  CHECK_VALID_SIZE(outputs.size(), 1);
3239 
3240  auto flatBufferDescriptor = graph->layers()->Get(layerIndex)->layer_as_MeanLayer()->descriptor();
3241  auto flatBufferAxis = flatBufferDescriptor->axis();
3242  auto flatBufferKeepDims = flatBufferDescriptor->keepDims();
3243 
3244  armnn::MeanDescriptor descriptor;
3245  descriptor.m_Axis = std::vector<unsigned int>(flatBufferAxis->begin(), flatBufferAxis->end());
3246  descriptor.m_KeepDims = flatBufferKeepDims;
3247 
3248  auto layerName = GetLayerName(graph, layerIndex);
3249  IConnectableLayer* layer = m_Network->AddMeanLayer(descriptor, layerName.c_str());
3250 
3251  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3252  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3253 
3254  RegisterInputSlots(graph, layerIndex, layer);
3255  RegisterOutputSlots(graph, layerIndex, layer);
3256 }
3257 
3258 void IDeserializer::DeserializerImpl::ParseSplitter(GraphPtr graph, unsigned int layerIndex)
3259 {
3260  CHECK_LAYERS(graph, 0, layerIndex);
3261 
3262  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
3263  CHECK_VALID_SIZE(inputs.size(), 1);
3264 
3265  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
3266 
3267  auto flatBufferViewsDescriptor = graph->layers()->Get(layerIndex)->layer_as_SplitterLayer()->descriptor();
3268  auto flatBufferViewSizes = flatBufferViewsDescriptor->viewSizes();
3269  auto flatBufferOriginsDescriptor = flatBufferViewsDescriptor->origins();
3270  auto flatBufferViewOrigins = flatBufferOriginsDescriptor->viewOrigins();
3271  uint32_t numViews = flatBufferOriginsDescriptor->numViews();
3272  uint32_t numDimensions = flatBufferOriginsDescriptor->numDimensions();
3273 
3274  // Check numViews and numDimensions corresponds to the ones already serialized ...
3275  // numViews == flatBufferViewSizes.size();
3276  // foreach: numDimensions == flatBufferViewSizes[x].size();
3277 
3278  armnn::ViewsDescriptor viewsDescriptor(numViews, numDimensions);
3279  for(unsigned int vIdx = 0; vIdx < numViews; ++vIdx)
3280  {
3281  for (unsigned int dIdx = 0; dIdx < numDimensions; ++dIdx)
3282  {
3283  viewsDescriptor.SetViewSize(vIdx, dIdx, flatBufferViewSizes->Get(vIdx)->data()->Get(dIdx));
3284  viewsDescriptor.SetViewOriginCoord(vIdx, dIdx, flatBufferViewOrigins->Get(vIdx)->data()->Get(dIdx));
3285  }
3286  }
3287 
3288  if (flatBufferViewsDescriptor->hasAxis())
3289  {
3290  viewsDescriptor.SetAxis(flatBufferViewsDescriptor->axis());
3291  }
3292 
3293  auto layerName = GetLayerName(graph, layerIndex);
3294  IConnectableLayer* layer = m_Network->AddSplitterLayer(viewsDescriptor, layerName.c_str());
3295 
3296  // I could have as many outputs as views ...
3297  for(unsigned int vIdx = 0; vIdx < numViews; ++vIdx)
3298  {
3299  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[vIdx]);
3300  layer->GetOutputSlot(vIdx).SetTensorInfo(outputTensorInfo);
3301  }
3302 
3303  RegisterInputSlots(graph, layerIndex, layer);
3304  RegisterOutputSlots(graph, layerIndex, layer);
3305 }
3306 
3308 {
3309  armnn::LstmDescriptor desc;
3310 
3311  desc.m_ActivationFunc = lstmDescriptor->activationFunc();
3312  desc.m_ClippingThresCell = lstmDescriptor->clippingThresCell();
3313  desc.m_ClippingThresProj = lstmDescriptor->clippingThresProj();
3314  desc.m_CifgEnabled = lstmDescriptor->cifgEnabled();
3315  desc.m_PeepholeEnabled = lstmDescriptor->peepholeEnabled();
3316  desc.m_ProjectionEnabled = lstmDescriptor->projectionEnabled();
3317  desc.m_LayerNormEnabled = lstmDescriptor->layerNormEnabled();
3318 
3319  return desc;
3320 }
3321 
3322 void IDeserializer::DeserializerImpl::ParseLstm(GraphPtr graph, unsigned int layerIndex)
3323 {
3324  CHECK_LAYERS(graph, 0, layerIndex);
3325 
3326  auto inputs = GetInputs(graph, layerIndex);
3327  CHECK_VALID_SIZE(inputs.size(), 3);
3328 
3329  auto outputs = GetOutputs(graph, layerIndex);
3330  CHECK_VALID_SIZE(outputs.size(), 4);
3331 
3332  auto flatBufferLayer = graph->layers()->Get(layerIndex)->layer_as_LstmLayer();
3333  auto layerName = GetLayerName(graph, layerIndex);
3334  auto flatBufferDescriptor = flatBufferLayer->descriptor();
3335  auto flatBufferInputParams = flatBufferLayer->inputParams();
3336 
3337  auto lstmDescriptor = GetLstmDescriptor(flatBufferDescriptor);
3338 
3339  armnn::LstmInputParams lstmInputParams;
3340 
3341  armnn::ConstTensor inputToForgetWeights = ToConstTensor(flatBufferInputParams->inputToForgetWeights());
3342  armnn::ConstTensor inputToCellWeights = ToConstTensor(flatBufferInputParams->inputToCellWeights());
3343  armnn::ConstTensor inputToOutputWeights = ToConstTensor(flatBufferInputParams->inputToOutputWeights());
3344  armnn::ConstTensor recurrentToForgetWeights = ToConstTensor(flatBufferInputParams->recurrentToForgetWeights());
3345  armnn::ConstTensor recurrentToCellWeights = ToConstTensor(flatBufferInputParams->recurrentToCellWeights());
3346  armnn::ConstTensor recurrentToOutputWeights = ToConstTensor(flatBufferInputParams->recurrentToOutputWeights());
3347  armnn::ConstTensor forgetGateBias = ToConstTensor(flatBufferInputParams->forgetGateBias());
3348  armnn::ConstTensor cellBias = ToConstTensor(flatBufferInputParams->cellBias());
3349  armnn::ConstTensor outputGateBias = ToConstTensor(flatBufferInputParams->outputGateBias());
3350 
3351  lstmInputParams.m_InputToForgetWeights = &inputToForgetWeights;
3352  lstmInputParams.m_InputToCellWeights = &inputToCellWeights;
3353  lstmInputParams.m_InputToOutputWeights = &inputToOutputWeights;
3354  lstmInputParams.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
3355  lstmInputParams.m_RecurrentToCellWeights = &recurrentToCellWeights;
3356  lstmInputParams.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
3357  lstmInputParams.m_ForgetGateBias = &forgetGateBias;
3358  lstmInputParams.m_CellBias = &cellBias;
3359  lstmInputParams.m_OutputGateBias = &outputGateBias;
3360 
3361  armnn::ConstTensor inputToInputWeights;
3362  armnn::ConstTensor recurrentToInputWeights;
3363  armnn::ConstTensor cellToInputWeights;
3364  armnn::ConstTensor inputGateBias;
3365  if (!lstmDescriptor.m_CifgEnabled)
3366  {
3367  inputToInputWeights = ToConstTensor(flatBufferInputParams->inputToInputWeights());
3368  recurrentToInputWeights = ToConstTensor(flatBufferInputParams->recurrentToInputWeights());
3369  cellToInputWeights = ToConstTensor(flatBufferInputParams->cellToInputWeights());
3370  inputGateBias = ToConstTensor(flatBufferInputParams->inputGateBias());
3371 
3372  lstmInputParams.m_InputToInputWeights = &inputToInputWeights;
3373  lstmInputParams.m_RecurrentToInputWeights = &recurrentToInputWeights;
3374  lstmInputParams.m_CellToInputWeights = &cellToInputWeights;
3375  lstmInputParams.m_InputGateBias = &inputGateBias;
3376  }
3377 
3378  armnn::ConstTensor projectionWeights;
3379  armnn::ConstTensor projectionBias;
3380  if (lstmDescriptor.m_ProjectionEnabled)
3381  {
3382  projectionWeights = ToConstTensor(flatBufferInputParams->projectionWeights());
3383  projectionBias = ToConstTensor(flatBufferInputParams->projectionBias());
3384 
3385  lstmInputParams.m_ProjectionWeights = &projectionWeights;
3386  lstmInputParams.m_ProjectionBias = &projectionBias;
3387  }
3388 
3389  armnn::ConstTensor cellToForgetWeights;
3390  armnn::ConstTensor cellToOutputWeights;
3391  if (lstmDescriptor.m_PeepholeEnabled)
3392  {
3393  cellToForgetWeights = ToConstTensor(flatBufferInputParams->cellToForgetWeights());
3394  cellToOutputWeights = ToConstTensor(flatBufferInputParams->cellToOutputWeights());
3395 
3396  lstmInputParams.m_CellToForgetWeights = &cellToForgetWeights;
3397  lstmInputParams.m_CellToOutputWeights = &cellToOutputWeights;
3398  }
3399 
3400  armnn::ConstTensor inputLayerNormWeights;
3401  armnn::ConstTensor forgetLayerNormWeights;
3402  armnn::ConstTensor cellLayerNormWeights;
3403  armnn::ConstTensor outputLayerNormWeights;
3404  if (lstmDescriptor.m_LayerNormEnabled)
3405  {
3406  if (!lstmDescriptor.m_CifgEnabled)
3407  {
3408  inputLayerNormWeights = ToConstTensor(flatBufferInputParams->inputLayerNormWeights());
3409  lstmInputParams.m_InputLayerNormWeights = &inputLayerNormWeights;
3410  }
3411  forgetLayerNormWeights = ToConstTensor(flatBufferInputParams->forgetLayerNormWeights());
3412  cellLayerNormWeights = ToConstTensor(flatBufferInputParams->cellLayerNormWeights());
3413  outputLayerNormWeights = ToConstTensor(flatBufferInputParams->outputLayerNormWeights());
3414 
3415  lstmInputParams.m_ForgetLayerNormWeights = &forgetLayerNormWeights;
3416  lstmInputParams.m_CellLayerNormWeights = &cellLayerNormWeights;
3417  lstmInputParams.m_OutputLayerNormWeights = &outputLayerNormWeights;
3418  }
3419 
3420  IConnectableLayer* layer = m_Network->AddLstmLayer(lstmDescriptor, lstmInputParams, layerName.c_str());
3421 
3422  armnn::TensorInfo outputTensorInfo1 = ToTensorInfo(outputs[0]);
3423  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo1);
3424 
3425  armnn::TensorInfo outputTensorInfo2 = ToTensorInfo(outputs[1]);
3426  layer->GetOutputSlot(1).SetTensorInfo(outputTensorInfo2);
3427 
3428  armnn::TensorInfo outputTensorInfo3 = ToTensorInfo(outputs[2]);
3429  layer->GetOutputSlot(2).SetTensorInfo(outputTensorInfo3);
3430 
3431  armnn::TensorInfo outputTensorInfo4 = ToTensorInfo(outputs[3]);
3432  layer->GetOutputSlot(3).SetTensorInfo(outputTensorInfo4);
3433 
3434  RegisterInputSlots(graph, layerIndex, layer);
3435  RegisterOutputSlots(graph, layerIndex, layer);
3436 }
3437 
3439 {
3441 
3442  desc.m_CifgEnabled = qLstmDescriptor->cifgEnabled();
3443  desc.m_PeepholeEnabled = qLstmDescriptor->peepholeEnabled();
3444  desc.m_ProjectionEnabled = qLstmDescriptor->projectionEnabled();
3445  desc.m_LayerNormEnabled = qLstmDescriptor->layerNormEnabled();
3446 
3447  desc.m_CellClip = qLstmDescriptor->cellClip();
3448  desc.m_ProjectionClip = qLstmDescriptor->projectionClip();
3449 
3450  desc.m_InputIntermediateScale = qLstmDescriptor->inputIntermediateScale();
3451  desc.m_ForgetIntermediateScale = qLstmDescriptor->forgetIntermediateScale();
3452  desc.m_CellIntermediateScale = qLstmDescriptor->cellIntermediateScale();
3453  desc.m_OutputIntermediateScale = qLstmDescriptor->outputIntermediateScale();
3454 
3455  desc.m_HiddenStateScale = qLstmDescriptor->hiddenStateScale();
3456  desc.m_HiddenStateZeroPoint = qLstmDescriptor->hiddenStateZeroPoint();
3457 
3458  return desc;
3459 }
3460 
3461 void IDeserializer::DeserializerImpl::ParseQLstm(GraphPtr graph, unsigned int layerIndex)
3462 {
3463  CHECK_LAYERS(graph, 0, layerIndex);
3464 
3465  auto inputs = GetInputs(graph, layerIndex);
3466  CHECK_VALID_SIZE(inputs.size(), 3);
3467 
3468  auto outputs = GetOutputs(graph, layerIndex);
3469  CHECK_VALID_SIZE(outputs.size(), 3);
3470 
3471  auto flatBufferLayer = graph->layers()->Get(layerIndex)->layer_as_QLstmLayer();
3472  auto layerName = GetLayerName(graph, layerIndex);
3473  auto flatBufferDescriptor = flatBufferLayer->descriptor();
3474  auto flatBufferInputParams = flatBufferLayer->inputParams();
3475 
3476  auto qLstmDescriptor = GetQLstmDescriptor(flatBufferDescriptor);
3477  armnn::LstmInputParams qLstmInputParams;
3478 
3479  // Mandatory params
3480  armnn::ConstTensor inputToForgetWeights = ToConstTensor(flatBufferInputParams->inputToForgetWeights());
3481  armnn::ConstTensor inputToCellWeights = ToConstTensor(flatBufferInputParams->inputToCellWeights());
3482  armnn::ConstTensor inputToOutputWeights = ToConstTensor(flatBufferInputParams->inputToOutputWeights());
3483  armnn::ConstTensor recurrentToForgetWeights = ToConstTensor(flatBufferInputParams->recurrentToForgetWeights());
3484  armnn::ConstTensor recurrentToCellWeights = ToConstTensor(flatBufferInputParams->recurrentToCellWeights());
3485  armnn::ConstTensor recurrentToOutputWeights = ToConstTensor(flatBufferInputParams->recurrentToOutputWeights());
3486  armnn::ConstTensor forgetGateBias = ToConstTensor(flatBufferInputParams->forgetGateBias());
3487  armnn::ConstTensor cellBias = ToConstTensor(flatBufferInputParams->cellBias());
3488  armnn::ConstTensor outputGateBias = ToConstTensor(flatBufferInputParams->outputGateBias());
3489 
3490  qLstmInputParams.m_InputToForgetWeights = &inputToForgetWeights;
3491  qLstmInputParams.m_InputToCellWeights = &inputToCellWeights;
3492  qLstmInputParams.m_InputToOutputWeights = &inputToOutputWeights;
3493  qLstmInputParams.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
3494  qLstmInputParams.m_RecurrentToCellWeights = &recurrentToCellWeights;
3495  qLstmInputParams.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
3496  qLstmInputParams.m_ForgetGateBias = &forgetGateBias;
3497  qLstmInputParams.m_CellBias = &cellBias;
3498  qLstmInputParams.m_OutputGateBias = &outputGateBias;
3499 
3500  // Optional CIFG params
3501  armnn::ConstTensor inputToInputWeights;
3502  armnn::ConstTensor recurrentToInputWeights;
3503  armnn::ConstTensor inputGateBias;
3504 
3505  if (!qLstmDescriptor.m_CifgEnabled)
3506  {
3507  inputToInputWeights = ToConstTensor(flatBufferInputParams->inputToInputWeights());
3508  recurrentToInputWeights = ToConstTensor(flatBufferInputParams->recurrentToInputWeights());
3509  inputGateBias = ToConstTensor(flatBufferInputParams->inputGateBias());
3510 
3511  qLstmInputParams.m_InputToInputWeights = &inputToInputWeights;
3512  qLstmInputParams.m_RecurrentToInputWeights = &recurrentToInputWeights;
3513  qLstmInputParams.m_InputGateBias = &inputGateBias;
3514  }
3515 
3516  // Optional projection params
3517  armnn::ConstTensor projectionWeights;
3518  armnn::ConstTensor projectionBias;
3519 
3520  if (qLstmDescriptor.m_ProjectionEnabled)
3521  {
3522  projectionWeights = ToConstTensor(flatBufferInputParams->projectionWeights());
3523  projectionBias = ToConstTensor(flatBufferInputParams->projectionBias());
3524 
3525  qLstmInputParams.m_ProjectionWeights = &projectionWeights;
3526  qLstmInputParams.m_ProjectionBias = &projectionBias;
3527  }
3528 
3529  // Optional peephole params
3530  armnn::ConstTensor cellToInputWeights;
3531  armnn::ConstTensor cellToForgetWeights;
3532  armnn::ConstTensor cellToOutputWeights;
3533 
3534  if (qLstmDescriptor.m_PeepholeEnabled)
3535  {
3536  if (!qLstmDescriptor.m_CifgEnabled)
3537  {
3538  cellToInputWeights = ToConstTensor(flatBufferInputParams->cellToInputWeights());
3539  qLstmInputParams.m_CellToInputWeights = &cellToInputWeights;
3540  }
3541 
3542  cellToForgetWeights = ToConstTensor(flatBufferInputParams->cellToForgetWeights());
3543  cellToOutputWeights = ToConstTensor(flatBufferInputParams->cellToOutputWeights());
3544 
3545  qLstmInputParams.m_CellToForgetWeights = &cellToForgetWeights;
3546  qLstmInputParams.m_CellToOutputWeights = &cellToOutputWeights;
3547  }
3548 
3549  // Optional layer norm params
3550  armnn::ConstTensor inputLayerNormWeights;
3551  armnn::ConstTensor forgetLayerNormWeights;
3552  armnn::ConstTensor cellLayerNormWeights;
3553  armnn::ConstTensor outputLayerNormWeights;
3554 
3555  if (qLstmDescriptor.m_LayerNormEnabled)
3556  {
3557  if (!qLstmDescriptor.m_CifgEnabled)
3558  {
3559  inputLayerNormWeights = ToConstTensor(flatBufferInputParams->inputLayerNormWeights());
3560  qLstmInputParams.m_InputLayerNormWeights = &inputLayerNormWeights;
3561  }
3562 
3563  forgetLayerNormWeights = ToConstTensor(flatBufferInputParams->forgetLayerNormWeights());
3564  cellLayerNormWeights = ToConstTensor(flatBufferInputParams->cellLayerNormWeights());
3565  outputLayerNormWeights = ToConstTensor(flatBufferInputParams->outputLayerNormWeights());
3566 
3567  qLstmInputParams.m_ForgetLayerNormWeights = &forgetLayerNormWeights;
3568  qLstmInputParams.m_CellLayerNormWeights = &cellLayerNormWeights;
3569  qLstmInputParams.m_OutputLayerNormWeights = &outputLayerNormWeights;
3570  }
3571 
3572  IConnectableLayer* layer = m_Network->AddQLstmLayer(qLstmDescriptor, qLstmInputParams, layerName.c_str());
3573 
3574  armnn::TensorInfo outputStateOutInfo = ToTensorInfo(outputs[0]);
3575  layer->GetOutputSlot(0).SetTensorInfo(outputStateOutInfo);
3576 
3577  armnn::TensorInfo cellStateOutInfo = ToTensorInfo(outputs[1]);
3578  layer->GetOutputSlot(1).SetTensorInfo(cellStateOutInfo);
3579 
3580  armnn::TensorInfo outputInfo = ToTensorInfo(outputs[2]);
3581  layer->GetOutputSlot(2).SetTensorInfo(outputInfo);
3582 
3583  RegisterInputSlots(graph, layerIndex, layer);
3584  RegisterOutputSlots(graph, layerIndex, layer);
3585 }
3586 
3587 void IDeserializer::DeserializerImpl::ParseQuantizedLstm(GraphPtr graph, unsigned int layerIndex)
3588 {
3589  CHECK_LAYERS(graph, 0, layerIndex);
3590 
3591  auto inputs = GetInputs(graph, layerIndex);
3592  CHECK_VALID_SIZE(inputs.size(), 3);
3593 
3594  auto outputs = GetOutputs(graph, layerIndex);
3595  CHECK_VALID_SIZE(outputs.size(), 2);
3596 
3597  auto flatBufferLayer = graph->layers()->Get(layerIndex)->layer_as_QuantizedLstmLayer();
3598  auto layerName = GetLayerName(graph, layerIndex);
3599  auto flatBufferInputParams = flatBufferLayer->inputParams();
3600 
3601  armnn::QuantizedLstmInputParams lstmInputParams;
3602 
3603  armnn::ConstTensor inputToInputWeights = ToConstTensor(flatBufferInputParams->inputToInputWeights());
3604  armnn::ConstTensor inputToForgetWeights = ToConstTensor(flatBufferInputParams->inputToForgetWeights());
3605  armnn::ConstTensor inputToCellWeights = ToConstTensor(flatBufferInputParams->inputToCellWeights());
3606  armnn::ConstTensor inputToOutputWeights = ToConstTensor(flatBufferInputParams->inputToOutputWeights());
3607  armnn::ConstTensor recurrentToInputWeights = ToConstTensor(flatBufferInputParams->recurrentToInputWeights());
3608  armnn::ConstTensor recurrentToForgetWeights = ToConstTensor(flatBufferInputParams->recurrentToForgetWeights());
3609  armnn::ConstTensor recurrentToCellWeights = ToConstTensor(flatBufferInputParams->recurrentToCellWeights());
3610  armnn::ConstTensor recurrentToOutputWeights = ToConstTensor(flatBufferInputParams->recurrentToOutputWeights());
3611  armnn::ConstTensor inputGateBias = ToConstTensor(flatBufferInputParams->inputGateBias());
3612  armnn::ConstTensor forgetGateBias = ToConstTensor(flatBufferInputParams->forgetGateBias());
3613  armnn::ConstTensor cellBias = ToConstTensor(flatBufferInputParams->cellBias());
3614  armnn::ConstTensor outputGateBias = ToConstTensor(flatBufferInputParams->outputGateBias());
3615 
3616  lstmInputParams.m_InputToInputWeights = &inputToInputWeights;
3617  lstmInputParams.m_InputToForgetWeights = &inputToForgetWeights;
3618  lstmInputParams.m_InputToCellWeights = &inputToCellWeights;
3619  lstmInputParams.m_InputToOutputWeights = &inputToOutputWeights;
3620  lstmInputParams.m_RecurrentToInputWeights = &recurrentToInputWeights;
3621  lstmInputParams.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
3622  lstmInputParams.m_RecurrentToCellWeights = &recurrentToCellWeights;
3623  lstmInputParams.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
3624  lstmInputParams.m_InputGateBias = &inputGateBias;
3625  lstmInputParams.m_ForgetGateBias = &forgetGateBias;
3626  lstmInputParams.m_CellBias = &cellBias;
3627  lstmInputParams.m_OutputGateBias = &outputGateBias;
3628 
3629  IConnectableLayer* layer = m_Network->AddQuantizedLstmLayer(lstmInputParams, layerName.c_str());
3630 
3631  armnn::TensorInfo outputTensorInfo1 = ToTensorInfo(outputs[0]);
3632  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo1);
3633 
3634  armnn::TensorInfo outputTensorInfo2 = ToTensorInfo(outputs[1]);
3635  layer->GetOutputSlot(1).SetTensorInfo(outputTensorInfo2);
3636 
3637  RegisterInputSlots(graph, layerIndex, layer);
3638  RegisterOutputSlots(graph, layerIndex, layer);
3639 }
3640 
3641 void IDeserializer::DeserializerImpl::ParseDequantize(GraphPtr graph, unsigned int layerIndex)
3642 {
3643  CHECK_LAYERS(graph, 0, layerIndex);
3644 
3645  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
3646  CHECK_VALID_SIZE(inputs.size(), 1);
3647 
3648  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
3649  CHECK_VALID_SIZE(outputs.size(), 1);
3650 
3651  const std::string layerName = GetLayerName(graph, layerIndex);
3652  IConnectableLayer* layer = m_Network->AddDequantizeLayer(layerName.c_str());
3653 
3654  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3655  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3656 
3657  RegisterInputSlots(graph, layerIndex, layer);
3658  RegisterOutputSlots(graph, layerIndex, layer);
3659 }
3660 
3661 void IDeserializer::DeserializerImpl::ParseMerge(GraphPtr graph, unsigned int layerIndex)
3662 {
3663  CHECK_LAYERS(graph, 0, layerIndex);
3664 
3665  TensorRawPtrVector inputs = GetInputs(graph, layerIndex);
3666  CHECK_VALID_SIZE(inputs.size(), 2);
3667 
3668  TensorRawPtrVector outputs = GetOutputs(graph, layerIndex);
3669  CHECK_VALID_SIZE(outputs.size(), 1);
3670 
3671  const std::string layerName = GetLayerName(graph, layerIndex);
3672  IConnectableLayer* layer = m_Network->AddMergeLayer(layerName.c_str());
3673 
3674  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3675  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3676 
3677  RegisterInputSlots(graph, layerIndex, layer);
3678  RegisterOutputSlots(graph, layerIndex, layer);
3679 }
3680 
3681 void IDeserializer::DeserializerImpl::ParseSwitch(GraphPtr graph, unsigned int layerIndex)
3682 {
3683  CHECK_LAYERS(graph, 0, layerIndex);
3684  auto inputs = GetInputs(graph, layerIndex);
3685  CHECK_LOCATION();
3686  CHECK_VALID_SIZE(inputs.size(), 2);
3687 
3688  auto outputs = GetOutputs(graph, layerIndex);
3689  CHECK_VALID_SIZE(outputs.size(), 2);
3690 
3691  auto layerName = GetLayerName(graph, layerIndex);
3692  IConnectableLayer* layer = m_Network->AddSwitchLayer(layerName.c_str());
3693 
3694  armnn::TensorInfo output0TensorInfo = ToTensorInfo(outputs[0]);
3695  layer->GetOutputSlot(0).SetTensorInfo(output0TensorInfo);
3696 
3697  armnn::TensorInfo output1TensorInfo = ToTensorInfo(outputs[1]);
3698  layer->GetOutputSlot(1).SetTensorInfo(output1TensorInfo);
3699 
3700  RegisterInputSlots(graph, layerIndex, layer);
3701  RegisterOutputSlots(graph, layerIndex, layer);
3702 }
3703 
3704 void IDeserializer::DeserializerImpl::ParseTile(GraphPtr graph, unsigned int layerIndex)
3705 {
3706  CHECK_LAYERS(graph, 0, layerIndex);
3707  auto inputs = GetInputs(graph, layerIndex);
3708  CHECK_LOCATION();
3709  CHECK_VALID_SIZE(inputs.size(), 1);
3710 
3711  auto outputs = GetOutputs(graph, layerIndex);
3712  CHECK_VALID_SIZE(outputs.size(), 1);
3713 
3714  auto TileLayer = graph->layers()->Get(layerIndex)->layer_as_TileLayer();
3715  auto layerName = GetLayerName(graph, layerIndex);
3716  auto flatBufferDescriptor = TileLayer->descriptor();
3717  auto flatBufferMultiples = flatBufferDescriptor->m_Multiples();
3718 
3719  armnn::TileDescriptor tileDescriptor;
3720  tileDescriptor.m_Multiples = std::vector<unsigned int>(flatBufferMultiples->begin(), flatBufferMultiples->end());
3721 
3722  IConnectableLayer* layer = m_Network->AddTileLayer(tileDescriptor, layerName.c_str());
3723 
3724  armnn::TensorInfo output0TensorInfo = ToTensorInfo(outputs[0]);
3725  layer->GetOutputSlot(0).SetTensorInfo(output0TensorInfo);
3726 
3727  RegisterInputSlots(graph, layerIndex, layer);
3728  RegisterOutputSlots(graph, layerIndex, layer);
3729 }
3730 
3731 void IDeserializer::DeserializerImpl::ParsePrelu(GraphPtr graph, unsigned int layerIndex)
3732 {
3733  CHECK_LAYERS(graph, 0, layerIndex);
3734  auto inputs = GetInputs(graph, layerIndex);
3735  CHECK_LOCATION();
3736  CHECK_VALID_SIZE(inputs.size(), 2);
3737 
3738  auto outputs = GetOutputs(graph, layerIndex);
3739  CHECK_VALID_SIZE(outputs.size(), 1);
3740 
3741  auto layerName = GetLayerName(graph, layerIndex);
3742  IConnectableLayer* layer = m_Network->AddPreluLayer(layerName.c_str());
3743 
3744  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3745  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3746 
3747  RegisterInputSlots(graph, layerIndex, layer);
3748  RegisterOutputSlots(graph, layerIndex, layer);
3749 }
3750 
3751 void IDeserializer::DeserializerImpl::ParseTranspose(GraphPtr graph, unsigned int layerIndex)
3752 {
3753  CHECK_LAYERS(graph, 0, layerIndex);
3754 
3755  auto dimsMapping = graph->layers()->Get(layerIndex)->layer_as_TransposeLayer()->descriptor()->dimMappings();
3756 
3757  auto inputs = GetInputs(graph, layerIndex);
3758  CHECK_VALID_SIZE(inputs.size(), 1);
3759 
3760  auto outputs = GetOutputs(graph, layerIndex);
3761  CHECK_VALID_SIZE(outputs.size(), 1);
3762  auto outputInfo = ToTensorInfo(outputs[0]);
3763 
3764  auto layerName = GetLayerName(graph, layerIndex);
3765  const armnn::TransposeDescriptor descriptor(armnn::PermutationVector(dimsMapping->data(), dimsMapping->size()));
3766 
3767  IConnectableLayer* layer = m_Network->AddTransposeLayer(descriptor, layerName.c_str());
3768  layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
3769 
3770  RegisterInputSlots(graph, layerIndex, layer);
3771  RegisterOutputSlots(graph, layerIndex, layer);
3772 }
3773 
3774 void IDeserializer::DeserializerImpl::ParseTransposeConvolution2d(GraphPtr graph, unsigned int layerIndex)
3775 {
3776  CHECK_LAYERS(graph, 0, layerIndex);
3777 
3778  auto inputs = GetInputs(graph, layerIndex);
3779  CHECK_VALID_SIZE(inputs.size(), 1);
3780 
3781  auto outputs = GetOutputs(graph, layerIndex);
3782  CHECK_VALID_SIZE(outputs.size(), 1);
3783 
3784  auto serializerLayer = graph->layers()->Get(layerIndex)->layer_as_TransposeConvolution2dLayer();
3785  auto layerName = GetLayerName(graph, layerIndex);
3786  auto serializerDescriptor = serializerLayer->descriptor();
3787 
3789  descriptor.m_PadLeft = serializerDescriptor->padLeft();
3790  descriptor.m_PadRight = serializerDescriptor->padRight();
3791  descriptor.m_PadTop = serializerDescriptor->padTop();
3792  descriptor.m_PadBottom = serializerDescriptor->padBottom();
3793  descriptor.m_StrideX = serializerDescriptor->strideX();
3794  descriptor.m_StrideY = serializerDescriptor->strideY();;
3795  descriptor.m_BiasEnabled = serializerDescriptor->biasEnabled();;
3796  descriptor.m_DataLayout = ToDataLayout(serializerDescriptor->dataLayout());
3797 
3798  // weights & biases
3799  armnn::ConstTensor weights = ToConstTensor(serializerLayer->weights());
3800  armnn::Optional<armnn::ConstTensor> optionalBiases;
3801  if (descriptor.m_BiasEnabled)
3802  {
3803  armnn::ConstTensor biases = ToConstTensor(serializerLayer->biases());
3804  optionalBiases = armnn::MakeOptional<armnn::ConstTensor>(biases);
3805  }
3806 
3807  IConnectableLayer* layer = m_Network->AddTransposeConvolution2dLayer(descriptor,
3808  weights,
3809  optionalBiases,
3810  layerName.c_str());
3811 
3812  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3813  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3814 
3815  RegisterInputSlots(graph, layerIndex, layer);
3816  RegisterOutputSlots(graph, layerIndex, layer);
3817 }
3818 
3819 void IDeserializer::DeserializerImpl::ParseStack(GraphPtr graph, unsigned int layerIndex)
3820 {
3821  CHECK_LAYERS(graph, 0, layerIndex);
3822  auto inputs = GetInputs(graph, layerIndex);
3823 
3824  auto outputs = GetOutputs(graph, layerIndex);
3825  CHECK_VALID_SIZE(outputs.size(), 1);
3826 
3827  auto flatBufferDescriptor = graph->layers()->Get(layerIndex)->layer_as_StackLayer()->descriptor();
3828  unsigned int axis = flatBufferDescriptor->axis();
3829  unsigned int numInputs = flatBufferDescriptor->numInputs();
3830  CHECK_VALID_SIZE(inputs.size(), numInputs);
3831 
3832  auto flatBufferInputShape = flatBufferDescriptor->inputShape();
3833  std::vector<uint32_t> vectorInputShape(flatBufferInputShape->begin(),
3834  flatBufferInputShape->begin() + flatBufferInputShape->size());
3835 
3836  TensorShape inputShape(static_cast<unsigned int>(vectorInputShape.size()), vectorInputShape.data());
3837  armnn::StackDescriptor descriptor(axis, numInputs, inputShape);
3838 
3839  for (unsigned int i=0; i<inputs.size(); ++i)
3840  {
3841  armnn::TensorShape inputShape = ToTensorInfo(inputs[i]).GetShape();
3842  if (descriptor.m_InputShape != inputShape)
3843  {
3844  std::stringstream ss;
3845  ss << "Shape of input "
3846  << i
3847  << " "
3848  << inputShape
3849  << " does not equal defined input shape "
3850  << descriptor.m_InputShape
3851  << ": "
3852  << CHECK_LOCATION().AsString();
3853  throw ParseException(ss.str());
3854  }
3855  }
3856 
3857  auto layerName = GetLayerName(graph, layerIndex);
3858  IConnectableLayer* layer = m_Network->AddStackLayer(descriptor, layerName.c_str());
3859 
3860  armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
3861  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
3862 
3863  RegisterInputSlots(graph, layerIndex, layer);
3864  RegisterOutputSlots(graph, layerIndex, layer);
3865 }
3866 
3867 void IDeserializer::DeserializerImpl::ParseStandIn(GraphPtr graph, unsigned int layerIndex)
3868 {
3869  CHECK_LAYERS(graph, 0, layerIndex);
3870 
3871  auto inputs = GetInputs(graph, layerIndex);
3872  auto outputs = GetOutputs(graph, layerIndex);
3873 
3874  auto fbLayer = graph->layers()->Get(layerIndex)->layer_as_StandInLayer();
3875  auto fbDescriptor = fbLayer->descriptor();
3876 
3877  armnn::StandInDescriptor descriptor;
3878  descriptor.m_NumInputs = fbDescriptor->numInputs();
3879  descriptor.m_NumOutputs = fbDescriptor->numOutputs();
3880 
3881  CHECK_VALID_SIZE(inputs.size(), descriptor.m_NumInputs);
3882  CHECK_VALID_SIZE(outputs.size(), descriptor.m_NumOutputs);
3883 
3884  const std::string layerName = GetLayerName(graph, layerIndex);
3885  armnn::IConnectableLayer* layer = m_Network->AddStandInLayer(descriptor, layerName.c_str());
3886 
3887  for (unsigned int i = 0u; i < descriptor.m_NumOutputs; ++i)
3888  {
3889  armnn::TensorInfo outputInfo = ToTensorInfo(outputs[i]);
3890  layer->GetOutputSlot(i).SetTensorInfo(outputInfo);
3891  }
3892 
3893  RegisterInputSlots(graph, layerIndex, layer);
3894  RegisterOutputSlots(graph, layerIndex, layer);
3895 }
3896 
3899 {
3901 
3902  desc.m_ActivationFunc = descriptor->activationFunc();
3903  desc.m_ClippingThresCell = descriptor->clippingThresCell();
3904  desc.m_ClippingThresProj = descriptor->clippingThresProj();
3905  desc.m_CifgEnabled = descriptor->cifgEnabled();
3906  desc.m_PeepholeEnabled = descriptor->peepholeEnabled();
3907  desc.m_ProjectionEnabled = descriptor->projectionEnabled();
3908  desc.m_LayerNormEnabled = descriptor->layerNormEnabled();
3909  desc.m_TimeMajor = descriptor->timeMajor();
3910 
3911  return desc;
3912 }
3913 
3914 void IDeserializer::DeserializerImpl::ParseUnidirectionalSequenceLstm(GraphPtr graph, unsigned int layerIndex)
3915 {
3916  CHECK_LAYERS(graph, 0, layerIndex);
3917 
3918  auto inputs = GetInputs(graph, layerIndex);
3919  CHECK_VALID_SIZE(inputs.size(), 3);
3920 
3921  auto outputs = GetOutputs(graph, layerIndex);
3922  CHECK_VALID_SIZE(outputs.size(), 3);
3923 
3924  auto flatBufferLayer = graph->layers()->Get(layerIndex)->layer_as_UnidirectionalSequenceLstmLayer();
3925  auto layerName = GetLayerName(graph, layerIndex);
3926  auto flatBufferDescriptor = flatBufferLayer->descriptor();
3927  auto flatBufferInputParams = flatBufferLayer->inputParams();
3928 
3929  auto descriptor = GetUnidirectionalSequenceLstmDescriptor(flatBufferDescriptor);
3930 
3931  armnn::LstmInputParams lstmInputParams;
3932 
3933  armnn::ConstTensor inputToForgetWeights = ToConstTensor(flatBufferInputParams->inputToForgetWeights());
3934  armnn::ConstTensor inputToCellWeights = ToConstTensor(flatBufferInputParams->inputToCellWeights());
3935  armnn::ConstTensor inputToOutputWeights = ToConstTensor(flatBufferInputParams->inputToOutputWeights());
3936  armnn::ConstTensor recurrentToForgetWeights = ToConstTensor(flatBufferInputParams->recurrentToForgetWeights());
3937  armnn::ConstTensor recurrentToCellWeights = ToConstTensor(flatBufferInputParams->recurrentToCellWeights());
3938  armnn::ConstTensor recurrentToOutputWeights = ToConstTensor(flatBufferInputParams->recurrentToOutputWeights());
3939  armnn::ConstTensor forgetGateBias = ToConstTensor(flatBufferInputParams->forgetGateBias());
3940  armnn::ConstTensor cellBias = ToConstTensor(flatBufferInputParams->cellBias());
3941  armnn::ConstTensor outputGateBias = ToConstTensor(flatBufferInputParams->outputGateBias());
3942 
3943  lstmInputParams.m_InputToForgetWeights = &inputToForgetWeights;
3944  lstmInputParams.m_InputToCellWeights = &inputToCellWeights;
3945  lstmInputParams.m_InputToOutputWeights = &inputToOutputWeights;
3946  lstmInputParams.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
3947  lstmInputParams.m_RecurrentToCellWeights = &recurrentToCellWeights;
3948  lstmInputParams.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
3949  lstmInputParams.m_ForgetGateBias = &forgetGateBias;
3950  lstmInputParams.m_CellBias = &cellBias;
3951  lstmInputParams.m_OutputGateBias = &outputGateBias;
3952 
3953  armnn::ConstTensor inputToInputWeights;
3954  armnn::ConstTensor recurrentToInputWeights;
3955  armnn::ConstTensor cellToInputWeights;
3956  armnn::ConstTensor inputGateBias;
3957  if (!descriptor.m_CifgEnabled)
3958  {
3959  inputToInputWeights = ToConstTensor(flatBufferInputParams->inputToInputWeights());
3960  recurrentToInputWeights = ToConstTensor(flatBufferInputParams->recurrentToInputWeights());
3961  inputGateBias = ToConstTensor(flatBufferInputParams->inputGateBias());
3962 
3963  lstmInputParams.m_InputToInputWeights = &inputToInputWeights;
3964  lstmInputParams.m_RecurrentToInputWeights = &recurrentToInputWeights;
3965  lstmInputParams.m_InputGateBias = &inputGateBias;
3966 
3967  if (descriptor.m_PeepholeEnabled)
3968  {
3969  cellToInputWeights = ToConstTensor(flatBufferInputParams->cellToInputWeights());
3970  lstmInputParams.m_CellToInputWeights = &cellToInputWeights;
3971  }
3972  }
3973 
3974  armnn::ConstTensor projectionWeights;
3975  armnn::ConstTensor projectionBias;
3976  if (descriptor.m_ProjectionEnabled)
3977  {
3978  projectionWeights = ToConstTensor(flatBufferInputParams->projectionWeights());
3979  projectionBias = ToConstTensor(flatBufferInputParams->projectionBias());
3980 
3981  lstmInputParams.m_ProjectionWeights = &projectionWeights;
3982  lstmInputParams.m_ProjectionBias = &projectionBias;
3983  }
3984 
3985  armnn::ConstTensor cellToForgetWeights;
3986  armnn::ConstTensor cellToOutputWeights;
3987  if (descriptor.m_PeepholeEnabled)
3988  {
3989  cellToForgetWeights = ToConstTensor(flatBufferInputParams->cellToForgetWeights());
3990  cellToOutputWeights = ToConstTensor(flatBufferInputParams->cellToOutputWeights());
3991 
3992  lstmInputParams.m_CellToForgetWeights = &cellToForgetWeights;
3993  lstmInputParams.m_CellToOutputWeights = &cellToOutputWeights;
3994  }
3995 
3996  armnn::ConstTensor inputLayerNormWeights;
3997  armnn::ConstTensor forgetLayerNormWeights;
3998  armnn::ConstTensor cellLayerNormWeights;
3999  armnn::ConstTensor outputLayerNormWeights;
4000  if (descriptor.m_LayerNormEnabled)
4001  {
4002  if (!descriptor.m_CifgEnabled)
4003  {
4004  inputLayerNormWeights = ToConstTensor(flatBufferInputParams->inputLayerNormWeights());
4005  lstmInputParams.m_InputLayerNormWeights = &inputLayerNormWeights;
4006  }
4007  forgetLayerNormWeights = ToConstTensor(flatBufferInputParams->forgetLayerNormWeights());
4008  cellLayerNormWeights = ToConstTensor(flatBufferInputParams->cellLayerNormWeights());
4009  outputLayerNormWeights = ToConstTensor(flatBufferInputParams->outputLayerNormWeights());
4010 
4011  lstmInputParams.m_ForgetLayerNormWeights = &forgetLayerNormWeights;
4012  lstmInputParams.m_CellLayerNormWeights = &cellLayerNormWeights;
4013  lstmInputParams.m_OutputLayerNormWeights = &outputLayerNormWeights;
4014  }
4015 
4016  IConnectableLayer* layer = m_Network->AddUnidirectionalSequenceLstmLayer(descriptor,
4017  lstmInputParams,
4018  layerName.c_str());
4019 
4020  armnn::TensorInfo outputTensorInfo0 = ToTensorInfo(outputs[0]);
4021  layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo0);
4022 
4023  armnn::TensorInfo outputTensorInfo1 = ToTensorInfo(outputs[1]);
4024  layer->GetOutputSlot(1).SetTensorInfo(outputTensorInfo1);
4025 
4026  armnn::TensorInfo outputTensorInfo2 = ToTensorInfo(outputs[2]);
4027  layer->GetOutputSlot(2).SetTensorInfo(outputTensorInfo2);
4028 
4029  RegisterInputSlots(graph, layerIndex, layer);
4030  RegisterOutputSlots(graph, layerIndex, layer);
4031 }
4032 
4033 void IDeserializer::DeserializerImpl::ParseScatterNd(GraphPtr graph, unsigned int layerIndex)
4034 {
4035  CHECK_LAYERS(graph, 0, layerIndex);
4036  auto inputs = GetInputs(graph, layerIndex);
4037  CHECK_LOCATION();
4038  CHECK_VALID_SIZE(inputs.size(), 3);
4039 
4040  auto outputs = GetOutputs(graph, layerIndex);
4041  CHECK_VALID_SIZE(outputs.size(), 1);
4042 
4043  auto ScatterNdLayer = graph->layers()->Get(layerIndex)->layer_as_ScatterNdLayer();
4044  auto layerName = GetLayerName(graph, layerIndex);
4045  auto flatBufferDescriptor = ScatterNdLayer->descriptor();
4046 
4047  armnn::ScatterNdDescriptor scatterNdDescriptor;
4048  scatterNdDescriptor.m_Function = ToScatterNdFunction(flatBufferDescriptor->m_Function());
4049  scatterNdDescriptor.m_InputEnabled = flatBufferDescriptor->m_InputEnabled();
4050  scatterNdDescriptor.m_Axis = flatBufferDescriptor->m_Axis();
4051  scatterNdDescriptor.m_AxisEnabled = flatBufferDescriptor->m_AxisEnabled();
4052 
4053  IConnectableLayer* layer = m_Network->AddScatterNdLayer(scatterNdDescriptor, layerName.c_str());
4054 
4055  armnn::TensorInfo output0TensorInfo = ToTensorInfo(outputs[0]);
4056  layer->GetOutputSlot(0).SetTensorInfo(output0TensorInfo);
4057 
4058  RegisterInputSlots(graph, layerIndex, layer);
4059  RegisterOutputSlots(graph, layerIndex, layer);
4060 }
4061 
4062 } // namespace armnnDeserializer
armnn::BatchNormalizationDescriptor
A BatchNormalizationDescriptor for the BatchNormalizationLayer.
Definition: Descriptors.hpp:828
armnn::Convolution2dDescriptor::m_PadTop
uint32_t m_PadTop
Padding top value in the height dimension.
Definition: Descriptors.hpp:570
armnnDeserializer::ToArgMinMaxFunction
armnn::ArgMinMaxFunction ToArgMinMaxFunction(armnnSerializer::ArgMinMaxFunction function)
Definition: Deserializer.cpp:515
armnn::ArgMinMaxFunction::Max
@ Max
armnn::INetworkPtr
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
Definition: INetwork.hpp:339
armnn::InstanceNormalizationDescriptor::m_Beta
float m_Beta
Beta, the offset scalar value applied for the normalized tensor. Defaults to 1.0.
Definition: Descriptors.hpp:867
armnn::PaddingMode::Symmetric
@ Symmetric
armnn::SliceDescriptor::m_Begin
std::vector< unsigned int > m_Begin
Beginning indices of the slice in each dimension.
Definition: Descriptors.hpp:1244
armnn::BindingPointInfo
std::pair< armnn::LayerBindingId, armnn::TensorInfo > BindingPointInfo
Definition: Tensor.hpp:276
armnn::Convolution3dDescriptor::GetNumInputs
uint32_t GetNumInputs() const
Get the number of views/inputs.
Definition: Descriptors.cpp:465
armnn::LstmInputParams::m_RecurrentToForgetWeights
const ConstTensor * m_RecurrentToForgetWeights
Definition: LstmParams.hpp:45
armnnDeserializer::ToResizeMethod
armnn::ResizeMethod ToResizeMethod(armnnSerializer::ResizeMethod method)
Definition: Deserializer.cpp:663
armnn::ChannelShuffleDescriptor::m_Axis
uint32_t m_Axis
Axis to apply channel shuffle operation on.
Definition: Descriptors.hpp:1580
armnn::BinaryOperation::Mul
@ Mul
armnn::DataType::Boolean
@ Boolean
armnn::FullyConnectedDescriptor::m_ConstantWeights
bool m_ConstantWeights
Enable/disable constant weights and biases.
Definition: Descriptors.hpp:530
armnn::Pooling2dDescriptor::m_PaddingMethod
PaddingMethod m_PaddingMethod
The padding method to be used. (Exclude, IgnoreValue).
Definition: Descriptors.hpp:425
armnn::ViewsDescriptor
A ViewsDescriptor for the SplitterLayer.
Definition: Descriptors.hpp:244
armnn::TensorInfo::GetNumElements
unsigned int GetNumElements() const
Definition: Tensor.hpp:198
armnn::LstmInputParams::m_OutputLayerNormWeights
const ConstTensor * m_OutputLayerNormWeights
Definition: LstmParams.hpp:60
armnn::DetectionPostProcessDescriptor::m_NmsScoreThreshold
float m_NmsScoreThreshold
NMS score threshold.
Definition: Descriptors.hpp:751
armnn::QLstmDescriptor::m_ForgetIntermediateScale
float m_ForgetIntermediateScale
Forget intermediate quantization scale.
Definition: Descriptors.hpp:1428
armnn::ActivationDescriptor
An ActivationDescriptor for the ActivationLayer.
Definition: Descriptors.hpp:36
armnn::TransposeConvolution2dDescriptor::m_PadLeft
uint32_t m_PadLeft
Padding left value in the width dimension.
Definition: Descriptors.hpp:1469
armnnDeserializer::TensorRawPtr
const armnnSerializer::TensorInfo * TensorRawPtr
Definition: Deserializer.hpp:20
armnn::NormalizationAlgorithmChannel::Within
@ Within
armnn::FullyConnectedDescriptor
A FullyConnectedDescriptor for the FullyConnectedLayer.
Definition: Descriptors.hpp:507
armnn::BinaryOperation::Add
@ Add
armnn::DetectionPostProcessDescriptor::m_ScaleX
float m_ScaleX
Center size encoding scale x.
Definition: Descriptors.hpp:759
armnnDeserializer::ToPaddingMode
armnn::PaddingMode ToPaddingMode(armnnSerializer::PaddingMode paddingMode)
Definition: Deserializer.cpp:650
armnn::BaseTensor::GetMemoryArea
MemoryType GetMemoryArea() const
Definition: Tensor.hpp:307
armnn::ComparisonOperation::LessOrEqual
@ LessOrEqual
armnnDeserializer::IDeserializer::DeserializerImpl::GetBindingLayerInfo
static int32_t GetBindingLayerInfo(const GraphPtr &graphPtr, unsigned int layerIndex)
Definition: Deserializer.cpp:451
armnnDeserializer::CheckShape
bool CheckShape(const armnn::TensorShape &actual, const std::vector< uint32_t > &expected)
Definition: Deserializer.cpp:188
armnn::QLstmDescriptor
A QLstmDescriptor for the QLstmLayer.
Definition: Descriptors.hpp:1380
armnn::ScatterNdFunction::Min
@ Min
armnn::TensorInfo::GetNumBytes
unsigned int GetNumBytes() const
Definition: Tensor.cpp:427
armnn::TransposeConvolution2dDescriptor::m_StrideX
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
Definition: Descriptors.hpp:1477
armnn::Optional
Definition: Optional.hpp:270
armnn::DataLayout::NCDHW
@ NCDHW
armnn::IConnectableLayer::GetNumInputSlots
virtual unsigned int GetNumInputSlots() const =0
Returns the number of connectable input slots.
armnn::ActivationFunction::LeakyReLu
@ LeakyReLu
armnn::QLstmDescriptor::m_ProjectionEnabled
bool m_ProjectionEnabled
Enable/disable the projection layer.
Definition: Descriptors.hpp:1422
armnn::Pooling3dDescriptor::m_OutputShapeRounding
OutputShapeRounding m_OutputShapeRounding
The rounding method for the output shape. (Floor, Ceiling).
Definition: Descriptors.hpp:499
armnn::ResizeDescriptor::m_HalfPixelCenters
bool m_HalfPixelCenters
Half Pixel Centers.
Definition: Descriptors.hpp:1018
armnn::LstmDescriptor::m_TimeMajor
bool m_TimeMajor
Enable/disable time major.
Definition: Descriptors.hpp:1154
armnnDeserializer::IDeserializerPtr
std::unique_ptr< IDeserializer, void(*)(IDeserializer *parser)> IDeserializerPtr
Definition: IDeserializer.hpp:25
armnn::BatchNormalizationDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:843
armnn::ResizeMethod
ResizeMethod
Definition: Types.hpp:166
armnn::DataLayout
DataLayout
Definition: Types.hpp:62
armnn::Pooling3dDescriptor::m_PadTop
uint32_t m_PadTop
Padding top value in the height dimension.
Definition: Descriptors.hpp:479
armnnDeserializer::IDeserializer::DeserializerImpl::GetInputs
static TensorRawPtrVector GetInputs(const GraphPtr &graph, unsigned int layerIndex)
Definition: Deserializer.cpp:825
Descriptors.hpp
armnn::SpaceToBatchNdDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:1071
armnnDeserializer
Definition: IDeserializer.hpp:16
armnnDeserializer::ToLogicalBinaryOperation
armnn::LogicalBinaryOperation ToLogicalBinaryOperation(armnnSerializer::LogicalBinaryOperation operation)
Definition: Deserializer.cpp:585
armnn::FullyConnectedDescriptor::m_TransposeWeightMatrix
bool m_TransposeWeightMatrix
Enable/disable transpose weight matrix.
Definition: Descriptors.hpp:528
armnn::ResizeDescriptor::m_TargetHeight
uint32_t m_TargetHeight
Target height value.
Definition: Descriptors.hpp:1009
armnn::DepthwiseConvolution2dDescriptor::m_BiasEnabled
bool m_BiasEnabled
Enable/disable bias.
Definition: Descriptors.hpp:708
armnn::Pooling2dDescriptor::m_PoolHeight
uint32_t m_PoolHeight
Pooling height value.
Definition: Descriptors.hpp:417
armnn::LstmInputParams::m_ProjectionBias
const ConstTensor * m_ProjectionBias
Definition: LstmParams.hpp:56
armnn::ScatterNdFunction::Sub
@ Sub
armnn::DetectionPostProcessDescriptor::m_ScaleY
float m_ScaleY
Center size encoding scale y.
Definition: Descriptors.hpp:761
armnn::Pooling3dDescriptor
A Pooling3dDescriptor for the Pooling3dLayer.
Definition: Descriptors.hpp:431
armnn::DetectionPostProcessDescriptor::m_MaxDetections
uint32_t m_MaxDetections
Maximum numbers of detections.
Definition: Descriptors.hpp:745
armnn::LstmInputParams::m_RecurrentToCellWeights
const ConstTensor * m_RecurrentToCellWeights
Definition: LstmParams.hpp:46
armnn::DataLayout::NHWC
@ NHWC
armnn::QuantizedLstmInputParams::m_InputToOutputWeights
const ConstTensor * m_InputToOutputWeights
Definition: QuantizedLstmParams.hpp:36
armnn::LstmInputParams::m_CellBias
const ConstTensor * m_CellBias
Definition: LstmParams.hpp:53
armnn::Convolution3dDescriptor::m_PadFront
uint32_t m_PadFront
Padding front value in the depth dimension.
Definition: Descriptors.hpp:637
armnn::ResizeDescriptor
A ResizeDescriptor for the ResizeLayer.
Definition: Descriptors.hpp:985
armnn::ArgMinMaxDescriptor
An ArgMinMaxDescriptor for ArgMinMaxLayer.
Definition: Descriptors.hpp:67
armnnDeserializer::LstmDescriptorPtr
const armnnSerializer::LstmDescriptor * LstmDescriptorPtr
Definition: Deserializer.hpp:24
armnn::ActivationDescriptor::m_A
float m_A
Alpha upper bound value used by the activation functions. (BoundedReLu, Linear, TanH,...
Definition: Descriptors.hpp:61
armnn::InstanceNormalizationDescriptor
An InstanceNormalizationDescriptor for InstanceNormalizationLayer.
Definition: Descriptors.hpp:847
armnn::CheckLocation::m_Function
const char * m_Function
Definition: Exceptions.hpp:16
armnn::SoftmaxDescriptor::m_Beta
float m_Beta
Exponentiation value.
Definition: Descriptors.hpp:190
armnnDeserializer::IDeserializer::DeserializerImpl::CreateNetworkFromBinary
armnn::INetworkPtr CreateNetworkFromBinary(const std::vector< uint8_t > &binaryContent)
Create an input network from binary file contents.
Definition: Deserializer.cpp:876
armnn::GatherDescriptor
A GatherDescriptor for the GatherLayer.
Definition: Descriptors.hpp:965
TypesUtils.hpp
armnn::DepthwiseConvolution2dDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:710
armnn::ActivationFunction::Sqrt
@ Sqrt
armnn::ScatterNdDescriptor::m_InputEnabled
bool m_InputEnabled
Flag to show if input tensor is accepted.
Definition: Descriptors.hpp:1722
armnn::L2NormalizationDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:824
armnn::TensorInfo
Definition: Tensor.hpp:152
armnn::L2NormalizationDescriptor
A L2NormalizationDescriptor for the L2NormalizationLayer.
Definition: Descriptors.hpp:809
armnn::NormalizationAlgorithmMethod::LocalBrightness
@ LocalBrightness
Krichevsky 2012: Local Brightness Normalization.
armnn::NormalizationDescriptor::m_Beta
float m_Beta
Beta value for the normalization equation.
Definition: Descriptors.hpp:801
armnn::BinaryOperation::Sub
@ Sub
armnn::NormalizationDescriptor
A NormalizationDescriptor for the NormalizationLayer.
Definition: Descriptors.hpp:769
armnn::OutputShapeRounding::Floor
@ Floor
armnn::Pooling2dDescriptor::m_StrideY
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
Definition: Descriptors.hpp:421
armnn::BatchToSpaceNdDescriptor::m_BlockShape
std::vector< unsigned int > m_BlockShape
Block shape values.
Definition: Descriptors.hpp:898
CHECK_LOCATION
#define CHECK_LOCATION()
Definition: Exceptions.hpp:203
armnn::ChannelShuffleDescriptor
A ChannelShuffleDescriptor for the ChannelShuffle operator.
Definition: Descriptors.hpp:1562
Deserializer.hpp
armnn::DataType::Float32
@ Float32
armnn::ResizeDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:1014
armnn::ActivationFunction::TanH
@ TanH
armnn::QuantizedLstmInputParams::m_RecurrentToInputWeights
const ConstTensor * m_RecurrentToInputWeights
Definition: QuantizedLstmParams.hpp:38
armnnDeserializer::BindingPointInfo
Definition: IDeserializer.hpp:18
armnn::DepthwiseConvolution2dDescriptor::m_PadLeft
uint32_t m_PadLeft
Padding left value in the width dimension.
Definition: Descriptors.hpp:692
armnn::Convolution2dDescriptor::m_StrideY
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
Definition: Descriptors.hpp:576
armnn::QuantizedLstmInputParams::m_RecurrentToForgetWeights
const ConstTensor * m_RecurrentToForgetWeights
Definition: QuantizedLstmParams.hpp:39
armnn::LogicalBinaryOperation::LogicalOr
@ LogicalOr
armnn::Pooling2dDescriptor::m_PadTop
uint32_t m_PadTop
Padding top value in the height dimension.
Definition: Descriptors.hpp:411
armnn::Convolution3dDescriptor::m_PadTop
uint32_t m_PadTop
Padding top value in the height dimension.
Definition: Descriptors.hpp:633
CHECK_LAYERS
#define CHECK_LAYERS(GRAPH, LAYERS_INDEX, LAYER_INDEX)
Definition: Deserializer.cpp:181
armnnSerializer
Definition: ISerializer.hpp:11
armnn::ArgMinMaxDescriptor::m_Function
ArgMinMaxFunction m_Function
Specify if the function is to find Min or Max.
Definition: Descriptors.hpp:81
armnn::PoolingAlgorithm::L2
@ L2
armnn::SpaceToBatchNdDescriptor::m_BlockShape
std::vector< unsigned int > m_BlockShape
Block shape value.
Definition: Descriptors.hpp:1066
armnn::LstmInputParams::m_CellToOutputWeights
const ConstTensor * m_CellToOutputWeights
Definition: LstmParams.hpp:50
armnn::Convolution3dDescriptor::m_DilationX
uint32_t m_DilationX
Dilation along x axis.
Definition: Descriptors.hpp:647
armnn::PaddingMode
PaddingMode
The padding mode controls whether the padding should be filled with constant values (Constant),...
Definition: Types.hpp:200
CHECK_CONST_TENSOR_PTR
#define CHECK_CONST_TENSOR_PTR(TENSOR_PTR)
Definition: Deserializer.cpp:178
armnn::LstmInputParams::m_InputToCellWeights
const ConstTensor * m_InputToCellWeights
Definition: LstmParams.hpp:42
armnn::Convolution3dDescriptor::m_PadBottom
uint32_t m_PadBottom
Padding bottom value in the height dimension.
Definition: Descriptors.hpp:635
armnn::MaxNumOfTensorDimensions
constexpr unsigned int MaxNumOfTensorDimensions
Definition: Types.hpp:31
armnn::DataType::QAsymmU8
@ QAsymmU8
armnn::QLstmDescriptor::m_InputIntermediateScale
float m_InputIntermediateScale
Input intermediate quantization scale.
Definition: Descriptors.hpp:1426
armnn::ArgMinMaxFunction
ArgMinMaxFunction
Definition: Types.hpp:103
armnn::DetectionPostProcessDescriptor::m_ScaleW
float m_ScaleW
Center size encoding scale weight.
Definition: Descriptors.hpp:763
armnn::ActivationFunction::BoundedReLu
@ BoundedReLu
min(a, max(b, input)) ReLu1 & ReLu6.
armnn::DataType::QSymmS8
@ QSymmS8
armnn::QuantizedLstmInputParams::m_ForgetGateBias
const ConstTensor * m_ForgetGateBias
Definition: QuantizedLstmParams.hpp:44
armnn::StackDescriptor
A StackDescriptor for the StackLayer.
Definition: Descriptors.hpp:1251
armnnUtils::Permute
void Permute(const armnn::TensorShape &dstShape, const armnn::PermutationVector &mappings, const void *src, void *dst, size_t dataTypeSize)
Definition: Permute.cpp:164
armnn::QuantizedLstmInputParams::m_RecurrentToCellWeights
const ConstTensor * m_RecurrentToCellWeights
Definition: QuantizedLstmParams.hpp:40
IgnoreUnused.hpp
armnn::Pooling3dDescriptor::m_StrideZ
uint32_t m_StrideZ
Stride value when proceeding through input for the depth dimension.
Definition: Descriptors.hpp:497
armnn::NormalizationDescriptor::m_NormSize
uint32_t m_NormSize
Depth radius value.
Definition: Descriptors.hpp:797
armnnUtils::Permuted
armnn::TensorShape Permuted(const armnn::TensorShape &srcShape, const armnn::PermutationVector &mappings)
Definition: Permute.cpp:125
armnn::Pooling2dDescriptor::m_PoolWidth
uint32_t m_PoolWidth
Pooling width value.
Definition: Descriptors.hpp:415
armnn::UnaryOperation::Neg
@ Neg
armnn::StandInDescriptor::m_NumInputs
uint32_t m_NumInputs
Number of input tensors.
Definition: Descriptors.hpp:1297
armnnDeserializer::IDeserializer::DeserializerImpl::GetQLstmDescriptor
static armnn::QLstmDescriptor GetQLstmDescriptor(QLstmDescriptorPtr qLstmDescriptorPtr)
Definition: Deserializer.cpp:3438
armnn::LogicalBinaryOperation
LogicalBinaryOperation
Definition: Types.hpp:119
armnnDeserializer::IDeserializer::DeserializerImpl
Definition: Deserializer.hpp:34
armnn::Pooling3dDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCDHW, NDHWC).
Definition: Descriptors.hpp:503
armnn::Convolution2dDescriptor::m_PadLeft
uint32_t m_PadLeft
Padding left value in the width dimension.
Definition: Descriptors.hpp:566
armnn::BatchToSpaceNdDescriptor::m_Crops
std::vector< std::pair< unsigned int, unsigned int > > m_Crops
The values to crop from the input dimension.
Definition: Descriptors.hpp:900
armnn::DepthwiseConvolution2dDescriptor::m_StrideY
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
Definition: Descriptors.hpp:702
armnn::CheckLocation::AsString
std::string AsString() const
Definition: Exceptions.hpp:29
armnn::Convolution2dDescriptor::m_DilationY
uint32_t m_DilationY
Dilation along y axis.
Definition: Descriptors.hpp:580
armnnDeserializer::UnidirectionalSequenceLstmDescriptorPtr
const armnnSerializer::UnidirectionalSequenceLstmDescriptor * UnidirectionalSequenceLstmDescriptorPtr
Definition: Deserializer.hpp:32
armnn::BoostLogSeverityMapping::error
@ error
armnn::Pooling3dDescriptor::m_PadBottom
uint32_t m_PadBottom
Padding bottom value in the height dimension.
Definition: Descriptors.hpp:481
armnn::DetectionPostProcessDescriptor::m_MaxClassesPerDetection
uint32_t m_MaxClassesPerDetection
Maximum numbers of classes per detection, used in Fast NMS.
Definition: Descriptors.hpp:747
armnn::IConnectableLayer::GetNumOutputSlots
virtual unsigned int GetNumOutputSlots() const =0
Returns the number of connectable output slots.
armnn::ReduceOperation::Mean
@ Mean
armnn::QLstmDescriptor::m_CellIntermediateScale
float m_CellIntermediateScale
Cell intermediate quantization scale.
Definition: Descriptors.hpp:1430
armnn::ActivationFunction::HardSwish
@ HardSwish
armnn::DataType::QSymmS16
@ QSymmS16
armnn::ActivationFunction::Gelu
@ Gelu
armnn::NormalizationDescriptor::m_NormMethodType
NormalizationAlgorithmMethod m_NormMethodType
Normalization method algorithm to use (LocalBrightness, LocalContrast).
Definition: Descriptors.hpp:795
armnn::TransposeConvolution2dDescriptor::m_PadBottom
uint32_t m_PadBottom
Padding bottom value in the height dimension.
Definition: Descriptors.hpp:1475
armnn::ScatterNdDescriptor::m_AxisEnabled
bool m_AxisEnabled
Flag for ScatterElement, will be set to false by default, we do not support m_AxisEnable = true for n...
Definition: Descriptors.hpp:1728
NumericCast.hpp
armnn::LstmInputParams::m_ForgetGateBias
const ConstTensor * m_ForgetGateBias
Definition: LstmParams.hpp:52
armnn::Pooling3dDescriptor::m_StrideY
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
Definition: Descriptors.hpp:495
armnn::NormalizationAlgorithmChannel::Across
@ Across
armnn::ReduceDescriptor::m_ReduceOperation
ReduceOperation m_ReduceOperation
Specifies the reduction operation to execute.
Definition: Descriptors.hpp:1558
armnnDeserializer::IDeserializer::DeserializerImpl::GetNetworkInputBindingInfo
BindingPointInfo GetNetworkInputBindingInfo(unsigned int layerId, const std::string &name) const
Retrieve binding info (layer id and tensor info) for the network input identified by the given layer ...
Definition: Deserializer.cpp:961
armnn::ComparisonOperation::NotEqual
@ NotEqual
armnn::LstmInputParams::m_CellToInputWeights
const ConstTensor * m_CellToInputWeights
Definition: LstmParams.hpp:48
armnn::ComparisonOperation::GreaterOrEqual
@ GreaterOrEqual
armnn::MeanDescriptor::m_KeepDims
bool m_KeepDims
Enable/disable keep dimensions. If true, then the reduced dimensions that are of length 1 are kept.
Definition: Descriptors.hpp:1192
armnnDeserializer::ToConstTensor
armnn::ConstTensor ToConstTensor(ConstTensorRawPtr constTensorPtr)
Definition: Deserializer.cpp:782
ARMNN_LOG
#define ARMNN_LOG(severity)
Definition: Logging.hpp:212
armnn::DataLayout::NDHWC
@ NDHWC
armnn::FillDescriptor::m_Value
float m_Value
Definition: Descriptors.hpp:940
armnn::TileLayer
Definition: TileLayer.hpp:13
armnn::ElementwiseBinaryDescriptor
A ElementwiseBinaryDescriptor for the ElementwiseBinaryLayer.
Definition: Descriptors.hpp:109
armnnDeserializer::LayerBaseRawPtr
const armnnSerializer::LayerBase * LayerBaseRawPtr
Definition: Deserializer.hpp:30
Assert.hpp
armnn::Pooling3dDescriptor::m_PoolType
PoolingAlgorithm m_PoolType
The pooling algorithm to use (Max. Average, L2).
Definition: Descriptors.hpp:473
CHECKED_NON_NEGATIVE
#define CHECKED_NON_NEGATIVE(VALUE)
Definition: VerificationHelpers.hpp:35
armnn::ResizeDescriptor::m_Method
ResizeMethod m_Method
The Interpolation method to use (Bilinear, NearestNeighbor).
Definition: Descriptors.hpp:1012
armnn::SpaceToBatchNdDescriptor::m_PadList
std::vector< std::pair< unsigned int, unsigned int > > m_PadList
Specifies the padding values for the input dimension: heightPad{top, bottom} widthPad{left,...
Definition: Descriptors.hpp:1069
armnn::LstmInputParams::m_InputToOutputWeights
const ConstTensor * m_InputToOutputWeights
Definition: LstmParams.hpp:43
armnn::LstmDescriptor::m_PeepholeEnabled
bool m_PeepholeEnabled
Enable/disable peephole.
Definition: Descriptors.hpp:1148
armnn::TensorShape
Definition: Tensor.hpp:20
armnn::Convolution3dDescriptor::m_PadRight
uint32_t m_PadRight
Padding right value in the width dimension.
Definition: Descriptors.hpp:631
VerificationHelpers.hpp
armnn::ScatterNdDescriptor::m_Axis
int32_t m_Axis
Extra attribute for ScatterElement, will be set to 0 by default, we do not support axis !...
Definition: Descriptors.hpp:1725
armnn::NormalizationDescriptor::m_NormChannelType
NormalizationAlgorithmChannel m_NormChannelType
Normalization channel algorithm to use (Across, Within).
Definition: Descriptors.hpp:793
LstmParams.hpp
armnnDeserializer::ToActivationFunction
armnn::ActivationFunction ToActivationFunction(armnnSerializer::ActivationFunction function)
Definition: Deserializer.cpp:482
armnn::IOutputSlot
An output connection slot for a layer.
Definition: INetwork.hpp:53
armnn::BinaryOperation::Maximum
@ Maximum
armnn::LstmInputParams::m_CellToForgetWeights
const ConstTensor * m_CellToForgetWeights
Definition: LstmParams.hpp:49
armnnDeserializer::IDeserializer::DeserializerImpl::GetNetworkOutputBindingInfo
BindingPointInfo GetNetworkOutputBindingInfo(unsigned int layerId, const std::string &name) const
Retrieve binding info (layer id and tensor info) for the network output identified by the given layer...
Definition: Deserializer.cpp:977
armnnDeserializer::IDeserializer::DeserializerImpl::GetOutputs
static TensorRawPtrVector GetOutputs(const GraphPtr &graph, unsigned int layerIndex)
Definition: Deserializer.cpp:842
armnn::DataType::Float16
@ Float16
armnn::CheckLocation
Definition: Exceptions.hpp:14
armnnDeserializer::IDeserializer::DeserializerImpl::GetPooling3dDescriptor
static armnn::Pooling3dDescriptor GetPooling3dDescriptor(Pooling3dDescriptor pooling3dDescriptor, unsigned int layerIndex)
Definition: Deserializer.cpp:2478
armnn::LstmInputParams::m_RecurrentToInputWeights
const ConstTensor * m_RecurrentToInputWeights
Definition: LstmParams.hpp:44
armnn::LstmDescriptor::m_ClippingThresProj
float m_ClippingThresProj
Clipping threshold value for the projection.
Definition: Descriptors.hpp:1144
armnn::Pooling3dDescriptor::m_PoolWidth
uint32_t m_PoolWidth
Pooling width value.
Definition: Descriptors.hpp:487
armnn::BinaryOperation::SqDiff
@ SqDiff
armnn::Pooling2dDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:427
armnn::Convolution2dDescriptor::GetNumInputs
uint32_t GetNumInputs() const
Definition: Descriptors.cpp:470
armnn::UnaryOperation::Rsqrt
@ Rsqrt
armnn::LstmInputParams::m_InputToInputWeights
const ConstTensor * m_InputToInputWeights
Definition: LstmParams.hpp:40
armnn::TensorShape::GetNumDimensions
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
Definition: Tensor.cpp:174
armnn::DepthwiseConvolution2dDescriptor::m_DilationY
uint32_t m_DilationY
Dilation factor value for height dimension.
Definition: Descriptors.hpp:706
armnn::ComparisonOperation::Less
@ Less
armnn::UnaryOperation::Sqrt
@ Sqrt
armnnDeserializer::IDeserializer::DeserializerImpl::OutputShapeOfReshape
static armnn::TensorInfo OutputShapeOfReshape(const armnn::TensorInfo &inputTensorInfo, const std::vector< uint32_t > &targetDimsIn)
Definition: Deserializer.cpp:2638
armnn::UnaryOperation::LogicalNot
@ LogicalNot
armnn::QuantizedLstmInputParams::m_RecurrentToOutputWeights
const ConstTensor * m_RecurrentToOutputWeights
Definition: QuantizedLstmParams.hpp:41
armnn::Pooling2dDescriptor::m_PadBottom
uint32_t m_PadBottom
Padding bottom value in the height dimension.
Definition: Descriptors.hpp:413
armnn::LstmInputParams::m_RecurrentToOutputWeights
const ConstTensor * m_RecurrentToOutputWeights
Definition: LstmParams.hpp:47
armnn::Pooling3dDescriptor::m_PaddingMethod
PaddingMethod m_PaddingMethod
The padding method to be used. (Exclude, IgnoreValue).
Definition: Descriptors.hpp:501
armnn::Pooling2dDescriptor::m_PadRight
uint32_t m_PadRight
Padding right value in the width dimension.
Definition: Descriptors.hpp:409
armnnDeserializer::ToElementwiseUnaryOperation
armnn::UnaryOperation ToElementwiseUnaryOperation(armnnSerializer::UnaryOperation operation)
Definition: Deserializer.cpp:623
armnn::FullyConnectedDescriptor::m_BiasEnabled
bool m_BiasEnabled
Enable/disable bias.
Definition: Descriptors.hpp:526
Logging.hpp
armnn::LogicalBinaryDescriptor::m_Operation
LogicalBinaryOperation m_Operation
Specifies the logical operation to execute.
Definition: Descriptors.hpp:1534
armnn::PadDescriptor
A PadDescriptor for the PadLayer.
Definition: Descriptors.hpp:1196
armnn::UnaryOperation::Exp
@ Exp
armnnDeserializer::NormalizationDescriptorPtr
const armnnSerializer::NormalizationDescriptor * NormalizationDescriptorPtr
Definition: Deserializer.hpp:23
armnn::IOutputSlot::SetTensorInfo
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
armnnDeserializer::ToComparisonOperation
armnn::ComparisonOperation ToComparisonOperation(armnnSerializer::ComparisonOperation operation)
Definition: Deserializer.cpp:546
armnn::TransposeDescriptor
A TransposeDescriptor for the TransposeLayer.
Definition: Descriptors.hpp:1490
armnn::Convolution3dDescriptor::m_DilationZ
uint32_t m_DilationZ
Dilation along z axis.
Definition: Descriptors.hpp:651
armnn::DetectionPostProcessDescriptor::m_NumClasses
uint32_t m_NumClasses
Number of classes.
Definition: Descriptors.hpp:755
armnn::PaddingMethod::Exclude
@ Exclude
The padding fields don't count and are ignored.
armnn::EmptyOptional
EmptyOptional is used to initialize the Optional class in case we want to have default value for an O...
Definition: Optional.hpp:32
armnn::SliceDescriptor
A SliceDescriptor for the SliceLayer.
Definition: Descriptors.hpp:1228
armnn::DataType
DataType
Definition: Types.hpp:48
armnn::InstanceNormalizationDescriptor::m_Gamma
float m_Gamma
Gamma, the scale scalar value applied for the normalized tensor. Defaults to 1.0.
Definition: Descriptors.hpp:865
armnn::LstmInputParams::m_InputGateBias
const ConstTensor * m_InputGateBias
Definition: LstmParams.hpp:51
armnn::DetectionPostProcessDescriptor::m_NmsIouThreshold
float m_NmsIouThreshold
Intersection over union threshold.
Definition: Descriptors.hpp:753
armnn::Dimensionality::Scalar
@ Scalar
armnn::ActivationFunction::Elu
@ Elu
armnn::Convolution2dDescriptor::m_BiasEnabled
bool m_BiasEnabled
Enable/disable bias.
Definition: Descriptors.hpp:582
armnn::PaddingMethod::IgnoreValue
@ IgnoreValue
The padding fields count, but are ignored.
armnn::ReshapeDescriptor
A ReshapeDescriptor for the ReshapeLayer.
Definition: Descriptors.hpp:1023
armnn::InvalidArgumentException
Definition: Exceptions.hpp:80
armnnDeserializer::ToDataLayout
armnn::DataLayout ToDataLayout(armnnSerializer::DataLayout dataLayout)
Definition: Deserializer.cpp:466
armnn::UnaryOperation::Sin
@ Sin
armnn::LayerBindingId
int LayerBindingId
Type of identifiers for bindable layers (inputs, outputs).
Definition: Types.hpp:309
armnn::ActivationFunction::Linear
@ Linear
armnn::ScatterNdFunction
ScatterNdFunction
Definition: Types.hpp:500
armnn::DepthwiseConvolution2dDescriptor::m_PadRight
uint32_t m_PadRight
Padding right value in the width dimension.
Definition: Descriptors.hpp:694
armnn::Convolution3dDescriptor::m_PadLeft
uint32_t m_PadLeft
Padding left value in the width dimension.
Definition: Descriptors.hpp:629
armnn::ActivationDescriptor::m_Function
ActivationFunction m_Function
The activation function to use (Sigmoid, TanH, Linear, ReLu, BoundedReLu, SoftReLu,...
Definition: Descriptors.hpp:59
armnn::NormalizationDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:805
armnn::PermuteDescriptor
A PermuteDescriptor for the PermuteLayer.
Definition: Descriptors.hpp:149
armnn::BatchMatMulDescriptor
A BatchMatMulDescriptor for the BatchMatMul operator.
Definition: Descriptors.hpp:1584
CHECK_TENSOR_PTR
#define CHECK_TENSOR_PTR(TENSOR_PTR)
Definition: Deserializer.cpp:172
armnn::Convolution3dDescriptor::m_StrideY
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
Definition: Descriptors.hpp:643
armnn::ReduceOperation::Sum
@ Sum
armnn::GetDataTypeSize
constexpr unsigned int GetDataTypeSize(DataType dataType)
Definition: TypesUtils.hpp:182
armnn::Convolution2dDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:584
armnn::QLstmDescriptor::m_ProjectionClip
float m_ProjectionClip
Clipping threshold value for the projection.
Definition: Descriptors.hpp:1416
armnn::GatherDescriptor::m_Axis
int32_t m_Axis
The axis in params to gather indices from.
Definition: Descriptors.hpp:981
armnn::Convolution3dDescriptor::m_StrideX
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
Definition: Descriptors.hpp:641
armnn::SpaceToBatchNdDescriptor
A SpaceToBatchNdDescriptor for the SpaceToBatchNdLayer.
Definition: Descriptors.hpp:1043
armnnDeserializer::IDeserializer::DeserializerImpl::GetNormalizationDescriptor
static armnn::NormalizationDescriptor GetNormalizationDescriptor(NormalizationDescriptorPtr normalizationDescriptor, unsigned int layerIndex)
Definition: Deserializer.cpp:2972
armnn::Convolution2dDescriptor::m_PadBottom
uint32_t m_PadBottom
Padding bottom value in the height dimension.
Definition: Descriptors.hpp:572
armnn::PermutationVector
Definition: Types.hpp:314
armnn::Convolution3dDescriptor
A Convolution3dDescriptor for the Convolution3dLayer.
Definition: Descriptors.hpp:588
armnn::ReshapeDescriptor::m_TargetShape
TensorShape m_TargetShape
Target shape value.
Definition: Descriptors.hpp:1039
armnn::Exception
Base class for all ArmNN exceptions so that users can filter to just those.
Definition: Exceptions.hpp:46
armnn::ScatterNdFunction::Add
@ Add
armnn::QuantizedLstmInputParams::m_InputToForgetWeights
const ConstTensor * m_InputToForgetWeights
Definition: QuantizedLstmParams.hpp:34
armnn::TransposeConvolution2dDescriptor::m_StrideY
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
Definition: Descriptors.hpp:1479
armnnDeserializer::ToScatterNdFunction
armnn::ScatterNdFunction ToScatterNdFunction(armnnSerializer::ScatterNdFunction function)
Definition: Deserializer.cpp:527
armnnDeserializer::TensorRawPtrVector
std::vector< TensorRawPtr > TensorRawPtrVector
Definition: Deserializer.hpp:28
armnn::ResizeMethod::NearestNeighbor
@ NearestNeighbor
armnnDeserializer::IDeserializer::DeserializerImpl::GetPooling2dDescriptor
static armnn::Pooling2dDescriptor GetPooling2dDescriptor(Pooling2dDescriptor pooling2dDescriptor, unsigned int layerIndex)
Definition: Deserializer.cpp:2383
armnn::BaseTensor::GetInfo
const TensorInfo & GetInfo() const
Definition: Tensor.hpp:297
ParserHelper.hpp
armnn::QuantizedLstmInputParams::m_OutputGateBias
const ConstTensor * m_OutputGateBias
Definition: QuantizedLstmParams.hpp:46
armnn::Pooling2dDescriptor::m_PadLeft
uint32_t m_PadLeft
Padding left value in the width dimension.
Definition: Descriptors.hpp:407
Permute.hpp
armnn::ActivationFunction
ActivationFunction
Definition: Types.hpp:86
armnn::StandInDescriptor::m_NumOutputs
uint32_t m_NumOutputs
Number of output tensors.
Definition: Descriptors.hpp:1299
armnn::BinaryOperation::Power
@ Power
CHECK_CONST_TENSOR_SIZE
#define CHECK_CONST_TENSOR_SIZE(CONST_TENSOR_SIZE, TENSOR_SIZE)
Definition: Deserializer.cpp:175
armnn::Pooling3dDescriptor::m_PadFront
uint32_t m_PadFront
Padding front value in the depth dimension.
Definition: Descriptors.hpp:483
armnnDeserializer::IDeserializer::DeserializerImpl::GetLstmDescriptor
static armnn::LstmDescriptor GetLstmDescriptor(LstmDescriptorPtr lstmDescriptor)
Definition: Deserializer.cpp:3307
armnn::UnaryOperation
UnaryOperation
Definition: Types.hpp:125
armnn::Convolution2dDescriptor::m_StrideX
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
Definition: Descriptors.hpp:574
armnn::QLstmDescriptor::m_OutputIntermediateScale
float m_OutputIntermediateScale
Output intermediate quantization scale.
Definition: Descriptors.hpp:1432
armnn::Convolution2dDescriptor::m_PadRight
uint32_t m_PadRight
Padding right value in the width dimension.
Definition: Descriptors.hpp:568
armnn::TensorInfo::GetDataType
DataType GetDataType() const
Definition: Tensor.hpp:200
armnn::PoolingAlgorithm::Average
@ Average
armnn::DetectionPostProcessDescriptor::m_DetectionsPerClass
uint32_t m_DetectionsPerClass
Detections per classes, used in Regular NMS.
Definition: Descriptors.hpp:749
armnn::ScatterNdLayer
This layer represents a ScatterNd operator.
Definition: ScatterNdLayer.hpp:14
armnn::DetectionPostProcessDescriptor::m_ScaleH
float m_ScaleH
Center size encoding scale height.
Definition: Descriptors.hpp:765
armnnDeserializer::IDeserializer::DeserializerImpl::LoadGraphFromBinary
static GraphPtr LoadGraphFromBinary(const uint8_t *binaryContent, size_t len)
Definition: Deserializer.cpp:899
armnn::DataType::Signed32
@ Signed32
armnn::UnaryOperation::Ceil
@ Ceil
armnnDeserializer::IDeserializer
Definition: IDeserializer.hpp:27
armnn::LstmInputParams::m_InputLayerNormWeights
const ConstTensor * m_InputLayerNormWeights
Definition: LstmParams.hpp:57
armnn::ReduceDescriptor::m_KeepDims
bool m_KeepDims
if true then output shape has no change.
Definition: Descriptors.hpp:1554
armnn::BatchToSpaceNdDescriptor
A BatchToSpaceNdDescriptor for the BatchToSpaceNdLayer.
Definition: Descriptors.hpp:875
armnn::Convolution2dDescriptor
A Convolution2dDescriptor for the Convolution2dLayer.
Definition: Descriptors.hpp:534
armnn::ReduceOperation::Prod
@ Prod
armnn::ActivationFunction::Abs
@ Abs
armnn::DepthwiseConvolution2dDescriptor::m_PadBottom
uint32_t m_PadBottom
Padding bottom value in the height dimension.
Definition: Descriptors.hpp:698
armnn::ComparisonDescriptor
A ComparisonDescriptor for the ComparisonLayer.
Definition: Descriptors.hpp:89
armnn::FillDescriptor
A FillDescriptor for the FillLayer.
Definition: Descriptors.hpp:925
armnn::DataType::QAsymmS8
@ QAsymmS8
armnn::ComparisonDescriptor::m_Operation
ComparisonOperation m_Operation
Specifies the comparison operation to execute.
Definition: Descriptors.hpp:105
armnnDeserializer::QLstmDescriptorPtr
const armnnSerializer::QLstmDescriptor * QLstmDescriptorPtr
Definition: Deserializer.hpp:26
armnn::Pooling3dDescriptor::m_PadRight
uint32_t m_PadRight
Padding right value in the width dimension.
Definition: Descriptors.hpp:477
armnn::ElementwiseUnaryDescriptor::m_Operation
UnaryOperation m_Operation
Specifies the elementwiseUnary operation to execute.
Definition: Descriptors.hpp:145
armnn::ResizeMethod::Bilinear
@ Bilinear
armnn::ArgMinMaxFunction::Min
@ Min
armnn::StandInDescriptor
A StandInDescriptor for the StandIn layer.
Definition: Descriptors.hpp:1281
armnn::Pooling2dDescriptor::m_StrideX
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
Definition: Descriptors.hpp:419
armnn::SpaceToDepthDescriptor::m_BlockSize
unsigned int m_BlockSize
Scalar specifying the input block size. It must be >= 1.
Definition: Descriptors.hpp:1092
armnn::LstmInputParams::m_ForgetLayerNormWeights
const ConstTensor * m_ForgetLayerNormWeights
Definition: LstmParams.hpp:58
armnn::UnaryOperation::Log
@ Log
armnn::ResizeDescriptor::m_TargetWidth
uint32_t m_TargetWidth
Target width value.
Definition: Descriptors.hpp:1007
armnn::Pooling3dDescriptor::m_PoolHeight
uint32_t m_PoolHeight
Pooling height value.
Definition: Descriptors.hpp:489
armnn::LogicalBinaryOperation::LogicalAnd
@ LogicalAnd
armnnDeserializer::ToTensorInfo
armnn::TensorInfo ToTensorInfo(TensorRawPtr tensorPtr)
Definition: Deserializer.cpp:676
armnn::InstanceNormalizationDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:871
Transpose.hpp
armnn::LstmDescriptor
An LstmDescriptor for the LstmLayer.
Definition: Descriptors.hpp:1102
armnn::ComparisonOperation
ComparisonOperation
Definition: Types.hpp:109
armnn::StridedSliceDescriptor
A StridedSliceDescriptor for the StridedSliceLayer.
Definition: Descriptors.hpp:1303
armnn::Pooling3dDescriptor::m_PadBack
uint32_t m_PadBack
Padding back value in the depth dimension.
Definition: Descriptors.hpp:485
armnn::ResizeDescriptor::m_AlignCorners
bool m_AlignCorners
Aligned corners.
Definition: Descriptors.hpp:1016
armnn::TileDescriptor::m_Multiples
std::vector< uint32_t > m_Multiples
The vector to multiply the input shape by.
Definition: Descriptors.hpp:1656
armnn::MeanDescriptor::m_Axis
std::vector< unsigned int > m_Axis
Values for the dimensions to reduce.
Definition: Descriptors.hpp:1190
armnn::LstmDescriptor::m_CifgEnabled
bool m_CifgEnabled
Enable/disable cifg (coupled input & forget gate).
Definition: Descriptors.hpp:1146
armnn::IOutputSlot::Connect
virtual int Connect(IInputSlot &destination)=0
armnn::LogicalBinaryDescriptor
A LogicalBinaryDescriptor for the LogicalBinaryLayer.
Definition: Descriptors.hpp:1518
armnn::NormalizationDescriptor::m_Alpha
float m_Alpha
Alpha value for the normalization equation.
Definition: Descriptors.hpp:799
armnn::BinaryOperation
BinaryOperation
Definition: Types.hpp:138
armnn::Pooling3dDescriptor::m_StrideX
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
Definition: Descriptors.hpp:493
armnn::Pooling3dDescriptor::m_PadLeft
uint32_t m_PadLeft
Padding left value in the width dimension.
Definition: Descriptors.hpp:475
armnn::TensorInfo::GetShape
const TensorShape & GetShape() const
Definition: Tensor.hpp:193
armnn::QLstmDescriptor::m_HiddenStateZeroPoint
int32_t m_HiddenStateZeroPoint
Hidden State zero point.
Definition: Descriptors.hpp:1434
armnn::Convolution2dDescriptor::m_DilationX
uint32_t m_DilationX
Dilation along x axis.
Definition: Descriptors.hpp:578
armnn::SoftmaxDescriptor::m_Axis
int m_Axis
Scalar, defaulted to the last index (-1), specifying the dimension the activation will be performed o...
Definition: Descriptors.hpp:192
armnn::Convolution3dDescriptor::m_PadBack
uint32_t m_PadBack
Padding back value in the depth dimension.
Definition: Descriptors.hpp:639
armnn::ReduceDescriptor::m_vAxis
std::vector< uint32_t > m_vAxis
The indices of the dimensions to reduce.
Definition: Descriptors.hpp:1556
armnn::ParseException
Definition: Exceptions.hpp:92
armnn::LstmDescriptor::m_LayerNormEnabled
bool m_LayerNormEnabled
Enable/disable layer normalization.
Definition: Descriptors.hpp:1152
armnn::QuantizedLstmInputParams::m_InputToInputWeights
const ConstTensor * m_InputToInputWeights
Definition: QuantizedLstmParams.hpp:33
armnn::IgnoreUnused
void IgnoreUnused(Ts &&...)
Definition: IgnoreUnused.hpp:14
armnn::TransposeConvolution2dDescriptor::m_PadTop
uint32_t m_PadTop
Padding top value in the height dimension.
Definition: Descriptors.hpp:1473
armnn::TransposeConvolution2dDescriptor::m_PadRight
uint32_t m_PadRight
Padding right value in the width dimension.
Definition: Descriptors.hpp:1471
armnn::QuantizedLstmInputParams::m_CellBias
const ConstTensor * m_CellBias
Definition: QuantizedLstmParams.hpp:45
armnn::LstmInputParams::m_OutputGateBias
const ConstTensor * m_OutputGateBias
Definition: LstmParams.hpp:54
armnn::QLstmDescriptor::m_CifgEnabled
bool m_CifgEnabled
Enable/disable CIFG (coupled input & forget gate).
Definition: Descriptors.hpp:1418
armnn::IInputSlot::SetTensorInfo
virtual void SetTensorInfo(const TensorInfo tensorInfo)=0
Sets the TensorInfo for this InputSlot.
armnn::ElementwiseBinaryDescriptor::m_Operation
BinaryOperation m_Operation
Specifies the elementwiseBinary operation to execute.
Definition: Descriptors.hpp:125
armnn::ScatterNdFunction::Update
@ Update
armnn::BinaryOperation::Minimum
@ Minimum
armnnDeserializer::Pooling3dDescriptor
const armnnSerializer::Pooling3dDescriptor * Pooling3dDescriptor
Definition: Deserializer.hpp:22
armnn::Convolution3dDescriptor::m_DilationY
uint32_t m_DilationY
Dilation along y axis.
Definition: Descriptors.hpp:649
armnn::OriginsDescriptor
An OriginsDescriptor for the ConcatLayer.
Definition: Descriptors.hpp:201
armnn::LstmInputParams::m_ProjectionWeights
const ConstTensor * m_ProjectionWeights
Definition: LstmParams.hpp:55
armnn::ScatterNdFunction::Max
@ Max
armnn::FullyConnectedDescriptor::GetNumInputs
uint32_t GetNumInputs() const
Get the number of inputs.
Definition: Descriptors.cpp:475
armnn::ActivationFunction::ReLu
@ ReLu
armnn::LstmInputParams::m_InputToForgetWeights
const ConstTensor * m_InputToForgetWeights
Definition: LstmParams.hpp:41
armnn::TensorInfo::SetShape
void SetShape(const TensorShape &newShape)
Definition: Tensor.hpp:195
armnn::IConnectableLayer::GetOutputSlot
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
Exceptions.hpp
armnn
Copyright (c) 2021 ARM Limited and Contributors.
Definition: 01_00_quick_start.dox:6
armnn::ElementwiseUnaryDescriptor
A ElementwiseUnaryDescriptor for the ElementwiseUnaryLayer.
Definition: Descriptors.hpp:129
armnn::TransposeConvolution2dDescriptor
A TransposeConvolution2dDescriptor for the TransposeConvolution2dLayer.
Definition: Descriptors.hpp:1440
armnn::IConnectableLayer::GetInputSlot
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
CHECK_VALID_SIZE
#define CHECK_VALID_SIZE(ACTUAL,...)
Definition: VerificationHelpers.hpp:32
armnn::Convolution3dDescriptor::m_BiasEnabled
bool m_BiasEnabled
Enable/disable bias.
Definition: Descriptors.hpp:653
armnn::ArgMinMaxDescriptor::m_Axis
int m_Axis
Axis to reduce across the input tensor.
Definition: Descriptors.hpp:83
armnn::ActivationDescriptor::m_B
float m_B
Beta lower bound value used by the activation functions. (BoundedReLu, Linear, TanH).
Definition: Descriptors.hpp:63
armnn::Convolution3dDescriptor::m_StrideZ
uint32_t m_StrideZ
Stride value when proceeding through input for the depth dimension.
Definition: Descriptors.hpp:645
QuantizedLstmParams.hpp
armnn::DetectionPostProcessDescriptor::m_UseRegularNms
bool m_UseRegularNms
Use Regular NMS.
Definition: Descriptors.hpp:757
armnn::ScatterNdDescriptor::m_Function
ScatterNdFunction m_Function
Specify if the function is update, add, sub, max or min.
Definition: Descriptors.hpp:1719
armnn::PoolingAlgorithm::Max
@ Max
armnnDeserializer::ConstTensorRawPtr
const armnnSerializer::ConstTensor * ConstTensorRawPtr
Definition: Deserializer.hpp:18
armnn::QLstmDescriptor::m_HiddenStateScale
float m_HiddenStateScale
Hidden State quantization scale.
Definition: Descriptors.hpp:1436
armnn::ReduceOperation
ReduceOperation
Definition: Types.hpp:157
armnn::NormalizationDescriptor::m_K
float m_K
Kappa value used for the across channel normalization equation.
Definition: Descriptors.hpp:803
armnn::UnaryOperation::Abs
@ Abs
armnn::LstmDescriptor::m_ProjectionEnabled
bool m_ProjectionEnabled
Enable/disable the projection layer.
Definition: Descriptors.hpp:1150
armnnDeserializer::IDeserializer::DeserializerImpl::GetBaseLayer
static LayerBaseRawPtr GetBaseLayer(const GraphPtr &graphPtr, unsigned int layerIndex)
Definition: Deserializer.cpp:286
armnn::ReduceOperation::Min
@ Min
armnnDeserializer::IDeserializer::CreateNetworkFromBinary
armnn::INetworkPtr CreateNetworkFromBinary(const std::vector< uint8_t > &binaryContent)
Create an input network from binary file contents.
Definition: Deserializer.cpp:57
armnn::ConstTensor
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
Definition: Tensor.hpp:329
armnn::ActivationFunction::Square
@ Square
armnn::IConnectableLayer
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:80
armnn::IInputSlot
An input connection slot for a layer.
Definition: INetwork.hpp:25
armnn::Pooling2dDescriptor::m_OutputShapeRounding
OutputShapeRounding m_OutputShapeRounding
The rounding method for the output shape. (Floor, Ceiling).
Definition: Descriptors.hpp:423
armnnDeserializer::IDeserializer::DeserializerImpl::GetLayerName
static std::string GetLayerName(const GraphPtr &graph, unsigned int index)
Definition: Deserializer.cpp:444
armnnDeserializer::IDeserializer::DeserializerImpl::GetUnidirectionalSequenceLstmDescriptor
static armnn::UnidirectionalSequenceLstmDescriptor GetUnidirectionalSequenceLstmDescriptor(UnidirectionalSequenceLstmDescriptorPtr descriptor)
Definition: Deserializer.cpp:3897
armnn::TransposeConvolution2dDescriptor::m_BiasEnabled
bool m_BiasEnabled
Enable/disable bias.
Definition: Descriptors.hpp:1481
armnn::QLstmDescriptor::m_CellClip
float m_CellClip
Clipping threshold value for the cell state.
Definition: Descriptors.hpp:1414
armnn::DetectionPostProcessDescriptor
Definition: Descriptors.hpp:713
armnn::QLstmDescriptor::m_LayerNormEnabled
bool m_LayerNormEnabled
Enable/disable layer normalization.
Definition: Descriptors.hpp:1424
armnn::ChannelShuffleDescriptor::m_NumGroups
uint32_t m_NumGroups
Number of groups for the channel shuffle operation.
Definition: Descriptors.hpp:1578
armnn::Convolution3dDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NDHWC, NCDHW).
Definition: Descriptors.hpp:655
armnn::L2NormalizationDescriptor::m_Eps
float m_Eps
Used to avoid dividing by zero.
Definition: Descriptors.hpp:822
armnn::TensorInfo::SetConstant
void SetConstant(const bool IsConstant=true)
Marks the data corresponding to this tensor info as constant.
Definition: Tensor.cpp:518
armnn::BinaryOperation::Div
@ Div
armnn::OutputShapeRounding::Ceiling
@ Ceiling
armnn::DataType::Signed64
@ Signed64
armnn::TransposeConvolution2dDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:1483
armnn::QuantizedLstmInputParams::m_InputGateBias
const ConstTensor * m_InputGateBias
Definition: QuantizedLstmParams.hpp:43
armnn::SliceDescriptor::m_Size
std::vector< unsigned int > m_Size
Size of the slice in each dimension.
Definition: Descriptors.hpp:1247
armnn::Pooling2dDescriptor
A Pooling2dDescriptor for the Pooling2dLayer.
Definition: Descriptors.hpp:371
armnn::LstmDescriptor::m_ActivationFunc
uint32_t m_ActivationFunc
The activation function to use.
Definition: Descriptors.hpp:1140
armnn::BatchToSpaceNdDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:902
armnn::DepthwiseConvolution2dDescriptor
A DepthwiseConvolution2dDescriptor for the DepthwiseConvolution2dLayer.
Definition: Descriptors.hpp:659
armnn::ComparisonOperation::Equal
@ Equal
armnn::ScatterNdDescriptor
A ScatterNdDescriptor for the ScatterNdLayer.
Definition: Descriptors.hpp:1679
armnn::ReduceDescriptor
A ReduceDescriptor for the REDUCE operators.
Definition: Descriptors.hpp:1538
armnn::DepthwiseConvolution2dDescriptor::m_DilationX
uint32_t m_DilationX
Dilation factor value for width dimension.
Definition: Descriptors.hpp:704
armnn::BatchNormalizationDescriptor::m_Eps
float m_Eps
Value to add to the variance. Used to avoid dividing by zero.
Definition: Descriptors.hpp:841
armnn::LstmDescriptor::m_ClippingThresCell
float m_ClippingThresCell
Clipping threshold value for the cell state.
Definition: Descriptors.hpp:1142
armnn::NormalizationAlgorithmMethod::LocalContrast
@ LocalContrast
Jarret 2009: Local Contrast Normalization.
armnn::Pooling3dDescriptor::m_PoolDepth
uint32_t m_PoolDepth
Pooling depth value.
Definition: Descriptors.hpp:491
armnnDeserializer::ToElementwiseBinaryOperation
armnn::BinaryOperation ToElementwiseBinaryOperation(armnnSerializer::BinaryOperation operation)
Definition: Deserializer.cpp:598
armnn::LstmInputParams
Definition: LstmParams.hpp:13
armnn::PaddingMode::Reflect
@ Reflect
armnn::LstmInputParams::m_CellLayerNormWeights
const ConstTensor * m_CellLayerNormWeights
Definition: LstmParams.hpp:59
armnn::MeanDescriptor
A MeanDescriptor for the MeanLayer.
Definition: Descriptors.hpp:1172
armnn::QLstmDescriptor::m_PeepholeEnabled
bool m_PeepholeEnabled
Enable/disable peephole.
Definition: Descriptors.hpp:1420
armnn::QuantizedLstmInputParams
Definition: QuantizedLstmParams.hpp:13
armnn::CheckLocation::FileLine
std::string FileLine() const
Definition: Exceptions.hpp:37
armnn::TileDescriptor
Definition: Descriptors.hpp:1640
armnnDeserializer::ToReduceOperation
armnn::ReduceOperation ToReduceOperation(armnnSerializer::ReduceOperation operation)
Definition: Deserializer.cpp:566
armnn::PaddingMode::Constant
@ Constant
armnn::SoftmaxDescriptor
A SoftmaxDescriptor for the SoftmaxLayer.
Definition: Descriptors.hpp:177
armnn::Pooling2dDescriptor::m_PoolType
PoolingAlgorithm m_PoolType
The pooling algorithm to use (Max. Average, L2).
Definition: Descriptors.hpp:405
armnn::QuantizedLstmInputParams::m_InputToCellWeights
const ConstTensor * m_InputToCellWeights
Definition: QuantizedLstmParams.hpp:35
armnn::InstanceNormalizationDescriptor::m_Eps
float m_Eps
Epsilon, small scalar value added to variance to avoid dividing by zero. Defaults to 1e-12f.
Definition: Descriptors.hpp:869
CHECK_GRAPH
#define CHECK_GRAPH(GRAPH, LAYERS_INDEX)
Definition: Deserializer.cpp:184
armnnDeserializer::GetOriginsDescriptor
const armnnSerializer::OriginsDescriptor * GetOriginsDescriptor(const armnnSerializer::SerializedGraph *graph, unsigned int layerIndex)
Definition: Deserializer.cpp:2055
armnn::SpaceToDepthDescriptor
A SpaceToDepthDescriptor for the SpaceToDepthLayer.
Definition: Descriptors.hpp:1075
armnnDeserializer::Pooling2dDescriptor
const armnnSerializer::Pooling2dDescriptor * Pooling2dDescriptor
Definition: Deserializer.hpp:21
armnn::ReduceOperation::Max
@ Max
armnn::DataLayout::NCHW
@ NCHW
armnnDeserializer::GraphPtr
const armnnSerializer::SerializedGraph * GraphPtr
Definition: Deserializer.hpp:19
armnn::DepthwiseConvolution2dDescriptor::GetNumInputs
uint32_t GetNumInputs() const
Get the number of views/inputs.
Definition: Descriptors.cpp:480
armnn::ActivationFunction::Sigmoid
@ Sigmoid
armnn::SpaceToDepthDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:1095
armnn::ComparisonOperation::Greater
@ Greater
armnn::DepthwiseConvolution2dDescriptor::m_StrideX
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
Definition: Descriptors.hpp:700
armnn::DepthwiseConvolution2dDescriptor::m_PadTop
uint32_t m_PadTop
Padding top value in the height dimension.
Definition: Descriptors.hpp:696