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