ArmNN
 20.11
WorkloadFactory.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include <Layer.hpp>
7 #include <LayersFwd.hpp>
8 
9 #include <armnn/Types.hpp>
10 #include <armnn/LayerSupport.hpp>
11 #include <armnn/ILayerSupport.hpp>
15 
18 
20 
21 #include <sstream>
22 
23 namespace armnn
24 {
25 
26 namespace
27 {
28 using LayerList = std::list<Layer*>;
29 using Iterator = LayerList::const_iterator; // Const so pointers in the list can't be modified externally.
30 
31 const TensorInfo OverrideDataType(const TensorInfo& info, Optional<DataType> type)
32 {
33  if (!type)
34  {
35  return info;
36  }
37 
38  return TensorInfo(info.GetShape(), type.value(), info.GetQuantizationScale(), info.GetQuantizationOffset());
39 }
40 
41 } // anonymous namespace
42 
43 bool IWorkloadFactory::IsLayerConfigurationSupported(const BackendId& backendId,
44  const IConnectableLayer& connectableLayer,
45  Optional<DataType> dataType,
46  std::string& outReasonIfUnsupported,
47  const ModelOptions& modelOptions)
48 {
49  Optional<std::string&> reason = outReasonIfUnsupported;
50  bool result;
51  const Layer& layer = *(PolymorphicDowncast<const Layer*>(&connectableLayer));
52 
53  auto const& backendRegistry = BackendRegistryInstance();
54  if (!backendRegistry.IsBackendRegistered(backendId))
55  {
56  std::stringstream ss;
57  ss << connectableLayer.GetName() << " is not supported on " << backendId
58  << " because this backend is not registered.";
59 
60  outReasonIfUnsupported = ss.str();
61  return false;
62  }
63 
64  auto backendFactory = backendRegistry.GetFactory(backendId);
65  auto backendObject = backendFactory();
66  auto layerSupportObject = backendObject->GetLayerSupport(modelOptions);
67 
68  switch(layer.GetType())
69  {
71  {
72  auto cLayer = PolymorphicDowncast<const ActivationLayer*>(&layer);
73  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
74  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
75  result = layerSupportObject->IsActivationSupported(
76  OverrideDataType(input, dataType),
77  OverrideDataType(output, dataType),
78  cLayer->GetParameters(),
79  reason);
80  break;
81  }
83  {
84  const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
85  const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
86  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
87  result = layerSupportObject->IsAdditionSupported(
88  OverrideDataType(input0, dataType),
89  OverrideDataType(input1, dataType),
90  OverrideDataType(output, dataType),
91  reason);
92  break;
93  }
95  {
96  auto cLayer = PolymorphicDowncast<const ArgMinMaxLayer*>(&layer);
97  const ArgMinMaxDescriptor& descriptor = cLayer->GetParameters();
98 
99  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
100  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
101  result = layerSupportObject->IsArgMinMaxSupported(
102  OverrideDataType(input, dataType),
103  OverrideDataType(output, DataType::Signed32),
104  descriptor,
105  reason);
106  break;
107  }
109  {
110  auto cLayer = PolymorphicDowncast<const BatchNormalizationLayer*>(&layer);
111  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
112  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
113  const TensorInfo& mean = cLayer->m_Mean->GetTensorInfo();
114  const TensorInfo& var = cLayer->m_Variance->GetTensorInfo();
115  const TensorInfo& beta = cLayer->m_Beta->GetTensorInfo();
116  const TensorInfo& gamma = cLayer->m_Gamma->GetTensorInfo();
117  result = layerSupportObject->IsBatchNormalizationSupported(
118  OverrideDataType(input, dataType),
119  OverrideDataType(output, dataType),
120  OverrideDataType(mean, dataType),
121  OverrideDataType(var, dataType),
122  OverrideDataType(beta, dataType),
123  OverrideDataType(gamma, dataType),
124  cLayer->GetParameters(),
125  reason);
126  break;
127  }
129  {
130  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
131  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
132  auto cLayer = PolymorphicDowncast<const BatchToSpaceNdLayer*>(&layer);
133 
134  result = layerSupportObject->IsBatchToSpaceNdSupported(OverrideDataType(input, dataType),
135  OverrideDataType(output, dataType),
136  cLayer->GetParameters(),
137  reason);
138  break;
139  }
141  {
142  auto cLayer = PolymorphicDowncast<const ComparisonLayer*>(&layer);
143 
144  const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
145  const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
146  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
147 
148  result = layerSupportObject->IsComparisonSupported(OverrideDataType(input0, dataType),
149  OverrideDataType(input1, dataType),
150  OverrideDataType(output, DataType::Boolean),
151  cLayer->GetParameters(),
152  reason);
153  break;
154  }
155  case LayerType::Constant:
156  {
157  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
158  result = layerSupportObject->IsConstantSupported(OverrideDataType(output, dataType), reason);
159  break;
160  }
162  {
163  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
164  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
165  result = layerSupportObject->IsConvertBf16ToFp32Supported(input, output, reason);
166  break;
167  }
169  {
170  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
171  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
172  result = layerSupportObject->IsConvertFp16ToFp32Supported(input, output, reason);
173  break;
174  }
176  {
177  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
178  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
179  result = layerSupportObject->IsConvertFp32ToBf16Supported(input, output, reason);
180  break;
181  }
183  {
184  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
185  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
186  result = layerSupportObject->IsConvertFp32ToFp16Supported(input, output, reason);
187  break;
188  }
190  {
191  auto cLayer = PolymorphicDowncast<const Convolution2dLayer*>(&layer);
192 
193  const TensorInfo input = OverrideDataType(layer.GetInputSlot(0).GetConnection()->GetTensorInfo(),
194  dataType);
195  const TensorInfo output = OverrideDataType(layer.GetOutputSlot(0).GetTensorInfo(), dataType);
196  ARMNN_ASSERT(cLayer->m_Weight.get() != nullptr);
197 
198  const Convolution2dDescriptor& descriptor = cLayer->GetParameters();
199 
200  // Construct optional biases object based on the value of m_BiasEnabled
201  Optional<TensorInfo> biases;
202  if (descriptor.m_BiasEnabled)
203  {
204  biases =
205  OverrideDataType(cLayer->m_Bias->GetTensorInfo(), GetBiasTypeFromWeightsType(dataType));
206  }
207 
208  result = layerSupportObject->IsConvolution2dSupported(
209  input,
210  output,
211  descriptor,
212  OverrideDataType(cLayer->m_Weight->GetTensorInfo(), dataType),
213  biases,
214  reason);
215  break;
216  }
217  case LayerType::Debug:
218  {
219  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
220  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
221 
222  result = layerSupportObject->IsDebugSupported(OverrideDataType(input, dataType),
223  OverrideDataType(output, dataType),
224  reason);
225  break;
226  }
228  {
229  auto cLayer = PolymorphicDowncast<const DepthToSpaceLayer*>(&layer);
230 
231  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
232  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
233 
234  result = layerSupportObject->IsDepthToSpaceSupported(OverrideDataType(input, dataType),
235  OverrideDataType(output, dataType),
236  cLayer->GetParameters(),
237  reason);
238  break;
239  }
241  {
242  auto cLayer = PolymorphicDowncast<const DepthwiseConvolution2dLayer*>(&layer);
243  const TensorInfo& input = OverrideDataType(layer.GetInputSlot(0).GetConnection()->GetTensorInfo(),
244  dataType);
245  const TensorInfo& output = OverrideDataType(layer.GetOutputSlot(0).GetTensorInfo(), dataType);
246  ARMNN_ASSERT(cLayer->m_Weight.get() != nullptr);
247 
248  const DepthwiseConvolution2dDescriptor& descriptor = cLayer->GetParameters();
249 
250  // Construct optional biases object based on the value of m_BiasEnabled
251  Optional<TensorInfo> biases;
252  if (descriptor.m_BiasEnabled)
253  {
254  biases =
255  OverrideDataType(cLayer->m_Bias->GetTensorInfo(), GetBiasTypeFromWeightsType(dataType));
256  }
257 
258  result = layerSupportObject->IsDepthwiseConvolutionSupported(
259  input,
260  output,
261  descriptor,
262  OverrideDataType(cLayer->m_Weight->GetTensorInfo(), dataType),
263  biases,
264  reason);
265  break;
266  }
268  {
269  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
270  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
271 
272  result = layerSupportObject->IsDequantizeSupported(input,
273  OverrideDataType(output, dataType),
274  reason);
275  break;
276  }
278  {
279  auto cLayer = PolymorphicDowncast<const DetectionPostProcessLayer*>(&layer);
280  const TensorInfo& boxEncodings = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
281  const TensorInfo& scores = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
282  const TensorInfo& anchors = cLayer->m_Anchors->GetTensorInfo();
283 
284  const TensorInfo& detectionBoxes = layer.GetOutputSlot(0).GetTensorInfo();
285  const TensorInfo& detectionClasses = layer.GetOutputSlot(1).GetTensorInfo();
286  const TensorInfo& detectionScores = layer.GetOutputSlot(2).GetTensorInfo();
287  const TensorInfo& numDetections = layer.GetOutputSlot(3).GetTensorInfo();
288 
289  const DetectionPostProcessDescriptor& descriptor = cLayer->GetParameters();
290  result = layerSupportObject->IsDetectionPostProcessSupported(boxEncodings,
291  scores,
292  anchors,
293  detectionBoxes,
294  detectionClasses,
295  detectionScores,
296  numDetections,
297  descriptor,
298  reason);
299  break;
300  }
302  {
303  auto cLayer = PolymorphicDowncast<const ElementwiseUnaryLayer*>(&layer);
304 
305  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
306  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
307 
308  result = layerSupportObject->IsElementwiseUnarySupported(OverrideDataType(input, dataType),
309  OverrideDataType(output, dataType),
310  cLayer->GetParameters(),
311  reason);
312  break;
313  }
314  case LayerType::Fill:
315  {
316  auto cLayer = PolymorphicDowncast<const FillLayer*>(&layer);
317  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
318  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
319  const FillDescriptor& descriptor = cLayer->GetParameters();
320 
321  result = layerSupportObject->IsFillSupported(
322  OverrideDataType(input, dataType),
323  OverrideDataType(output, dataType),
324  descriptor,
325  reason);
326  break;
327  }
329  {
330  auto cLayer = PolymorphicDowncast<const FakeQuantizationLayer*>(&layer);
331  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
332  result = layerSupportObject->IsFakeQuantizationSupported(OverrideDataType(input, dataType),
333  cLayer->GetParameters(),
334  reason);
335  break;
336  }
337  case LayerType::Floor:
338  {
339  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
340  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
341  result = layerSupportObject->IsFloorSupported(OverrideDataType(input, dataType),
342  OverrideDataType(output, dataType),
343  reason);
344  break;
345  }
347  {
348  auto cLayer = PolymorphicDowncast<const FullyConnectedLayer*>(&layer);
349  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
350  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
351  ARMNN_ASSERT(cLayer->m_Weight.get() != nullptr);
352 
353  TensorInfo biasInfo;
354  const TensorInfo * biasInfoPtr = nullptr;
355  static const TensorInfo dummyBFloat16Bias(TensorShape({1,1,1,1}), DataType::BFloat16);
356  static const TensorInfo dummyFloat16Bias(TensorShape({1,1,1,1}), DataType::Float16);
357  static const TensorInfo dummyFloat32Bias(TensorShape({1,1,1,1}), DataType::Float32);
358  static const TensorInfo dummyQA8Bias(TensorShape({1,1,1,1}), DataType::Signed32);
359 
360  const FullyConnectedDescriptor& descriptor = cLayer->GetParameters();
361  if (descriptor.m_BiasEnabled)
362  {
363  ARMNN_ASSERT(cLayer->m_Bias.get() != nullptr);
364  biasInfo = OverrideDataType(cLayer->m_Bias->GetTensorInfo(), GetBiasTypeFromWeightsType(dataType));
365  biasInfoPtr = &biasInfo;
366  }
367  else
368  {
369  // If biases are not enabled pass a dummy tensorinfo for the validation
370  switch(input.GetDataType())
371  {
372  case DataType::BFloat16:
373  {
374  biasInfoPtr = &dummyBFloat16Bias;
375  break;
376  }
377  case DataType::Float16:
378  {
379  biasInfoPtr = &dummyFloat16Bias;
380  break;
381  }
382  case DataType::Float32:
383  {
384  biasInfoPtr = &dummyFloat32Bias;
385  break;
386  }
387  case DataType::QAsymmU8:
388  case DataType::QAsymmS8:
389  case DataType::QSymmS8:
390  case DataType::QSymmS16:
391  {
392  biasInfoPtr = &dummyQA8Bias;
393  break;
394  }
395  default:
396  {
397  ARMNN_ASSERT_MSG(false, "Unexpected bias type");
398  }
399  }
400  }
401 
402  result = layerSupportObject->IsFullyConnectedSupported(
403  OverrideDataType(input, dataType),
404  OverrideDataType(output, dataType),
405  OverrideDataType(cLayer->m_Weight->GetTensorInfo(), dataType),
406  *biasInfoPtr,
407  descriptor,
408  reason);
409  break;
410  }
411  case LayerType::Gather:
412  {
413  const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
414  const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
415  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
416  auto cLayer = PolymorphicDowncast<const GatherLayer*>(&layer);
417  const GatherDescriptor& descriptor = cLayer->GetParameters();
418  result = layerSupportObject->IsGatherSupported(OverrideDataType(input0, dataType),
419  input1,
420  OverrideDataType(output, dataType),
421  descriptor,
422  reason);
423  break;
424  }
425  case LayerType::Input:
426  {
427  const TensorInfo& input = layer.GetOutputSlot(0).GetTensorInfo();
428  result = layerSupportObject->IsInputSupported(OverrideDataType(input, dataType), reason);
429  break;
430  }
432  {
433  auto cLayer = PolymorphicDowncast<const InstanceNormalizationLayer*>(&layer);
434  const InstanceNormalizationDescriptor& descriptor = cLayer->GetParameters();
435 
436  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
437  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
438 
439  result = layerSupportObject->IsInstanceNormalizationSupported(
440  OverrideDataType(input, dataType),
441  OverrideDataType(output, dataType),
442  descriptor,
443  reason);
444  break;
445  }
447  {
448  auto cLayer = PolymorphicDowncast<const L2NormalizationLayer*>(&layer);
449  const L2NormalizationDescriptor& descriptor = cLayer->GetParameters();
450 
451  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
452  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
453 
454  result = layerSupportObject->IsL2NormalizationSupported(
455  OverrideDataType(input, dataType),
456  OverrideDataType(output, dataType),
457  descriptor,
458  reason);
459  break;
460  }
462  {
463  auto cLayer = PolymorphicDowncast<const LogicalBinaryLayer*>(&layer);
464 
465  const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
466  const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
467  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
468 
469  result = layerSupportObject->IsLogicalBinarySupported(input0,
470  input1,
471  output,
472  cLayer->GetParameters(),
473  reason);
474  break;
475  }
477  {
478  auto cLayer = PolymorphicDowncast<const LogSoftmaxLayer*>(&layer);
479 
480  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
481  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
482 
483  result = layerSupportObject->IsLogSoftmaxSupported(OverrideDataType(input, dataType),
484  OverrideDataType(output, dataType),
485  cLayer->GetParameters(),
486  reason);
487  break;
488  }
489  case LayerType::Lstm:
490  {
491  auto cLayer = PolymorphicDowncast<const LstmLayer*>(&layer);
492  const LstmDescriptor& descriptor = cLayer->GetParameters();
493 
494  // All inputs.
495  const TensorInfo& input = OverrideDataType(layer.GetInputSlot(0).GetConnection()->GetTensorInfo(),
496  dataType);
497  const TensorInfo& outputStateIn = OverrideDataType(layer.GetInputSlot(1).GetConnection()->GetTensorInfo(),
498  dataType);
499  const TensorInfo& cellStateIn = OverrideDataType(layer.GetInputSlot(2).GetConnection()->GetTensorInfo(),
500  dataType);
501  // All outputs
502  const TensorInfo& scratchBuffer = OverrideDataType(layer.GetOutputSlot(0).GetTensorInfo(), dataType);
503  const TensorInfo& outputStateOut = OverrideDataType(layer.GetOutputSlot(1).GetTensorInfo(), dataType);
504  const TensorInfo& cellStateOut = OverrideDataType(layer.GetOutputSlot(2).GetTensorInfo(), dataType);
505  const TensorInfo& output = OverrideDataType(layer.GetOutputSlot(3).GetTensorInfo(), dataType);
506 
507  // Basic parameters
508  const TensorInfo& inputToForgetWeights
509  = OverrideDataType(cLayer->m_BasicParameters.m_InputToForgetWeights->GetTensorInfo(), dataType);
510  const TensorInfo& inputToCellWeights
511  = OverrideDataType(cLayer->m_BasicParameters.m_InputToCellWeights->GetTensorInfo(), dataType);
512  const TensorInfo& inputToOutputWeights
513  = OverrideDataType(cLayer->m_BasicParameters.m_InputToOutputWeights->GetTensorInfo(), dataType);
514  const TensorInfo& recurrentToForgetWeights
515  = OverrideDataType(cLayer->m_BasicParameters.m_RecurrentToForgetWeights->GetTensorInfo(), dataType);
516  const TensorInfo& recurrentToCellWeights
517  = OverrideDataType(cLayer->m_BasicParameters.m_RecurrentToCellWeights->GetTensorInfo(), dataType);
518  const TensorInfo& recurrentToOutputWeights
519  = OverrideDataType(cLayer->m_BasicParameters.m_RecurrentToOutputWeights->GetTensorInfo(), dataType);
520  const TensorInfo& forgetGateBias
521  = OverrideDataType(cLayer->m_BasicParameters.m_ForgetGateBias->GetTensorInfo(), dataType);
522  const TensorInfo& cellBias
523  = OverrideDataType(cLayer->m_BasicParameters.m_CellBias->GetTensorInfo(), dataType);
524  const TensorInfo& outputGateBias
525  = OverrideDataType(cLayer->m_BasicParameters.m_OutputGateBias->GetTensorInfo(), dataType);
526 
527  LstmInputParamsInfo paramsInfo;
528 
529  paramsInfo.m_InputToForgetWeights = &inputToForgetWeights;
530  paramsInfo.m_InputToCellWeights = &inputToCellWeights;
531  paramsInfo.m_InputToOutputWeights = &inputToOutputWeights;
532  paramsInfo.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
533  paramsInfo.m_RecurrentToCellWeights = &recurrentToCellWeights;
534  paramsInfo.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
535  paramsInfo.m_ForgetGateBias = &forgetGateBias;
536  paramsInfo.m_CellBias = &cellBias;
537  paramsInfo.m_OutputGateBias = &outputGateBias;
538 
539 
540  // Optional parameters
541  TensorInfo optInputToInputWeights;
542  TensorInfo optRecurrentToInputWeights;
543  TensorInfo optCellToInputWeights;
544  TensorInfo optInputGateBias;
545  TensorInfo optProjectionWeights;
546  TensorInfo optProjectionBias;
547  TensorInfo optCellToForgetWeights;
548  TensorInfo optCellToOutputWeights;
549  TensorInfo optInputLayerNormWeights;
550  TensorInfo optForgetLayerNormWeights;
551  TensorInfo optCellLayerNormWeights;
552  TensorInfo optOutputLayerNormWeights;
553 
554  if(!descriptor.m_CifgEnabled)
555  {
556  optInputToInputWeights =
557  OverrideDataType(cLayer->m_CifgParameters.m_InputToInputWeights->GetTensorInfo(), dataType);
558  paramsInfo.m_InputToInputWeights = &optInputToInputWeights;
559 
560  optRecurrentToInputWeights =
561  OverrideDataType(cLayer->m_CifgParameters.m_RecurrentToInputWeights->GetTensorInfo(), dataType);
562  paramsInfo.m_RecurrentToInputWeights = &optRecurrentToInputWeights;
563  optInputGateBias =
564  OverrideDataType(cLayer->m_CifgParameters.m_InputGateBias->GetTensorInfo(), dataType);
565  paramsInfo.m_InputGateBias = &optInputGateBias;
566  }
567 
568  if(descriptor.m_ProjectionEnabled)
569  {
570  optProjectionWeights =
571  OverrideDataType(cLayer->m_ProjectionParameters.m_ProjectionWeights->GetTensorInfo(), dataType);
572  paramsInfo.m_ProjectionWeights = &optProjectionWeights;
573  if (cLayer->m_ProjectionParameters.m_ProjectionBias != nullptr)
574  {
575  optProjectionBias =
576  OverrideDataType(cLayer->m_ProjectionParameters.m_ProjectionBias->GetTensorInfo(), dataType);
577  paramsInfo.m_ProjectionBias = &optProjectionBias;
578  }
579  }
580 
581  if(descriptor.m_PeepholeEnabled)
582  {
583  if(!descriptor.m_CifgEnabled)
584  {
585  optCellToInputWeights =
586  OverrideDataType(cLayer->m_PeepholeParameters.m_CellToInputWeights->GetTensorInfo(),
587  dataType);
588  paramsInfo.m_CellToInputWeights = &optCellToInputWeights;
589  }
590  optCellToForgetWeights =
591  OverrideDataType(cLayer->m_PeepholeParameters.m_CellToForgetWeights->GetTensorInfo(), dataType);
592  paramsInfo.m_CellToForgetWeights = &optCellToForgetWeights;
593  optCellToOutputWeights =
594  OverrideDataType(cLayer->m_PeepholeParameters.m_CellToOutputWeights->GetTensorInfo(), dataType);
595  paramsInfo.m_CellToOutputWeights = &optCellToOutputWeights;
596  }
597 
598  if(descriptor.m_LayerNormEnabled)
599  {
600  if (!descriptor.m_CifgEnabled)
601  {
602  optInputLayerNormWeights = OverrideDataType(
603  cLayer->m_LayerNormParameters.m_InputLayerNormWeights->GetTensorInfo(), dataType);
604  paramsInfo.m_InputLayerNormWeights = &optInputLayerNormWeights;
605  }
606 
607  optForgetLayerNormWeights = OverrideDataType(
608  cLayer->m_LayerNormParameters.m_ForgetLayerNormWeights->GetTensorInfo(), dataType);
609  paramsInfo.m_ForgetLayerNormWeights = &optForgetLayerNormWeights;
610 
611  optCellLayerNormWeights = OverrideDataType(
612  cLayer->m_LayerNormParameters.m_CellLayerNormWeights->GetTensorInfo(), dataType);
613  paramsInfo.m_CellLayerNormWeights = &optCellLayerNormWeights;
614 
615  optOutputLayerNormWeights = OverrideDataType(
616  cLayer->m_LayerNormParameters.m_OutputLayerNormWeights->GetTensorInfo(), dataType);
617  paramsInfo.m_OutputLayerNormWeights = &optOutputLayerNormWeights;
618  }
619 
620  result = layerSupportObject->IsLstmSupported(
621  input,
622  outputStateIn,
623  cellStateIn,
624  scratchBuffer,
625  outputStateOut,
626  cellStateOut,
627  output,
628  descriptor,
629  paramsInfo,
630  reason);
631  break;
632  }
633  case LayerType::Maximum:
634  {
635  const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
636  const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
637  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
638 
639  result = layerSupportObject->IsMaximumSupported(OverrideDataType(input0, dataType),
640  OverrideDataType(input1, dataType),
641  OverrideDataType(output, dataType),
642  reason);
643  break;
644  }
645  case LayerType::MemCopy:
646  {
647  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
648  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
649 
650  result = layerSupportObject->IsMemCopySupported(OverrideDataType(input, dataType),
651  OverrideDataType(output, dataType),
652  reason);
653  break;
654  }
656  {
657  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
658  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
659 
660  result = layerSupportObject->IsMemImportSupported(OverrideDataType(input, dataType),
661  OverrideDataType(output, dataType),
662  reason);
663  break;
664  }
665  case LayerType::Merge:
666  {
667  const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
668  const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
669  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
670 
671  result = layerSupportObject->IsMergeSupported(OverrideDataType(input0, dataType),
672  OverrideDataType(input1, dataType),
673  OverrideDataType(output, dataType),
674  reason);
675  break;
676  }
677  case LayerType::Concat:
678  {
679  auto cLayer = PolymorphicDowncast<const ConcatLayer*>(&layer);
680 
681  // Get vector of all inputs.
682  auto getTensorInfo = [&dataType](const InputSlot& slot)
683  {
684  return OverrideDataType(slot.GetConnectedOutputSlot()->GetTensorInfo(), dataType);
685  };
686 
687  auto beginI = MakeTransformIterator(layer.GetInputSlots().begin(), getTensorInfo);
688  auto endI = MakeTransformIterator(layer.GetInputSlots().end(), getTensorInfo);
689  std::vector<TensorInfo> inputs(beginI, endI);
690 
691  auto getTensorInfoPtr = [](const TensorInfo& info)
692  {
693  return &info;
694  };
695 
696  auto beginPtr = MakeTransformIterator(inputs.begin(), getTensorInfoPtr);
697  auto endPtr = MakeTransformIterator(inputs.end(), getTensorInfoPtr);
698  std::vector<const TensorInfo*> inputPtrs(beginPtr, endPtr);
699 
700  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
701 
702  result = layerSupportObject->IsConcatSupported(inputPtrs, output, cLayer->GetParameters(), reason);
703 
704 
705  break;
706  }
708  {
709  const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
710  const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
711  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
712  result = layerSupportObject->IsMultiplicationSupported(
713  OverrideDataType(input0, dataType),
714  OverrideDataType(input1, dataType),
715  OverrideDataType(output, dataType),
716  reason);
717  break;
718  }
720  {
721  auto cLayer = PolymorphicDowncast<const NormalizationLayer*>(&layer);
722  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
723  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
724  result = layerSupportObject->IsNormalizationSupported(OverrideDataType(input, dataType),
725  OverrideDataType(output, dataType),
726  cLayer->GetParameters(),
727  reason);
728  break;
729  }
730  case LayerType::Output:
731  {
732  const TensorInfo& output = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
733  result = layerSupportObject->IsOutputSupported(OverrideDataType(output, dataType), reason);
734  break;
735  }
736  case LayerType::Permute:
737  {
738  auto cLayer = PolymorphicDowncast<const PermuteLayer*>(&layer);
739  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
740  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
741  result = layerSupportObject->IsPermuteSupported(OverrideDataType(input, dataType),
742  OverrideDataType(output, dataType),
743  cLayer->GetParameters(),
744  reason);
745  break;
746  }
747  case LayerType::Pad:
748  {
749  auto cLayer = PolymorphicDowncast<const PadLayer*>(&layer);
750  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
751  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
752  result = layerSupportObject->IsPadSupported(
753  OverrideDataType(input, dataType),
754  OverrideDataType(output, dataType),
755  cLayer->GetParameters(),
756  reason);
757  break;
758  }
760  {
761  auto cLayer = PolymorphicDowncast<const Pooling2dLayer*>(&layer);
762  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
763  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
764  result = layerSupportObject->IsPooling2dSupported(OverrideDataType(input, dataType),
765  OverrideDataType(output, dataType),
766  cLayer->GetParameters(),
767  reason);
768  break;
769  }
771  {
772  auto cLayer = PolymorphicDowncast<const PreCompiledLayer*>(&layer);
773  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
774  result = layerSupportObject->IsPreCompiledSupported(OverrideDataType(input, dataType),
775  cLayer->GetParameters(),
776  reason);
777  break;
778  }
779  case LayerType::Quantize:
780  {
781  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
782  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
783  result = layerSupportObject->IsQuantizeSupported(input, output, reason);
784  break;
785  }
786  case LayerType::QLstm:
787  {
788  auto cLayer = PolymorphicDowncast<const QLstmLayer*>(&layer);
789  const QLstmDescriptor& descriptor = cLayer->GetParameters();
790 
791  // Inputs
792  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
793  const TensorInfo& previousOutputIn = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
794  const TensorInfo& previousCellStateIn = layer.GetInputSlot(2).GetConnection()->GetTensorInfo();
795 
796  // Outputs
797  const TensorInfo& outputStateOut = layer.GetOutputSlot(0).GetTensorInfo();
798  const TensorInfo& cellStateOut = layer.GetOutputSlot(1).GetTensorInfo();
799  const TensorInfo& output = layer.GetOutputSlot(2).GetTensorInfo();
800 
801  // Lstm parameters
802  LstmInputParamsInfo paramsInfo;
803 
804  // Basic parameters
805  paramsInfo.m_InputToForgetWeights = &cLayer->m_BasicParameters.m_InputToForgetWeights->GetTensorInfo();
806  paramsInfo.m_InputToCellWeights = &cLayer->m_BasicParameters.m_InputToCellWeights->GetTensorInfo();
807  paramsInfo.m_InputToOutputWeights = &cLayer->m_BasicParameters.m_InputToOutputWeights->GetTensorInfo();
808 
809  paramsInfo.m_RecurrentToForgetWeights =
810  &cLayer->m_BasicParameters.m_RecurrentToForgetWeights->GetTensorInfo();
811  paramsInfo.m_RecurrentToCellWeights =
812  &cLayer->m_BasicParameters.m_RecurrentToCellWeights->GetTensorInfo();
813  paramsInfo.m_RecurrentToOutputWeights =
814  &cLayer->m_BasicParameters.m_RecurrentToOutputWeights->GetTensorInfo();
815 
816  paramsInfo.m_ForgetGateBias = &cLayer->m_BasicParameters.m_ForgetGateBias->GetTensorInfo();
817  paramsInfo.m_CellBias = &cLayer->m_BasicParameters.m_CellBias->GetTensorInfo();
818  paramsInfo.m_OutputGateBias = &cLayer->m_BasicParameters.m_OutputGateBias->GetTensorInfo();
819 
820  if(!descriptor.m_CifgEnabled)
821  {
822  paramsInfo.m_InputToInputWeights = &cLayer->m_CifgParameters.m_InputToInputWeights->GetTensorInfo();
823  paramsInfo.m_RecurrentToInputWeights =
824  &cLayer->m_CifgParameters.m_RecurrentToInputWeights->GetTensorInfo();
825  paramsInfo.m_InputGateBias = &cLayer->m_CifgParameters.m_InputGateBias->GetTensorInfo();
826  }
827 
828  if(descriptor.m_ProjectionEnabled)
829  {
830  paramsInfo.m_ProjectionWeights = &cLayer->m_ProjectionParameters.m_ProjectionWeights->GetTensorInfo();
831 
832  // Projection bias is optional even if projection is enabled
833  if (cLayer->m_ProjectionParameters.m_ProjectionBias != nullptr)
834  {
835  paramsInfo.m_ProjectionBias = &cLayer->m_ProjectionParameters.m_ProjectionBias->GetTensorInfo();
836  }
837  }
838 
839  if(descriptor.m_PeepholeEnabled)
840  {
841  if (!descriptor.m_CifgEnabled)
842  {
843  paramsInfo.m_CellToInputWeights =
844  &cLayer->m_PeepholeParameters.m_CellToInputWeights->GetTensorInfo();
845  }
846 
847  paramsInfo.m_CellToForgetWeights =
848  &cLayer->m_PeepholeParameters.m_CellToForgetWeights->GetTensorInfo();
849  paramsInfo.m_CellToOutputWeights = &cLayer->m_PeepholeParameters.m_CellToOutputWeights->GetTensorInfo();
850  }
851 
852  if(descriptor.m_LayerNormEnabled)
853  {
854  if (!descriptor.m_CifgEnabled)
855  {
856  paramsInfo.m_InputLayerNormWeights =
857  &cLayer->m_LayerNormParameters.m_InputLayerNormWeights->GetTensorInfo();
858  }
859 
860  paramsInfo.m_ForgetLayerNormWeights =
861  &cLayer->m_LayerNormParameters.m_ForgetLayerNormWeights->GetTensorInfo();
862  paramsInfo.m_CellLayerNormWeights =
863  &cLayer->m_LayerNormParameters.m_CellLayerNormWeights->GetTensorInfo();
864  paramsInfo.m_OutputLayerNormWeights =
865  &cLayer->m_LayerNormParameters.m_OutputLayerNormWeights->GetTensorInfo();
866  }
867 
868  result = layerSupportObject->IsQLstmSupported(input,
869  previousOutputIn,
870  previousCellStateIn,
871  outputStateOut,
872  cellStateOut,
873  output,
874  descriptor,
875  paramsInfo,
876  reason);
877  break;
878  }
880  {
881  auto cLayer = PolymorphicDowncast<const QuantizedLstmLayer*>(&layer);
882 
883  // Inputs
884  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
885  const TensorInfo& previousCellStateIn = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
886  const TensorInfo& previousOutputIn = layer.GetInputSlot(2).GetConnection()->GetTensorInfo();
887 
888  // Outputs
889  const TensorInfo& cellStateOut = layer.GetOutputSlot(0).GetTensorInfo();
890  const TensorInfo& output = layer.GetOutputSlot(1).GetTensorInfo();
891 
892  // QuantizedLstm parameters
893  QuantizedLstmInputParamsInfo paramsInfo;
894 
895  paramsInfo.m_InputToInputWeights =
896  &cLayer->m_QuantizedLstmParameters.m_InputToInputWeights->GetTensorInfo();
897  paramsInfo.m_InputToForgetWeights =
898  &cLayer->m_QuantizedLstmParameters.m_InputToForgetWeights->GetTensorInfo();
899  paramsInfo.m_InputToCellWeights =
900  &cLayer->m_QuantizedLstmParameters.m_InputToCellWeights->GetTensorInfo();
901  paramsInfo.m_InputToOutputWeights =
902  &cLayer->m_QuantizedLstmParameters.m_InputToOutputWeights->GetTensorInfo();
903 
904  paramsInfo.m_RecurrentToInputWeights =
905  &cLayer->m_QuantizedLstmParameters.m_RecurrentToInputWeights->GetTensorInfo();
906  paramsInfo.m_RecurrentToForgetWeights =
907  &cLayer->m_QuantizedLstmParameters.m_RecurrentToForgetWeights->GetTensorInfo();
908  paramsInfo.m_RecurrentToCellWeights =
909  &cLayer->m_QuantizedLstmParameters.m_RecurrentToCellWeights->GetTensorInfo();
910  paramsInfo.m_RecurrentToOutputWeights =
911  &cLayer->m_QuantizedLstmParameters.m_RecurrentToOutputWeights->GetTensorInfo();
912 
913  paramsInfo.m_InputGateBias =
914  &cLayer->m_QuantizedLstmParameters.m_InputGateBias->GetTensorInfo();
915  paramsInfo.m_ForgetGateBias =
916  &cLayer->m_QuantizedLstmParameters.m_ForgetGateBias->GetTensorInfo();
917  paramsInfo.m_CellBias =
918  &cLayer->m_QuantizedLstmParameters.m_CellBias->GetTensorInfo();
919  paramsInfo.m_OutputGateBias =
920  &cLayer->m_QuantizedLstmParameters.m_OutputGateBias->GetTensorInfo();;
921 
922  result = layerSupportObject->IsQuantizedLstmSupported(input,
923  previousCellStateIn,
924  previousOutputIn,
925  cellStateOut,
926  output,
927  paramsInfo,
928  reason);
929  break;
930  }
931  case LayerType::Division:
932  {
933  const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
934  const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
935  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
936  result = layerSupportObject->IsDivisionSupported(
937  OverrideDataType(input0, dataType),
938  OverrideDataType(input1, dataType),
939  OverrideDataType(output, dataType),
940  reason);
941  break;
942  }
943  case LayerType::Rank:
944  {
945  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
946  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
947  result = layerSupportObject->IsRankSupported(OverrideDataType(input, dataType),
948  OverrideDataType(output, dataType),
949  reason);
950  break;
951  }
952  case LayerType::Reshape:
953  {
954  auto cLayer = PolymorphicDowncast<const ReshapeLayer*>(&layer);
955  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
956  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
957  result = layerSupportObject->IsReshapeSupported(OverrideDataType(input, dataType),
958  OverrideDataType(output, dataType),
959  cLayer->GetParameters(),
960  reason);
961  break;
962  }
963  case LayerType::Resize:
964  {
965  auto cLayer = PolymorphicDowncast<const ResizeLayer*>(&layer);
966  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
967  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
968  result = layerSupportObject->IsResizeSupported(OverrideDataType(input, dataType),
969  OverrideDataType(output, dataType),
970  cLayer->GetParameters(),
971  reason);
972  break;
973  }
974  case LayerType::Slice:
975  {
976  auto cLayer = PolymorphicDowncast<const SliceLayer*>(&layer);
977 
978  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
979  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
980 
981  result = layerSupportObject->IsSliceSupported(OverrideDataType(input, dataType),
982  OverrideDataType(output, dataType),
983  cLayer->GetParameters(),
984  reason);
985  break;
986  }
987  case LayerType::Softmax:
988  {
989  auto cLayer = PolymorphicDowncast<const SoftmaxLayer*>(&layer);
990  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
991  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
992  result = layerSupportObject->IsSoftmaxSupported(OverrideDataType(input, dataType),
993  OverrideDataType(output, dataType),
994  cLayer->GetParameters(),
995  reason);
996  break;
997  }
999  {
1000  auto cLayer = PolymorphicDowncast<const SpaceToBatchNdLayer*>(&layer);
1001  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
1002  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
1003  result = layerSupportObject->IsSpaceToBatchNdSupported(OverrideDataType(input, dataType),
1004  OverrideDataType(output, dataType),
1005  cLayer->GetParameters(),
1006  reason);
1007  break;
1008  }
1010  {
1011  auto cLayer = PolymorphicDowncast<const SpaceToDepthLayer*>(&layer);
1012 
1013  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
1014  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
1015 
1016  result = layerSupportObject->IsSpaceToDepthSupported(OverrideDataType(input, dataType),
1017  OverrideDataType(output, dataType),
1018  cLayer->GetParameters(),
1019  reason);
1020  break;
1021  }
1022  case LayerType::Splitter:
1023  {
1024  auto cLayer = PolymorphicDowncast<const SplitterLayer*>(&layer);
1025  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
1026 
1027  // Get vector of all outputs.
1028  auto getTensorInfo = [&dataType](const OutputSlot& slot)
1029  {
1030  return OverrideDataType(slot.GetTensorInfo(), dataType);
1031  };
1032  auto beginI = MakeTransformIterator(layer.GetOutputSlots().begin(), getTensorInfo);
1033  auto endI = MakeTransformIterator(layer.GetOutputSlots().end(), getTensorInfo);
1034  std::vector<TensorInfo> outputs(beginI, endI);
1035 
1036  const std::vector<std::reference_wrapper<TensorInfo>> outputPtrs(outputs.begin(), outputs.end());
1037 
1038  result = layerSupportObject->IsSplitterSupported(OverrideDataType(input, dataType),
1039  outputPtrs,
1040  cLayer->GetParameters(),
1041  reason);
1042  break;
1043  }
1044  case LayerType::Stack:
1045  {
1046  auto cLayer = PolymorphicDowncast<const StackLayer*>(&layer);
1047 
1048  // Get vector of all inputs.
1049  auto getTensorInfo = [&dataType](const InputSlot& slot)
1050  {
1051  return OverrideDataType(slot.GetConnectedOutputSlot()->GetTensorInfo(), dataType);
1052  };
1053  auto beginI = MakeTransformIterator(layer.GetInputSlots().begin(), getTensorInfo);
1054  auto endI = MakeTransformIterator(layer.GetInputSlots().end(), getTensorInfo);
1055  std::vector<TensorInfo> inputs(beginI, endI);
1056 
1057  auto getTensorInfoPtr = [](const TensorInfo& info)
1058  {
1059  return &info;
1060  };
1061  auto beginPtr = MakeTransformIterator(inputs.begin(), getTensorInfoPtr);
1062  auto endPtr = MakeTransformIterator(inputs.end(), getTensorInfoPtr);
1063  std::vector<const TensorInfo*> inputPtrs(beginPtr, endPtr);
1064 
1065  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
1066 
1067  result = layerSupportObject->IsStackSupported(inputPtrs, output, cLayer->GetParameters(), reason);
1068 
1069  break;
1070  }
1071  case LayerType::StandIn:
1072  {
1073  auto cLayer = PolymorphicDowncast<const StandInLayer*>(&layer);
1074 
1075  // Get vector of all inputs.
1076  auto getTensorInfoIn = [&dataType](const InputSlot& slot)
1077  {
1078  return OverrideDataType(slot.GetConnectedOutputSlot()->GetTensorInfo(), dataType);
1079  };
1080  auto getTensorInfoOut = [&dataType](const OutputSlot& slot)
1081  {
1082  return OverrideDataType(slot.GetTensorInfo(), dataType);
1083  };
1084  auto beginI = MakeTransformIterator(layer.GetInputSlots().begin(), getTensorInfoIn);
1085  auto endI = MakeTransformIterator(layer.GetInputSlots().end(), getTensorInfoIn);
1086  std::vector<TensorInfo> inputs(beginI, endI);
1087 
1088  auto beginO = MakeTransformIterator(layer.GetOutputSlots().begin(), getTensorInfoOut);
1089  auto endO = MakeTransformIterator(layer.GetOutputSlots().end(), getTensorInfoOut);
1090  std::vector<TensorInfo> outputs(beginO, endO);
1091 
1092 
1093  auto getTensorInfoPtr = [](const TensorInfo& info)
1094  {
1095  return &info;
1096  };
1097  auto beginPtrI = MakeTransformIterator(inputs.begin(), getTensorInfoPtr);
1098  auto endPtrI = MakeTransformIterator(inputs.end(), getTensorInfoPtr);
1099  std::vector<const TensorInfo*> inputPtrs(beginPtrI, endPtrI);
1100 
1101  auto beginPtrO = MakeTransformIterator(outputs.begin(), getTensorInfoPtr);
1102  auto endPtrO = MakeTransformIterator(outputs.end(), getTensorInfoPtr);
1103  std::vector<const TensorInfo*> outputPtrs(beginPtrO, endPtrO);
1104 
1105 
1106  result = layerSupportObject->IsStandInSupported(inputPtrs,
1107  outputPtrs,
1108  cLayer->GetParameters(),
1109  reason);
1110  break;
1111  }
1113  {
1114  auto cLayer = PolymorphicDowncast<const StridedSliceLayer*>(&layer);
1115  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
1116  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
1117  result = layerSupportObject->IsStridedSliceSupported(OverrideDataType(input, dataType),
1118  OverrideDataType(output, dataType),
1119  cLayer->GetParameters(),
1120  reason);
1121  break;
1122  }
1124  {
1125  const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
1126  const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
1127  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
1128  result = layerSupportObject->IsSubtractionSupported(
1129  OverrideDataType(input0, dataType),
1130  OverrideDataType(input1, dataType),
1131  OverrideDataType(output, dataType),
1132  reason);
1133  break;
1134  }
1135  case LayerType::Switch:
1136  {
1137  const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
1138  const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
1139  const TensorInfo& output0 = layer.GetOutputSlot(0).GetTensorInfo();
1140  const TensorInfo& output1 = layer.GetOutputSlot(1).GetTensorInfo();
1141  result = layerSupportObject->IsSwitchSupported(OverrideDataType(input0, dataType),
1142  OverrideDataType(input1, dataType),
1143  OverrideDataType(output0, dataType),
1144  OverrideDataType(output1, dataType),
1145  reason);
1146  break;
1147  }
1148  case LayerType::Mean:
1149  {
1150  auto cLayer = PolymorphicDowncast<const MeanLayer*>(&layer);
1151  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
1152  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
1153  result = layerSupportObject->IsMeanSupported(
1154  OverrideDataType(input, dataType),
1155  OverrideDataType(output, dataType),
1156  cLayer->GetParameters(),
1157  reason);
1158  break;
1159  }
1160  case LayerType::Minimum:
1161  {
1162  const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
1163  const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
1164  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
1165  result = layerSupportObject->IsMinimumSupported(OverrideDataType(input0, dataType),
1166  OverrideDataType(input1, dataType),
1167  OverrideDataType(output, dataType),
1168  reason);
1169  break;
1170  }
1171  case LayerType::Prelu:
1172  {
1173  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
1174  const TensorInfo& alpha = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
1175  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
1176  result = layerSupportObject->IsPreluSupported(OverrideDataType(input, dataType),
1177  OverrideDataType(alpha, dataType),
1178  OverrideDataType(output, dataType),
1179  reason);
1180  break;
1181  }
1182  case LayerType::Transpose:
1183  {
1184  auto cLayer = PolymorphicDowncast<const TransposeLayer*>(&layer);
1185  const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
1186  const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
1187  result = layerSupportObject->IsTransposeSupported(OverrideDataType(input, dataType),
1188  OverrideDataType(output, dataType),
1189  cLayer->GetParameters(),
1190  reason);
1191  break;
1192  }
1194  {
1195  auto cLayer = PolymorphicDowncast<const TransposeConvolution2dLayer*>(&layer);
1196 
1197  const TensorInfo input = OverrideDataType(layer.GetInputSlot(0).GetConnection()->GetTensorInfo(),
1198  dataType);
1199  const TensorInfo output = OverrideDataType(layer.GetOutputSlot(0).GetTensorInfo(), dataType);
1200 
1201  const TransposeConvolution2dDescriptor& descriptor = cLayer->GetParameters();
1202 
1203  Optional<TensorInfo> biases;
1204  if (descriptor.m_BiasEnabled)
1205  {
1206  ARMNN_ASSERT(cLayer->m_Bias.get() != nullptr);
1207  biases = OverrideDataType(cLayer->m_Bias->GetTensorInfo(),
1208  GetBiasTypeFromWeightsType(dataType));
1209  }
1210 
1211  ARMNN_ASSERT(cLayer->m_Weight.get() != nullptr);
1212  const TensorInfo weights = OverrideDataType(cLayer->m_Weight->GetTensorInfo(), dataType);
1213 
1214  result = layerSupportObject->IsTransposeConvolution2dSupported(input,
1215  output,
1216  descriptor,
1217  weights,
1218  biases,
1219  reason);
1220 
1221  break;
1222  }
1223  default:
1224  {
1225  ARMNN_ASSERT_MSG(false, "WorkloadFactory did not recognise type of layer.");
1226  reason.value() = "Unrecognised layer type";
1227  result = false;
1228  break;
1229  }
1230  }
1231  return result;
1232 }
1233 
1235  const IConnectableLayer& connectableLayer,
1236  Optional<DataType> dataType,
1237  std::string& outReasonIfUnsupported)
1238 {
1239  return IsLayerConfigurationSupported(backendId, connectableLayer, dataType, outReasonIfUnsupported);
1240 }
1241 
1243  Optional<DataType> dataType,
1244  std::string& outReasonIfUnsupported)
1245 {
1246  auto layer = PolymorphicDowncast<const Layer*>(&connectableLayer);
1247  return IsLayerConfigurationSupported(layer->GetBackendId(), connectableLayer, dataType, outReasonIfUnsupported);
1248 }
1249 
1250 // TODO merge with defaulted modelOptions above
1252  Optional<DataType> dataType,
1253  std::string& outReasonIfUnsupported,
1254  const ModelOptions& modelOptions)
1255 {
1256  auto layer = PolymorphicDowncast<const Layer*>(&connectableLayer);
1257  return IsLayerConfigurationSupported(layer->GetBackendId(),
1258  connectableLayer,
1259  dataType,
1260  outReasonIfUnsupported,
1261  modelOptions);
1262 }
1263 
1265  const IConnectableLayer& connectableLayer,
1266  Optional<DataType> dataType,
1267  std::string& outReasonIfUnsupported,
1268  const ModelOptions& modelOptions)
1269 {
1270  return IsLayerConfigurationSupported(backendId,
1271  connectableLayer,
1272  dataType,
1273  outReasonIfUnsupported,
1274  modelOptions);
1275 }
1276 
1277 // Default Implementations
1278 std::unique_ptr<IWorkload> IWorkloadFactory::CreateAbs(const AbsQueueDescriptor& /*descriptor*/,
1279  const WorkloadInfo& /*info*/) const
1280 {
1281  return std::unique_ptr<IWorkload>();
1282 }
1283 
1284 std::unique_ptr<IWorkload> IWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& /*descriptor*/,
1285  const WorkloadInfo& /*info*/) const
1286 {
1287  return std::unique_ptr<IWorkload>();
1288 }
1289 
1290 std::unique_ptr<IWorkload> IWorkloadFactory::CreateAddition(const AdditionQueueDescriptor& /*descriptor*/,
1291  const WorkloadInfo& /*info*/) const
1292 {
1293  return std::unique_ptr<IWorkload>();
1294 }
1295 
1296 std::unique_ptr<IWorkload> IWorkloadFactory::CreateArgMinMax(const ArgMinMaxQueueDescriptor& /*descriptor*/,
1297  const WorkloadInfo& /*info*/) const
1298 {
1299  return std::unique_ptr<IWorkload>();
1300 }
1301 
1303  const BatchNormalizationQueueDescriptor& /*descriptor*/, const WorkloadInfo& /*info*/) const
1304 {
1305  return std::unique_ptr<IWorkload>();
1306 }
1307 
1309  const WorkloadInfo& /*Info*/) const
1310 {
1311  return std::unique_ptr<IWorkload>();
1312 }
1313 
1314 std::unique_ptr<IWorkload> IWorkloadFactory::CreateComparison(const ComparisonQueueDescriptor& /*descriptor*/,
1315  const WorkloadInfo& /*info*/) const
1316 {
1317  return std::unique_ptr<IWorkload>();
1318 }
1319 
1320 std::unique_ptr<IWorkload> IWorkloadFactory::CreateConcat(const ConcatQueueDescriptor& /*descriptor*/,
1321  const WorkloadInfo& /*info*/) const
1322 {
1323  return std::unique_ptr<IWorkload>();
1324 }
1325 
1326 std::unique_ptr<IWorkload> IWorkloadFactory::CreateConstant(const ConstantQueueDescriptor& /*descriptor*/,
1327  const WorkloadInfo& /*info*/) const
1328 {
1329  return std::unique_ptr<IWorkload>();
1330 }
1331 
1333  const WorkloadInfo& /*info*/) const
1334 {
1335  return std::unique_ptr<IWorkload>();
1336 }
1337 
1339  const WorkloadInfo& /*info*/) const
1340 {
1341  return std::unique_ptr<IWorkload>();
1342 }
1343 
1345  const WorkloadInfo& /*info*/) const
1346 {
1347  return std::unique_ptr<IWorkload>();
1348 }
1349 
1351  const WorkloadInfo& /*info*/) const
1352 {
1353  return std::unique_ptr<IWorkload>();
1354 }
1355 
1356 std::unique_ptr<IWorkload> IWorkloadFactory::CreateConvolution2d(const Convolution2dQueueDescriptor& /*descriptor*/,
1357  const WorkloadInfo& /*info*/) const
1358 {
1359  return std::unique_ptr<IWorkload>();
1360 }
1361 
1362 std::unique_ptr<IWorkload> IWorkloadFactory::CreateDebug(const DebugQueueDescriptor& /*descriptor*/,
1363  const WorkloadInfo& /*info*/) const
1364 {
1365  return std::unique_ptr<IWorkload>();
1366 }
1367 
1368 std::unique_ptr<IWorkload> IWorkloadFactory::CreateDepthToSpace(const DepthToSpaceQueueDescriptor& /*descriptor*/,
1369  const WorkloadInfo& /*info*/) const
1370 {
1371  return std::unique_ptr<IWorkload>();
1372 }
1373 
1375  const DepthwiseConvolution2dQueueDescriptor& /*descriptor*/, const WorkloadInfo& /*info*/) const
1376 {
1377  return std::unique_ptr<IWorkload>();
1378 }
1379 
1380 std::unique_ptr<IWorkload> IWorkloadFactory::CreateDequantize(
1381  const DequantizeQueueDescriptor& /*descriptor*/, const WorkloadInfo& /*info*/) const
1382 {
1383  return std::unique_ptr<IWorkload>();
1384 }
1385 
1387  const DetectionPostProcessQueueDescriptor& /*descriptor*/, const WorkloadInfo& /*info*/) const
1388 {
1389  return std::unique_ptr<IWorkload>();
1390 }
1391 
1392 std::unique_ptr<IWorkload> IWorkloadFactory::CreateDivision(const DivisionQueueDescriptor& /*descriptor*/,
1393  const WorkloadInfo& /*info*/) const
1394 {
1395  return std::unique_ptr<IWorkload>();
1396 }
1397 
1399  const WorkloadInfo& /*info*/) const
1400 {
1401  return std::unique_ptr<IWorkload>();
1402 }
1403 
1404 std::unique_ptr<IWorkload> IWorkloadFactory::CreateEqual(const EqualQueueDescriptor& /*descriptor*/,
1405  const WorkloadInfo& /*Info*/) const
1406 {
1407  return std::unique_ptr<IWorkload>();
1408 }
1409 
1411  const WorkloadInfo& /*info*/) const
1412 {
1413  return std::unique_ptr<IWorkload>();
1414 }
1415 
1416 std::unique_ptr<IWorkload> IWorkloadFactory::CreateFill(const FillQueueDescriptor& /*descriptor*/,
1417  const WorkloadInfo& /*info*/) const
1418 {
1419  return std::unique_ptr<IWorkload>();
1420 }
1421 
1422 std::unique_ptr<IWorkload> IWorkloadFactory::CreateFloor(const FloorQueueDescriptor& /*descriptor*/,
1423  const WorkloadInfo& /*info*/) const
1424 {
1425  return std::unique_ptr<IWorkload>();
1426 }
1427 
1428 std::unique_ptr<IWorkload> IWorkloadFactory::CreateFullyConnected(const FullyConnectedQueueDescriptor& /*descriptor*/,
1429  const WorkloadInfo& /*info*/) const
1430 {
1431  return std::unique_ptr<IWorkload>();
1432 }
1433 
1434 std::unique_ptr<IWorkload> IWorkloadFactory::CreateGather(const GatherQueueDescriptor& /*descriptor*/,
1435  const WorkloadInfo& /*info*/) const
1436 {
1437  return std::unique_ptr<IWorkload>();
1438 }
1439 
1440 std::unique_ptr<IWorkload> IWorkloadFactory::CreateGreater(const GreaterQueueDescriptor& /*descriptor*/,
1441  const WorkloadInfo& /*info*/) const
1442 {
1443  return std::unique_ptr<IWorkload>();
1444 }
1445 
1447  const InstanceNormalizationQueueDescriptor& /*descriptor*/,
1448  const WorkloadInfo& /*info*/) const
1449 {
1450  return std::unique_ptr<IWorkload>();
1451 }
1452 
1454  const WorkloadInfo& /*info*/) const
1455 {
1456  return std::unique_ptr<IWorkload>();
1457 }
1458 
1459 std::unique_ptr<IWorkload> IWorkloadFactory::CreateLogicalBinary(const LogicalBinaryQueueDescriptor& /*desc*/,
1460  const WorkloadInfo& /*info*/) const
1461 {
1462  return std::unique_ptr<IWorkload>();
1463 }
1464 
1466  const WorkloadInfo& /*info*/) const
1467 {
1468  return std::unique_ptr<IWorkload>();
1469 }
1470 
1471 std::unique_ptr<IWorkload> IWorkloadFactory::CreateLogSoftmax(const LogSoftmaxQueueDescriptor& /*descriptor*/,
1472  const WorkloadInfo& /*info*/) const
1473 {
1474  return std::unique_ptr<IWorkload>();
1475 }
1476 
1477 std::unique_ptr<IWorkload> IWorkloadFactory::CreateLstm(const LstmQueueDescriptor& /*descriptor*/,
1478  const WorkloadInfo& /*info*/) const
1479 {
1480  return std::unique_ptr<IWorkload>();
1481 }
1482 
1483 std::unique_ptr<IWorkload> IWorkloadFactory::CreateMaximum(const MaximumQueueDescriptor& /*descriptor*/,
1484  const WorkloadInfo& /*info*/) const
1485 {
1486  return std::unique_ptr<IWorkload>();
1487 }
1488 
1489 std::unique_ptr<IWorkload> IWorkloadFactory::CreateMean(const MeanQueueDescriptor& /*descriptor*/,
1490  const WorkloadInfo& /*Info*/) const
1491 {
1492  return std::unique_ptr<IWorkload>();
1493 }
1494 
1495 std::unique_ptr<IWorkload> IWorkloadFactory::CreateMemCopy(const MemCopyQueueDescriptor& /*descriptor*/,
1496  const WorkloadInfo& /*info*/) const
1497 {
1498  return std::unique_ptr<IWorkload>();
1499 }
1500 
1501 std::unique_ptr<IWorkload> IWorkloadFactory::CreateMemImport(const MemImportQueueDescriptor& /*descriptor*/,
1502  const WorkloadInfo& /*info*/) const
1503 {
1504  return std::unique_ptr<IWorkload>();
1505 }
1506 
1507 std::unique_ptr<IWorkload> IWorkloadFactory::CreateMerge(const MergeQueueDescriptor& /*descriptor*/,
1508  const WorkloadInfo& /*info*/) const
1509 {
1510  return std::unique_ptr<IWorkload>();
1511 }
1512 
1513 std::unique_ptr<IWorkload> IWorkloadFactory::CreateMerger(const MergerQueueDescriptor& /*descriptor*/,
1514  const WorkloadInfo& /*info*/) const
1515 {
1516  return std::unique_ptr<IWorkload>();
1517 }
1518 
1519 std::unique_ptr<IWorkload> IWorkloadFactory::CreateMinimum(const MinimumQueueDescriptor& /*descriptor*/,
1520  const WorkloadInfo& /*info*/) const
1521 {
1522  return std::unique_ptr<IWorkload>();
1523 }
1524 
1525 std::unique_ptr<IWorkload> IWorkloadFactory::CreateMultiplication(const MultiplicationQueueDescriptor& /*descriptor*/,
1526  const WorkloadInfo& /*info*/) const
1527 {
1528  return std::unique_ptr<IWorkload>();
1529 }
1530 
1531 std::unique_ptr<IWorkload> IWorkloadFactory::CreateNormalization(const NormalizationQueueDescriptor& /*descriptor*/,
1532  const WorkloadInfo& /*info*/) const
1533 {
1534  return std::unique_ptr<IWorkload>();
1535 }
1536 
1537 std::unique_ptr<IWorkload> IWorkloadFactory::CreateOutput(const OutputQueueDescriptor& /*descriptor*/,
1538  const WorkloadInfo& /*info*/) const
1539 {
1540  return std::unique_ptr<IWorkload>();
1541 }
1542 
1543 std::unique_ptr<IWorkload> IWorkloadFactory::CreatePad(const PadQueueDescriptor& /*descriptor*/,
1544  const WorkloadInfo& /*Info*/) const
1545 {
1546  return std::unique_ptr<IWorkload>();
1547 }
1548 
1549 std::unique_ptr<IWorkload> IWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& /*descriptor*/,
1550  const WorkloadInfo& /*info*/) const
1551 {
1552  return std::unique_ptr<IWorkload>();
1553 }
1554 
1555 std::unique_ptr<IWorkload> IWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& /*descriptor*/,
1556  const WorkloadInfo& /*info*/) const
1557 {
1558  return std::unique_ptr<IWorkload>();
1559 }
1560 
1561 std::unique_ptr<IWorkload> IWorkloadFactory::CreatePreCompiled(const PreCompiledQueueDescriptor& /*descriptor*/,
1562  const WorkloadInfo& /*info*/) const
1563 {
1564  return std::unique_ptr<IWorkload>();
1565 }
1566 
1567 std::unique_ptr<IWorkload> IWorkloadFactory::CreatePrelu(const PreluQueueDescriptor &/*descriptor*/,
1568  const WorkloadInfo &/*info*/) const
1569 {
1570  return std::unique_ptr<IWorkload>();
1571 }
1572 
1573 std::unique_ptr<IWorkload> IWorkloadFactory::CreateQuantize(const QuantizeQueueDescriptor& /*descriptor*/,
1574  const WorkloadInfo& /*Info*/) const
1575 {
1576  return std::unique_ptr<IWorkload>();
1577 }
1578 
1579 std::unique_ptr<IWorkload> IWorkloadFactory::CreateQLstm(const QLstmQueueDescriptor& /*descriptor*/,
1580  const WorkloadInfo& /*info*/) const
1581 {
1582  return std::unique_ptr<IWorkload>();
1583 }
1584 
1585 std::unique_ptr<IWorkload> IWorkloadFactory::CreateQuantizedLstm(const QuantizedLstmQueueDescriptor& /*descriptor*/,
1586  const WorkloadInfo& /*info*/) const
1587 {
1588  return std::unique_ptr<IWorkload>();
1589 }
1590 std::unique_ptr<IWorkload> IWorkloadFactory::CreateRank(const RankQueueDescriptor& /*descriptor*/,
1591  const WorkloadInfo& /*info*/) const
1592 {
1593  return std::unique_ptr<IWorkload>();
1594 }
1595 
1596 std::unique_ptr<IWorkload> IWorkloadFactory::CreateReshape(const ReshapeQueueDescriptor& /*descriptor*/,
1597  const WorkloadInfo& /*info*/) const
1598 {
1599  return std::unique_ptr<IWorkload>();
1600 }
1601 
1602 std::unique_ptr<IWorkload> IWorkloadFactory::CreateResizeBilinear(const ResizeBilinearQueueDescriptor& /*descriptor*/,
1603  const WorkloadInfo& /*info*/) const
1604 {
1605  return std::unique_ptr<IWorkload>();
1606 }
1607 
1608 std::unique_ptr<IWorkload> IWorkloadFactory::CreateResize(const ResizeQueueDescriptor& /*descriptor*/,
1609  const WorkloadInfo& /*info*/) const
1610 {
1611  return std::unique_ptr<IWorkload>();
1612 }
1613 
1614 std::unique_ptr<IWorkload> IWorkloadFactory::CreateRsqrt(const RsqrtQueueDescriptor& /*descriptor*/,
1615  const WorkloadInfo& /*info*/) const
1616 {
1617  return std::unique_ptr<IWorkload>();
1618 }
1619 
1620 std::unique_ptr<IWorkload> IWorkloadFactory::CreateSlice(const SliceQueueDescriptor& /*descriptor*/,
1621  const WorkloadInfo& /*info*/) const
1622 {
1623  return std::unique_ptr<IWorkload>();
1624 }
1625 
1626 std::unique_ptr<IWorkload> IWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& /*descriptor*/,
1627  const WorkloadInfo& /*info*/) const
1628 {
1629  return std::unique_ptr<IWorkload>();
1630 }
1631 
1632 std::unique_ptr<IWorkload> IWorkloadFactory::CreateSplitter(const SplitterQueueDescriptor& /*descriptor*/,
1633  const WorkloadInfo& /*info*/) const
1634 {
1635  return std::unique_ptr<IWorkload>();
1636 }
1637 
1638 std::unique_ptr<IWorkload> IWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& /*descriptor*/,
1639  const WorkloadInfo& /*info*/) const
1640 {
1641  return std::unique_ptr<IWorkload>();
1642 }
1643 
1644 std::unique_ptr<IWorkload> IWorkloadFactory::CreateSpaceToDepth(const SpaceToDepthQueueDescriptor& /*descriptor*/,
1645  const WorkloadInfo& /*info*/) const
1646 {
1647  return std::unique_ptr<IWorkload>();
1648 }
1649 
1650 std::unique_ptr<IWorkload> IWorkloadFactory::CreateStack(const StackQueueDescriptor& /*descriptor*/,
1651  const WorkloadInfo& /*info*/) const
1652 {
1653  return std::unique_ptr<IWorkload>();
1654 }
1655 
1656 std::unique_ptr<IWorkload> IWorkloadFactory::CreateStridedSlice(const StridedSliceQueueDescriptor& /*descriptor*/,
1657  const WorkloadInfo& /*info*/) const
1658 {
1659  return std::unique_ptr<IWorkload>();
1660 }
1661 
1662 std::unique_ptr<IWorkload> IWorkloadFactory::CreateSubtraction(const SubtractionQueueDescriptor& /*descriptor*/,
1663  const WorkloadInfo& /*info*/) const
1664 {
1665  return std::unique_ptr<IWorkload>();
1666 }
1667 
1668 std::unique_ptr<IWorkload> IWorkloadFactory::CreateSwitch(const SwitchQueueDescriptor& /*descriptor*/,
1669  const WorkloadInfo& /*info*/) const
1670 {
1671  return std::unique_ptr<IWorkload>();
1672 }
1673 
1674 std::unique_ptr<IWorkload> IWorkloadFactory::CreateTranspose(const TransposeQueueDescriptor& /*descriptor*/,
1675  const WorkloadInfo& /*info*/) const
1676 {
1677  return std::unique_ptr<IWorkload>();
1678 }
1679 
1681  const TransposeConvolution2dQueueDescriptor& /*descriptor*/,
1682  const WorkloadInfo& /*info*/) const
1683 {
1684  return std::unique_ptr<IWorkload>();
1685 }
1686 
1687 } // namepsace armnn
virtual std::unique_ptr< IWorkload > CreateSplitter(const SplitterQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateBatchNormalization(const BatchNormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateDebug(const DebugQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateMemCopy(const MemCopyQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateL2Normalization(const L2NormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:61
virtual std::unique_ptr< IWorkload > CreateBatchToSpaceNd(const BatchToSpaceNdQueueDescriptor &descriptor, const WorkloadInfo &Info) const
virtual std::unique_ptr< IWorkload > CreateMultiplication(const MultiplicationQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateInstanceNormalization(const InstanceNormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateGreater(const GreaterQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateArgMinMax(const ArgMinMaxQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateMerger(const MergerQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateLogicalUnary(const ElementwiseUnaryQueueDescriptor &descriptor, const WorkloadInfo &Info) const
virtual std::unique_ptr< IWorkload > CreateLogSoftmax(const LogSoftmaxQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateResizeBilinear(const ResizeBilinearQueueDescriptor &descriptor, const WorkloadInfo &info) const
std::vector< BackendOptions > ModelOptions
virtual std::unique_ptr< IWorkload > CreateStridedSlice(const StridedSliceQueueDescriptor &descriptor, const WorkloadInfo &Info) const
virtual std::unique_ptr< IWorkload > CreateStack(const StackQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateLstm(const LstmQueueDescriptor &descriptor, const WorkloadInfo &info) const
constexpr TransformIterator< Function, Iterator > MakeTransformIterator(Iterator i, Function f)
virtual std::unique_ptr< IWorkload > CreateFakeQuantization(const FakeQuantizationQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateQuantizedLstm(const QuantizedLstmQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateQLstm(const QLstmQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateConstant(const ConstantQueueDescriptor &descriptor, const WorkloadInfo &info) const
BackendRegistry & BackendRegistryInstance()
virtual std::unique_ptr< IWorkload > CreateElementwiseUnary(const ElementwiseUnaryQueueDescriptor &descriptor, const WorkloadInfo &Info) const
std::vector< float > boxEncodings({ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f })
virtual std::unique_ptr< IWorkload > CreateAbs(const AbsQueueDescriptor &descriptor, const WorkloadInfo &info) const
Copyright (c) 2020 ARM Limited.
virtual std::unique_ptr< IWorkload > CreateActivation(const ActivationQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateRsqrt(const RsqrtQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateTranspose(const TransposeQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateDivision(const DivisionQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateConvertFp32ToBf16(const ConvertFp32ToBf16QueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateMaximum(const MaximumQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateConcat(const ConcatQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateMerge(const MergeQueueDescriptor &descriptor, const WorkloadInfo &info) const
armnn::Optional< armnn::DataType > GetBiasTypeFromWeightsType(armnn::Optional< armnn::DataType > weightsType)
virtual std::unique_ptr< IWorkload > CreateConvertBf16ToFp32(const ConvertBf16ToFp32QueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateEqual(const EqualQueueDescriptor &descriptor, const WorkloadInfo &Info) const
virtual std::unique_ptr< IWorkload > CreateRank(const RankQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateDetectionPostProcess(const DetectionPostProcessQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateResize(const ResizeQueueDescriptor &descriptor, const WorkloadInfo &info) const
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15
virtual std::unique_ptr< IWorkload > CreateQuantize(const QuantizeQueueDescriptor &descriptor, const WorkloadInfo &Info) const
virtual std::unique_ptr< IWorkload > CreateSwitch(const SwitchQueueDescriptor &descriptor, const WorkloadInfo &Info) const
virtual std::unique_ptr< IWorkload > CreatePad(const PadQueueDescriptor &descriptor, const WorkloadInfo &Info) const
#define ARMNN_ASSERT(COND)
Definition: Assert.hpp:14
static bool IsLayerSupported(const BackendId &backendId, const IConnectableLayer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)
virtual std::unique_ptr< IWorkload > CreateNormalization(const NormalizationQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateLogicalBinary(const LogicalBinaryQueueDescriptor &descriptor, const WorkloadInfo &Info) const
virtual std::unique_ptr< IWorkload > CreateReshape(const ReshapeQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreatePermute(const PermuteQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateFill(const FillQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateComparison(const ComparisonQueueDescriptor &descriptor, const WorkloadInfo &Info) const
virtual std::unique_ptr< IWorkload > CreatePooling2d(const Pooling2dQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateSpaceToDepth(const SpaceToDepthQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateGather(const GatherQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateConvertFp32ToFp16(const ConvertFp32ToFp16QueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateMinimum(const MinimumQueueDescriptor &descriptor, const WorkloadInfo &info) const
std::vector< float > scores({ 0.0f, 0.9f, 0.8f, 0.0f, 0.75f, 0.72f, 0.0f, 0.6f, 0.5f, 0.0f, 0.93f, 0.95f, 0.0f, 0.5f, 0.4f, 0.0f, 0.3f, 0.2f })
virtual std::unique_ptr< IWorkload > CreateDepthToSpace(const DepthToSpaceQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateSlice(const SliceQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateAddition(const AdditionQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateTransposeConvolution2d(const TransposeConvolution2dQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateMean(const MeanQueueDescriptor &descriptor, const WorkloadInfo &Info) const
virtual std::unique_ptr< IWorkload > CreateOutput(const OutputQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateSoftmax(const SoftmaxQueueDescriptor &descriptor, const WorkloadInfo &info) const
Contains information about inputs and outputs to a layer.
virtual std::unique_ptr< IWorkload > CreateFullyConnected(const FullyConnectedQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateDepthwiseConvolution2d(const DepthwiseConvolution2dQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateFloor(const FloorQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateMemImport(const MemImportQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateSubtraction(const SubtractionQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreatePreCompiled(const PreCompiledQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateConvertFp16ToFp32(const ConvertFp16ToFp32QueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreateConvolution2d(const Convolution2dQueueDescriptor &descriptor, const WorkloadInfo &info) const
virtual std::unique_ptr< IWorkload > CreatePrelu(const PreluQueueDescriptor &descriptor, const WorkloadInfo &info) const
std::vector< float > anchors({ 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 10.5f, 1.0f, 1.0f, 0.5f, 10.5f, 1.0f, 1.0f, 0.5f, 100.5f, 1.0f, 1.0f })
virtual std::unique_ptr< IWorkload > CreateDequantize(const DequantizeQueueDescriptor &descriptor, const WorkloadInfo &info) const