ArmNN
 22.11
TosaRefLayerSupport.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
8 
9 #include <armnn/Types.hpp>
12 #include <LayerSupportCommon.hpp>
13 
14 #include <vector>
15 #include <array>
16 
17 namespace armnn
18 {
19 
20 static bool IsTosaLayerSupported(TosaSerializationOperator* op,
21  const std::vector<TosaSerializationTensor*>& inputs,
22  const std::vector<TosaSerializationTensor*>& outputs,
23  Optional<string&> reasonIfUnsupported)
24 {
25  switch(op->GetOp())
26  {
27  case tosa::Op_ADD:
28  {
29  bool supported = true;
30 
31  std::array<Attribute, 1> supportedAttributes =
32  {
33  Attribute_NONE
34  };
35 
36  // Check Attribute from operator (GetAttribute)
37  supported &= CheckSupportRule(TosaOperatorAttributeOfAny(op, supportedAttributes), reasonIfUnsupported,
38  std::string("TOSA Reference addition: operator has an unsupported attribute.").c_str());
39 
40  std::array<DType, 9> supportedTypes =
41  {
42  DType_BOOL,
43  DType_UINT8,
44  DType_UINT16,
45  DType_INT4,
46  DType_INT8,
47  DType_INT16,
48  DType_INT32,
49  DType_FP16,
50  DType_FP32
51  };
52 
53  for (auto tensor : inputs)
54  {
55  // Check Dtype from tensor (GetDtype)
56  supported &= CheckSupportRule(TosaTypeAnyOf(tensor, supportedTypes),
57  reasonIfUnsupported,
58  std::string("TOSA Reference addition: " + tensor->GetName() +
59  " is not a supported type.").c_str());
60 
61  // Check Shape from tensor (GetShape)
63  reasonIfUnsupported,
64  std::string("Tosa Reference addition: " + tensor->GetName() + " Shape.Size()"
65  " outside bounds of between Zero and MaxNumOfTensorDimensions.").c_str());
66  }
67 
68  // Check Dtype from tensor (GetDtype)
69  supported &= CheckSupportRule(TosaTypeAnyOf(outputs[0], supportedTypes),
70  reasonIfUnsupported,
71  std::string("TOSA Reference addition: " + outputs[0]->GetName() +
72  " is not a supported type.").c_str());
73 
74  // Check Shape from tensor (GetShape)
76  reasonIfUnsupported,
77  std::string("Tosa Reference addition: " + outputs[0]->GetName() + " Shape.Size()"
78  " outside bounds of between Zero and MaxNumOfTensorDimensions.").c_str());
79 
80  return supported;
81  }
82  default:
83  SetValueChecked(reasonIfUnsupported, "Operation is currently unsupported by the TOSA Reference Backend.");
84  return false;
85  }
86 }
87 
89  const std::vector<TensorInfo>& infos,
90  const BaseDescriptor& descriptor,
91  const Optional<LstmInputParamsInfo>& lstmParamsInfo,
92  const Optional<QuantizedLstmInputParamsInfo>& quantizedLstmInputParamsInfo,
93  Optional<std::string&> reasonIfUnsupported) const
94 {
95  IgnoreUnused(lstmParamsInfo);
96  IgnoreUnused(quantizedLstmInputParamsInfo);
97 
98  std::vector<const TensorInfo*> inputInfos;
99  std::vector<const TensorInfo*> outputInfos;
100 
101  switch (type)
102  {
103  case LayerType::Addition:
104  // Setup inputs and outputs
105  inputInfos.push_back(&infos[0]);
106  inputInfos.push_back(&infos[1]);
107  outputInfos.push_back(&infos[2]);
108  break;
109  case LayerType::Input:
110  case LayerType::Output:
111  return true;
112  default:
113  break;
114  }
115 
116  auto mappings = GetTosaMapping(type, inputInfos, outputInfos, descriptor, false);
117  if (mappings->GetName() == "")
118  {
119  // There currently isn't a TOSA mapping for this layer, as the default was returned.
120  return false;
121  }
122 
123  // Loop through block and get each tensor and operator
124  for (long unsigned int i = 0; i < mappings->GetOperators().size(); ++i)
125  {
126  // While looping over operators check for op_UNKNOWN which is unsupported
127  if (mappings->GetOperators()[i]->GetOp() == tosa::Op_UNKNOWN) { return false; }
128 
129  // Loop over operators and get GetInput/OutputTensorNames, loop over resulting names and
130  // use GetTensorByName to pass pointers to tensors on to the IsTosaLayerSupported()
131  std::vector<TosaSerializationTensor*> inputTensorsVect;
132  for (const auto& name : mappings->GetOperators()[i]->GetInputTensorNames())
133  {
134  inputTensorsVect.push_back(mappings->GetTensorByName(name));
135  }
136 
137  std::vector<TosaSerializationTensor*> outputTensorsVect;
138  for (const auto& name : mappings->GetOperators()[i]->GetOutputTensorNames())
139  {
140  outputTensorsVect.push_back(mappings->GetTensorByName(name));
141  }
142 
143  if (!IsTosaLayerSupported(mappings->GetOperators()[i],
144  inputTensorsVect,
145  outputTensorsVect,
147  {
148  return false;
149  }
150  }
151  return true;
152 }
153 
154 } // namespace armnn
bool IsLayerSupported(const LayerType &type, const std::vector< TensorInfo > &infos, const BaseDescriptor &descriptor, const Optional< LstmInputParamsInfo > &lstmParamsInfo, const Optional< QuantizedLstmInputParamsInfo > &, Optional< std::string &> reasonIfUnsupported) const override
const TensorInfo const ActivationDescriptor Optional< std::string & > reasonIfUnsupported
Copyright (c) 2021 ARM Limited and Contributors.
TosaSerializationBasicBlock * GetTosaMapping(const LayerType type, const std::vector< const TensorInfo *> &inputs, const std::vector< const TensorInfo *> &outputs, const BaseDescriptor &, bool isMain=false)
void IgnoreUnused(Ts &&...)
Base class for all descriptors.
Definition: Descriptors.hpp:22
void SetValueChecked(Optional< T &> optionalRef, V &&val)
bool CheckSupportRule(F rule, Optional< std::string &> reasonIfUnsupported, const char *reason)
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below...
Definition: Types.hpp:468