ArmNN
 26.07
TosaMappings.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2022-2025 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "TosaMappings.hpp"
10 
11 using namespace armnn;
12 using namespace tosa;
13 
14 TosaSerializationBasicBlock* CreateEmptyTosaSerializationBasicBlock()
15 {
16  // Empty basic block when no TOSA mapping implemented/exists
17  auto* op = new TosaSerializationOperator(Op_UNKNOWN, Attribute_NONE, nullptr, {}, {});
18  return new TosaSerializationBasicBlock("", "", {op}, {}, {}, {});
19 }
20 
21 TosaSerializationBasicBlock* GetTosaMapping(const Layer* layer,
22  const LayerType type,
23  const std::vector<const TensorInfo*>& inputs,
24  const std::vector<const TensorInfo*>& outputs,
25  const BaseDescriptor& descriptor)
26 {
27  switch (type)
28  {
30  {
31  auto activationDesc = PolymorphicDowncast<const ActivationDescriptor*>(&descriptor);
32  switch (activationDesc->m_Function)
33  {
35  {
36  return ConvertLeakyReluToTosaOperator(layer, inputs, outputs, activationDesc);
37  }
40  {
41  return ConvertReluToTosaOperator(layer, inputs, outputs, activationDesc);
42  }
44  {
45  return ConvertGeluToTosaOperator(layer, inputs, outputs, activationDesc);
46  }
48  {
49  return ConvertHardSwishToTosaOperator(layer, inputs, outputs, activationDesc);
50  }
52  {
53  return ConvertSigmoidToTosaOperator(layer, inputs, outputs, activationDesc);
54  }
56  {
57  return ConvertTanHToTosaOperator(layer, inputs, outputs, activationDesc);
58  }
59  default:
60  {
62  }
63  }
64  }
68  {
69  return ConvertElementwiseBinaryToTosaOperator(layer, type, inputs, outputs);
70  }
72  {
73  auto binaryDesc = PolymorphicDowncast<const ElementwiseBinaryDescriptor*>(&descriptor);
74  switch (binaryDesc->m_Operation)
75  {
77  return ConvertSquaredDifferenceToTosaOperator(layer, type, inputs, outputs, binaryDesc);
78  default:
79  return ConvertElementwiseBinaryToTosaOperator(layer, type, inputs, outputs, binaryDesc);
80  }
81  }
83  {
84  auto unaryDesc = PolymorphicDowncast<const ElementwiseUnaryDescriptor*>(&descriptor);
85  switch(unaryDesc->m_Operation)
86  {
88  {
89  return ConvertRsqrtOperator(layer, inputs, outputs, unaryDesc);
90  }
92  {
93  return ConvertExpOperator(layer, inputs, outputs, unaryDesc);
94  }
96  {
97  return ConvertLogOperator(layer, inputs, outputs, unaryDesc);
98  }
99  default:
100  {
102  }
103  }
104  }
106  {
107  auto batchMatMulDesc = PolymorphicDowncast<const BatchMatMulDescriptor*>(&descriptor);
108  return ConvertBatchMatMulToTosaOperator(layer, inputs, outputs, batchMatMulDesc);
109  }
111  {
112  auto batchToSpaceDesc = PolymorphicDowncast<const BatchToSpaceNdDescriptor*>(&descriptor);
113  return ConvertBatchToSpaceToTosaOperator(layer, inputs, outputs, batchToSpaceDesc);
114  }
115  case LayerType::Concat:
116  {
117  auto concatDesc = PolymorphicDowncast<const OriginsDescriptor*>(&descriptor);
118  return ConvertConcatToTosaOperator(layer, inputs, outputs, concatDesc);
119  }
120  case LayerType::Constant:
121  {
122  bool isDepthwiseConv2dWeights = false;
123  if(layer)
124  {
125  // The difference in layout of weights in Tensorflow/ArmNN and the layout
126  // described in TOSA means we must permute the weights from [1, H, W, C * M] to [H, W, C, M].
127  unsigned int slotIdx = layer->GetOutputSlot().GetConnection(0)->GetSlotIndex();
129  if(type == LayerType::DepthwiseConvolution2d && slotIdx == 1)
130  {
131  isDepthwiseConv2dWeights = true;
132  }
133  }
134  return ConvertConstantToTosaOperator(layer, outputs, isDepthwiseConv2dWeights);
135  }
137  {
138  auto conv2dDesc = PolymorphicDowncast<const Convolution2dDescriptor*>(&descriptor);
139  return ConvertConv2dToTosaOperator(layer, inputs, outputs, conv2dDesc);
140  }
142  {
143  auto conv3dDesc = PolymorphicDowncast<const Convolution3dDescriptor*>(&descriptor);
144  return ConvertConv3dToTosaOperator(layer, inputs, outputs, conv3dDesc);
145  }
147  {
148  auto conv2dDesc = PolymorphicDowncast<const DepthwiseConvolution2dDescriptor*>(&descriptor);
149  return ConvertDepthwiseConv2dToTosaOperator(layer, inputs, outputs, conv2dDesc);
150  }
152  {
153  auto desc = PolymorphicDowncast<const DepthToSpaceDescriptor*>(&descriptor);
154  return ConvertDepthToSpaceToTosaOperator(layer, inputs, outputs, desc);
155  }
157  {
158  auto fullyConnectedDesc = PolymorphicDowncast<const FullyConnectedDescriptor*>(&descriptor);
159  return ConvertFullyConnectedToTosaOperator(layer, inputs, outputs, fullyConnectedDesc);
160  }
161  case LayerType::Gather:
162  {
163  auto gatherDesc = PolymorphicDowncast<const GatherDescriptor*>(&descriptor);
164  return ConvertGatherToTosaOperator(layer, inputs, outputs, gatherDesc);
165  }
166  case LayerType::Pad:
167  {
168  auto padDesc = PolymorphicDowncast<const PadDescriptor*>(&descriptor);
169  return ConvertPadToTosaOperator(layer, inputs, outputs, padDesc);
170  }
172  {
173  auto poolDesc = PolymorphicDowncast<const Pooling2dDescriptor*>(&descriptor);
174 
175  bool avgPoolIgnoreValue =
176  (poolDesc->m_PoolType == PoolingAlgorithm::Average) &&
177  (poolDesc->m_PaddingMethod == PaddingMethod::IgnoreValue);
178 
179  if (poolDesc->m_PoolType == PoolingAlgorithm::L2)
180  {
182  }
183  else if (avgPoolIgnoreValue)
184  {
185  return ConvertAvgPool2DIgnoreValueToTosaOperator(layer, inputs, outputs, poolDesc);
186  }
187  else
188  {
189  return ConvertPooling2DToTosaOperator(layer, inputs, outputs, poolDesc);
190  }
191  }
192  case LayerType::Mean:
193  {
194  auto meanDesc = PolymorphicDowncast<const MeanDescriptor*>(&descriptor);
195 
196  ReduceDescriptor reduceDesc;
197  reduceDesc.m_KeepDims = meanDesc->m_KeepDims;
198  reduceDesc.m_vAxis = meanDesc->m_Axis;
200 
201  return ConvertReduceToTosaOperator(layer, inputs, outputs, &reduceDesc);
202  }
204  {
205  return ConvertDequantizeToTosaOperator(layer, inputs, outputs);
206  }
207  case LayerType::Quantize:
208  {
209  return ConvertQuantizeToTosaOperator(layer, inputs, outputs);
210  }
211  case LayerType::Prelu:
212  {
213  return ConvertPReluToTosaOperator(layer, inputs, outputs);
214  }
215  case LayerType::Reduce:
216  {
217  auto reduceDesc = PolymorphicDowncast<const ReduceDescriptor*>(&descriptor);
218  return ConvertReduceToTosaOperator(layer, inputs, outputs, reduceDesc);
219  }
220  case LayerType::Reshape:
221  {
222  auto reshapeDesc = PolymorphicDowncast<const ReshapeDescriptor*>(&descriptor);
223  return ConvertReshapeToTosaOperator(layer, inputs, outputs, reshapeDesc);
224  }
225  case LayerType::Resize:
226  {
227  auto resizeDesc = PolymorphicDowncast<const ResizeDescriptor*>(&descriptor);
228  return ConvertResizeToTosaOperator(layer, inputs, outputs, resizeDesc);
229  }
230  case LayerType::Slice:
231  {
232  auto sliceDesc = PolymorphicDowncast<const SliceDescriptor*>(&descriptor);
233  return ConvertSliceToTosaOperator(layer, inputs, outputs, sliceDesc);
234  }
235  case LayerType::Softmax:
236  {
237  auto softmaxDesc = PolymorphicDowncast<const SoftmaxDescriptor*>(&descriptor);
238  return ConvertSoftmaxToTosaOperator(layer, inputs, outputs, softmaxDesc);
239  }
240  case LayerType::Splitter:
241  {
242  auto splitDesc = PolymorphicDowncast<const SplitterDescriptor*>(&descriptor);
243  return ConvertSplitToTosaOperator(layer, inputs, outputs, splitDesc);
244  }
246  {
247  auto spaceToBatchDesc = PolymorphicDowncast<const SpaceToBatchNdDescriptor*>(&descriptor);
248  return ConvertSpaceToBatchToTosaOperator(layer, inputs, outputs, spaceToBatchDesc);
249  }
250  case LayerType::Stack:
251  {
252  auto stackDesc = PolymorphicDowncast<const StackDescriptor*>(&descriptor);
253  return ConvertStackToTosaOperator(layer, inputs, outputs, stackDesc);
254  }
256  {
257  auto sliceDesc = PolymorphicDowncast<const StridedSliceDescriptor*>(&descriptor);
258  return ConvertStridedSliceToTosaOperator(layer, inputs, outputs, sliceDesc);
259  }
261  {
262  auto transposeConv2dDesc = PolymorphicDowncast<const TransposeConvolution2dDescriptor*>(&descriptor);
263  return ConvertTransposeConv2dToTosaOperator(layer, inputs, outputs, transposeConv2dDesc);
264  }
266  {
267  auto transposeDesc = PolymorphicDowncast<const TransposeDescriptor*>(&descriptor);
268  return ConvertTransposeToTosaOperator(layer, inputs, outputs, transposeDesc);
269  }
270  default:
271  {
273  }
274  }
275 }
276 
277 TosaSerializationBasicBlock* GetTosaMappingFromLayer(const Layer* layer)
278 {
279  std::vector<const TensorInfo*> inputs;
280  for (auto const& inputSlot : layer->GetInputSlots())
281  {
282  inputs.emplace_back(&inputSlot.GetTensorInfo());
283  }
284 
285  std::vector<const TensorInfo*> outputs;
286  for (auto& outputSlot : layer->GetOutputSlots())
287  {
288  outputs.emplace_back(&outputSlot.GetTensorInfo());
289  }
290 
291  TosaSerializationBasicBlock* basicBlock = GetTosaMapping(layer,
292  layer->GetType(),
293  inputs,
294  outputs,
295  layer->GetParameters());
296 
297  return basicBlock;
298 }
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 * ConvertBatchToSpaceToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const BatchToSpaceNdDescriptor *batchToSpaceDescriptor)
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 * ConvertPReluToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs)
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 * ConvertSpaceToBatchToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const SpaceToBatchNdDescriptor *spaceToBatchDescriptor)
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.