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