ArmNN
 26.07
AvgPool2DIgnoreValueOperator.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 "Pooling2DOperator.hpp"
7 
8 TosaSerializationBasicBlock* ConvertAvgPool2DIgnoreValueToTosaOperator(const Layer* layer,
9  const std::vector<const TensorInfo*>& inputs,
10  const std::vector<const TensorInfo*>& outputs,
11  const Pooling2dDescriptor* poolDescriptor)
12 {
13  std::string padInputName = std::string("input_");
14  std::string padOutputName = std::string("layer_intermediate0_") + GetUniqueTosaMappingID();
15  std::string poolOutputName = std::string("output0_");
16  std::string blockName = std::string("Op_AVG_POOL2D_block_") + GetUniqueTosaMappingID();
17 
18  // If a layer is present then the block will be used for execution, so input and output names need to be determined
19  // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter.
20  if(layer != nullptr)
21  {
22  padInputName = GenerateUniqueInputName(layer->GetInputSlot(0));
23  poolOutputName = GenerateUniqueOutputName(*layer);
24  }
25 
26  std::vector<int> paddings;
27  if (poolDescriptor->m_DataLayout == DataLayout::NHWC)
28  {
29  paddings = {0,
30  0,
31  static_cast<int>(poolDescriptor->m_PadTop),
32  static_cast<int>(poolDescriptor->m_PadBottom),
33  static_cast<int>(poolDescriptor->m_PadLeft),
34  static_cast<int>(poolDescriptor->m_PadRight),
35  0,
36  0
37  };
38  }
39  else
40  {
41  paddings = {0,
42  0,
43  0,
44  0,
45  static_cast<int>(poolDescriptor->m_PadTop),
46  static_cast<int>(poolDescriptor->m_PadBottom),
47  static_cast<int>(poolDescriptor->m_PadLeft),
48  static_cast<int>(poolDescriptor->m_PadRight)
49  };
50  }
51 
52  std::vector<TosaSerializationTensor*> tensors;
53  std::vector<TosaSerializationOperator*> operators;
54 
55  TosaPadAttribute padAttribute(paddings, 0, 0.0f);
56  operators.push_back(new TosaSerializationOperator(Op_PAD,
57  Attribute_PadAttribute,
58  &padAttribute,
59  {padInputName},
60  {padOutputName}));
61 
62  std::vector<int> pad = {0, 0, 0, 0};
63  std::vector<int> kernel = {static_cast<int>(poolDescriptor->m_PoolHeight),
64  static_cast<int>(poolDescriptor->m_PoolWidth)};
65  std::vector<int> stride = {static_cast<int>(poolDescriptor->m_StrideY),
66  static_cast<int>(poolDescriptor->m_StrideX)};
67  std::vector<int> dilation = {1, 1};
68 
69  std::vector<int32_t> inputShape = GetTosaTensorShape(inputs[0]->GetShape());
70  DType inputDType = ArmNNToDType(inputs[0]->GetDataType());
71  std::string sliceOutputName = GetInputSlicedToItsUsedSize(inputShape,
72  padOutputName,
73  poolDescriptor->m_DataLayout,
74  inputDType,
75  kernel,
76  pad,
77  stride,
78  dilation,
79  tensors,
80  operators,
81  true);
82 
83  TosaPoolAttribute poolAttribute(pad, kernel, stride, 0, 0, ArmNNToDType(inputs[0]->GetDataType()));
84 
85  operators.push_back(new TosaSerializationOperator(Op_AVG_POOL2D,
86  Attribute_PoolAttribute,
87  &poolAttribute,
88  {sliceOutputName},
89  {poolOutputName}));
90 
91  // Only add input tensors if connected layer is an input layer.
92  // As intermediate or constant tensors will be created separately.
93  // There also can't be duplicate tensor.
94  if(padInputName.find("input_") != std::string::npos)
95  {
96  tensors.push_back(new TosaSerializationTensor(padInputName, inputShape, inputDType, {}));
97  }
98 
99  std::vector<int32_t> outputShape = GetTosaTensorShape(outputs[0]->GetShape());
100  DType outputDType = ArmNNToDType(outputs[0]->GetDataType());
101 
102  std::vector<int32_t> intermediateShape;
103  if (poolDescriptor->m_DataLayout == DataLayout::NHWC)
104  {
105  intermediateShape = {inputShape[0],
106  inputShape[1] + paddings[2] + paddings[3],
107  inputShape[2] + paddings[4] + paddings[5],
108  inputShape[3]};
109  }
110  else
111  {
112  intermediateShape = {inputShape[0],
113  inputShape[1],
114  inputShape[2] + paddings[4] + paddings[5],
115  inputShape[3] + paddings[6] + paddings[7]};
116  }
117 
118  tensors.push_back(new TosaSerializationTensor(padOutputName, intermediateShape, inputDType, {}));
119  tensors.push_back(new TosaSerializationTensor(poolOutputName, outputShape, outputDType, {}));
120 
121  // operatorInputNames/operatorOutputNames ends up being the same as
122  // blockInputNames/blockOutputNames for one-to-one ArmNN to TOSA mappings
123  return new TosaSerializationBasicBlock(blockName, // name
124  mainName, // region name
125  operators, // operators
126  tensors, // tensors
127  {padInputName}, // inputs
128  {poolOutputName}); // outputs
129 }
TosaSerializationBasicBlock * ConvertAvgPool2DIgnoreValueToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const Pooling2dDescriptor *poolDescriptor)
std::string GenerateUniqueOutputName(const Layer &layer, uint32_t layerSlot=0)
const std::string mainName
DType ArmNNToDType(const DataType &type)
std::vector< int32_t > GetTosaTensorShape(const TensorShape &shape)
std::string GenerateUniqueInputName(const armnn::InputSlot &slot)
std::string GetInputSlicedToItsUsedSize(const std::vector< int32_t > &inputShape, const std::string &inputName, const DataLayout layout, const DType datatype, const std::vector< int32_t > &kernel, const std::vector< int32_t > &pad, const std::vector< int32_t > &stride, const std::vector< int32_t > &dilations, std::vector< TosaSerializationTensor * > &tensors, std::vector< TosaSerializationOperator * > &operators, const bool isPoolingOp=false)
std::string GetUniqueTosaMappingID()
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
Definition: Layer.hpp:337
A Pooling2dDescriptor for the Pooling2dLayer.
uint32_t m_PadRight
Padding right value in the width dimension.
uint32_t m_PoolHeight
Pooling height value.
uint32_t m_PadTop
Padding top value in the height dimension.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
uint32_t m_PoolWidth
Pooling width value.
uint32_t m_PadBottom
Padding bottom value in the height dimension.
uint32_t m_PadLeft
Padding left value in the width dimension.
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.