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