ArmNN
 25.02
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TosaMappings.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2022-2024 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "TosaMappings.hpp"
7 
8 using namespace armnn;
9 using namespace tosa;
10 
11 TosaSerializationBasicBlock* CreateEmptyTosaSerializationBasicBlock()
12 {
13  // Empty basic block when no TOSA mapping implemented/exists
14  auto* op = new TosaSerializationOperator(Op_UNKNOWN, Attribute_NONE, nullptr, {}, {});
15  return new TosaSerializationBasicBlock("", "", {op}, {}, {}, {});
16 }
17 
18 TosaSerializationBasicBlock* GetTosaMapping(const Layer* layer,
19  const LayerType type,
20  const std::vector<const TensorInfo*>& inputs,
21  const std::vector<const TensorInfo*>& outputs,
22  const BaseDescriptor& descriptor)
23 {
24  switch (type)
25  {
27  {
28  auto activationDesc = PolymorphicDowncast<const ActivationDescriptor*>(&descriptor);
29  switch (activationDesc->m_Function)
30  {
32  {
33  return ConvertLeakyReluToTosaOperator(layer, inputs, outputs, activationDesc);
34  }
37  {
38  return ConvertReluToTosaOperator(layer, inputs, outputs, activationDesc);
39  }
41  {
42  return ConvertGeluToTosaOperator(layer, inputs, outputs, activationDesc);
43  }
45  {
46  return ConvertHardSwishToTosaOperator(layer, inputs, outputs, activationDesc);
47  }
49  {
50  return ConvertSigmoidToTosaOperator(layer, inputs, outputs, activationDesc);
51  }
53  {
54  return ConvertTanHToTosaOperator(layer, inputs, outputs, activationDesc);
55  }
56  default:
57  {
59  }
60  }
61  }
65  {
66  return ConvertElementwiseBinaryToTosaOperator(layer, type, inputs, outputs);
67  }
69  {
70  auto binaryDesc = PolymorphicDowncast<const ElementwiseBinaryDescriptor*>(&descriptor);
71  switch (binaryDesc->m_Operation)
72  {
74  return ConvertSquaredDifferenceToTosaOperator(layer, type, inputs, outputs, binaryDesc);
75  default:
76  return ConvertElementwiseBinaryToTosaOperator(layer, type, inputs, outputs, binaryDesc);
77  }
78  }
80  {
81  auto unaryDesc = PolymorphicDowncast<const ElementwiseUnaryDescriptor*>(&descriptor);
82  switch(unaryDesc->m_Operation)
83  {
85  {
86  return ConvertRsqrtOperator(layer, inputs, outputs, unaryDesc);
87  }
89  {
90  return ConvertExpOperator(layer, inputs, outputs, unaryDesc);
91  }
93  {
94  return ConvertLogOperator(layer, inputs, outputs, unaryDesc);
95  }
96  default:
97  {
99  }
100  }
101  }
103  {
104  auto batchMatMulDesc = PolymorphicDowncast<const BatchMatMulDescriptor*>(&descriptor);
105  return ConvertBatchMatMulToTosaOperator(layer, inputs, outputs, batchMatMulDesc);
106  }
107  case LayerType::Concat:
108  {
109  auto concatDesc = PolymorphicDowncast<const OriginsDescriptor*>(&descriptor);
110  return ConvertConcatToTosaOperator(layer, inputs, outputs, concatDesc);
111  }
112  case LayerType::Constant:
113  {
114  bool isDepthwiseConv2dWeights = false;
115  if(layer)
116  {
117  // The difference in layout of weights in Tensorflow/ArmNN and the layout
118  // described in TOSA means we must permute the weights from [1, H, W, C * M] to [H, W, C, M].
119  unsigned int slotIdx = layer->GetOutputSlot().GetConnection(0)->GetSlotIndex();
121  if(type == LayerType::DepthwiseConvolution2d && slotIdx == 1)
122  {
123  isDepthwiseConv2dWeights = true;
124  }
125  }
126  return ConvertConstantToTosaOperator(layer, outputs, isDepthwiseConv2dWeights);
127  }
129  {
130  auto conv2dDesc = PolymorphicDowncast<const Convolution2dDescriptor*>(&descriptor);
131  return ConvertConv2dToTosaOperator(layer, inputs, outputs, conv2dDesc);
132  }
134  {
135  auto conv3dDesc = PolymorphicDowncast<const Convolution3dDescriptor*>(&descriptor);
136  return ConvertConv3dToTosaOperator(layer, inputs, outputs, conv3dDesc);
137  }
139  {
140  auto conv2dDesc = PolymorphicDowncast<const DepthwiseConvolution2dDescriptor*>(&descriptor);
141  return ConvertDepthwiseConv2dToTosaOperator(layer, inputs, outputs, conv2dDesc);
142  }
144  {
145  auto desc = PolymorphicDowncast<const DepthToSpaceDescriptor*>(&descriptor);
146  return ConvertDepthToSpaceToTosaOperator(layer, inputs, outputs, desc);
147  }
149  {
150  auto fullyConnectedDesc = PolymorphicDowncast<const FullyConnectedDescriptor*>(&descriptor);
151  return ConvertFullyConnectedToTosaOperator(layer, inputs, outputs, fullyConnectedDesc);
152  }
153  case LayerType::Gather:
154  {
155  auto gatherDesc = PolymorphicDowncast<const GatherDescriptor*>(&descriptor);
156  return ConvertGatherToTosaOperator(layer, inputs, outputs, gatherDesc);
157  }
158  case LayerType::Pad:
159  {
160  auto padDesc = PolymorphicDowncast<const PadDescriptor*>(&descriptor);
161  return ConvertPadToTosaOperator(layer, inputs, outputs, padDesc);
162  }
164  {
165  auto poolDesc = PolymorphicDowncast<const Pooling2dDescriptor*>(&descriptor);
166 
167  bool avgPoolIgnoreValue =
168  (poolDesc->m_PoolType == PoolingAlgorithm::Average) &&
169  (poolDesc->m_PaddingMethod == PaddingMethod::IgnoreValue);
170 
171  if (poolDesc->m_PoolType == PoolingAlgorithm::L2)
172  {
174  }
175  else if (avgPoolIgnoreValue)
176  {
177  return ConvertAvgPool2DIgnoreValueToTosaOperator(layer, inputs, outputs, poolDesc);
178  }
179  else
180  {
181  return ConvertPooling2DToTosaOperator(layer, inputs, outputs, poolDesc);
182  }
183  }
184  case LayerType::Mean:
185  {
186  auto meanDesc = PolymorphicDowncast<const MeanDescriptor*>(&descriptor);
187 
188  ReduceDescriptor reduceDesc;
189  reduceDesc.m_KeepDims = meanDesc->m_KeepDims;
190  reduceDesc.m_vAxis = meanDesc->m_Axis;
192 
193  return ConvertReduceToTosaOperator(layer, inputs, outputs, &reduceDesc);
194  }
196  {
197  return ConvertDequantizeToTosaOperator(layer, inputs, outputs);
198  }
199  case LayerType::Quantize:
200  {
201  return ConvertQuantizeToTosaOperator(layer, inputs, outputs);
202  }
203  case LayerType::Reduce:
204  {
205  auto reduceDesc = PolymorphicDowncast<const ReduceDescriptor*>(&descriptor);
206  return ConvertReduceToTosaOperator(layer, inputs, outputs, reduceDesc);
207  }
208  case LayerType::Reshape:
209  {
210  auto reshapeDesc = PolymorphicDowncast<const ReshapeDescriptor*>(&descriptor);
211  return ConvertReshapeToTosaOperator(layer, inputs, outputs, reshapeDesc);
212  }
213  case LayerType::Resize:
214  {
215  auto resizeDesc = PolymorphicDowncast<const ResizeDescriptor*>(&descriptor);
216  return ConvertResizeToTosaOperator(layer, inputs, outputs, resizeDesc);
217  }
218  case LayerType::Slice:
219  {
220  auto sliceDesc = PolymorphicDowncast<const SliceDescriptor*>(&descriptor);
221  return ConvertSliceToTosaOperator(layer, inputs, outputs, sliceDesc);
222  }
223  case LayerType::Softmax:
224  {
225  auto softmaxDesc = PolymorphicDowncast<const SoftmaxDescriptor*>(&descriptor);
226  return ConvertSoftmaxToTosaOperator(layer, inputs, outputs, softmaxDesc);
227  }
228  case LayerType::Splitter:
229  {
230  auto splitDesc = PolymorphicDowncast<const SplitterDescriptor*>(&descriptor);
231  return ConvertSplitToTosaOperator(layer, inputs, outputs, splitDesc);
232  }
233  case LayerType::Stack:
234  {
235  auto stackDesc = PolymorphicDowncast<const StackDescriptor*>(&descriptor);
236  return ConvertStackToTosaOperator(layer, inputs, outputs, stackDesc);
237  }
239  {
240  auto sliceDesc = PolymorphicDowncast<const StridedSliceDescriptor*>(&descriptor);
241  return ConvertStridedSliceToTosaOperator(layer, inputs, outputs, sliceDesc);
242  }
244  {
245  auto transposeConv2dDesc = PolymorphicDowncast<const TransposeConvolution2dDescriptor*>(&descriptor);
246  return ConvertTransposeConv2dToTosaOperator(layer, inputs, outputs, transposeConv2dDesc);
247  }
249  {
250  auto transposeDesc = PolymorphicDowncast<const TransposeDescriptor*>(&descriptor);
251  return ConvertTransposeToTosaOperator(layer, inputs, outputs, transposeDesc);
252  }
253  default:
254  {
256  }
257  }
258 }
259 
260 TosaSerializationBasicBlock* GetTosaMappingFromLayer(const Layer* layer)
261 {
262  std::vector<const TensorInfo*> inputs;
263  for (auto inputSlot : layer->GetInputSlots())
264  {
265  inputs.push_back(&inputSlot.GetTensorInfo());
266  }
267 
268  std::vector<const TensorInfo*> outputs;
269  for (auto& outputSlot : layer->GetOutputSlots())
270  {
271  outputs.push_back(&outputSlot.GetTensorInfo());
272  }
273 
274  TosaSerializationBasicBlock* basicBlock = GetTosaMapping(layer,
275  layer->GetType(),
276  inputs,
277  outputs,
278  layer->GetParameters());
279  return basicBlock;
280 }
TosaSerializationBasicBlock * ConvertAvgPool2DIgnoreValueToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const Pooling2dDescriptor *poolDescriptor)
TosaSerializationBasicBlock * ConvertBatchMatMulToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const BatchMatMulDescriptor *descriptor)
TosaSerializationBasicBlock * ConvertConcatToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const OriginsDescriptor *concatDescriptor)
TosaSerializationBasicBlock * ConvertConstantToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &outputs, bool isDepthwiseConv2dWeights=false)
TosaSerializationBasicBlock * ConvertConv2dToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const Convolution2dDescriptor *conv2dDescriptor)
TosaSerializationBasicBlock * ConvertConv3dToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const Convolution3dDescriptor *conv3dDescriptor)
TosaSerializationBasicBlock * ConvertDepthToSpaceToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const DepthToSpaceDescriptor *descriptor)
TosaSerializationBasicBlock * ConvertDepthwiseConv2dToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const DepthwiseConvolution2dDescriptor *conv2dDescriptor)
TosaSerializationBasicBlock * ConvertDequantizeToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs)
TosaSerializationBasicBlock * ConvertElementwiseBinaryToTosaOperator(const Layer *layer, const LayerType type, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ElementwiseBinaryDescriptor *descriptor)
TosaSerializationBasicBlock * ConvertSquaredDifferenceToTosaOperator(const Layer *layer, const LayerType, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ElementwiseBinaryDescriptor *descriptor)
TosaSerializationBasicBlock * ConvertExpOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ElementwiseUnaryDescriptor *unaryDescriptor)
Definition: ExpOperator.cpp:13
TosaSerializationBasicBlock * ConvertFullyConnectedToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const FullyConnectedDescriptor *fcDescriptor)
TosaSerializationBasicBlock * ConvertGatherToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const GatherDescriptor *gatherDescriptor)
TosaSerializationBasicBlock * ConvertGeluToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ActivationDescriptor *desc)
TosaSerializationBasicBlock * ConvertHardSwishToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ActivationDescriptor *desc)
TosaSerializationBasicBlock * ConvertLeakyReluToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ActivationDescriptor *activationDescriptor)
TosaSerializationBasicBlock * ConvertLogOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ElementwiseUnaryDescriptor *unaryDescriptor)
Definition: LogOperator.cpp:13
TosaSerializationBasicBlock * ConvertPadToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const PadDescriptor *padDescriptor)
Definition: PadOperator.cpp:9
TosaSerializationBasicBlock * ConvertPooling2DToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const Pooling2dDescriptor *poolDescriptor)
TosaSerializationBasicBlock * ConvertQuantizeToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs)
TosaSerializationBasicBlock * ConvertReduceToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ReduceDescriptor *reduceDescriptor)
TosaSerializationBasicBlock * ConvertReluToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ActivationDescriptor *desc)
TosaSerializationBasicBlock * ConvertReshapeToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ReshapeDescriptor *reshapeDescriptor)
TosaSerializationBasicBlock * ConvertResizeToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ResizeDescriptor *resizeDescriptor)
TosaSerializationBasicBlock * ConvertRsqrtOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ElementwiseUnaryDescriptor *unaryDescriptor)
TosaSerializationBasicBlock * ConvertSigmoidToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ActivationDescriptor *desc)
TosaSerializationBasicBlock * ConvertSliceToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const SliceDescriptor *sliceDescriptor)
TosaSerializationBasicBlock * ConvertSoftmaxToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const SoftmaxDescriptor *softmaxDescriptor)
TosaSerializationBasicBlock * ConvertSplitToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const SplitterDescriptor *splitDescriptor)
TosaSerializationBasicBlock * ConvertStackToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const StackDescriptor *stackDescriptor)
TosaSerializationBasicBlock * ConvertStridedSliceToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const StridedSliceDescriptor *stridedSliceDescriptor)
TosaSerializationBasicBlock * ConvertTanHToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const ActivationDescriptor *desc)
TosaSerializationBasicBlock * GetTosaMapping(const Layer *layer, const LayerType type, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const BaseDescriptor &descriptor)
TosaSerializationBasicBlock * CreateEmptyTosaSerializationBasicBlock()
TosaSerializationBasicBlock * GetTosaMappingFromLayer(const Layer *layer)
TosaSerializationBasicBlock * ConvertTransposeConv2dToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const TransposeConvolution2dDescriptor *descriptor)
TosaSerializationBasicBlock * ConvertTransposeToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const TransposeDescriptor *transposeDescriptor)
Layer & GetOwningLayer() const
Definition: Layer.hpp:53
unsigned int GetSlotIndex() const override
Definition: Layer.hpp:54
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
Definition: Layer.hpp:339
virtual const BaseDescriptor & GetParameters() const override
If the layer has a descriptor return it.
Definition: Layer.hpp:378
const std::vector< OutputSlot > & GetOutputSlots() const
Definition: Layer.hpp:259
LayerType GetType() const override
Returns the armnn::LayerType of this layer.
Definition: Layer.hpp:286
const std::vector< InputSlot > & GetInputSlots() const
Definition: Layer.hpp:258
const InputSlot * GetConnection(unsigned int index) const override
Definition: Layer.cpp:83
Copyright (c) 2021 ARM Limited and Contributors.
@ IgnoreValue
The padding fields count, but are ignored.
@ BoundedReLu
min(a, max(b, input)) ReLu1 & ReLu6.
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below.
Definition: Types.hpp:494
Base class for all descriptors.
Definition: Descriptors.hpp:23
A ReduceDescriptor for the REDUCE operators.
bool m_KeepDims
if true then output shape has no change.
std::vector< uint32_t > m_vAxis
The indices of the dimensions to reduce.
ReduceOperation m_ReduceOperation
Specifies the reduction operation to execute.