ArmNN
 24.08
Pad.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017,2024 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "Pad.hpp"
7 
8 #include "BaseIterator.hpp"
9 #include "Decoders.hpp"
10 #include "Encoders.hpp"
11 
13 
14 #include <cmath>
15 #include <cstddef>
16 #include <functional>
17 #include <limits>
18 #include <cassert>
19 
20 namespace
21 {
22 
23 void FillOutputWithPadValue(armnn::Encoder<float>& outputData,
24  const float padValue,
25  const unsigned int numOutputElements)
26 {
27  for (unsigned int i = 0; i < numOutputElements; ++i)
28  {
29  outputData[i];
30  outputData.Set(padValue);
31  }
32 }
33 
34 } // anonymous namespace
35 
36 namespace armnn
37 {
38 
39 void Pad(const TensorInfo& inputInfo,
40  const TensorInfo& outputInfo,
41  const ITensorHandle* inputHandle,
42  ITensorHandle* outputHandle,
43  const PadQueueDescriptor& data)
44 {
45  auto padList = data.m_Parameters.m_PadList;
46  auto padValue = data.m_Parameters.m_PadValue;
47 
48  unsigned int numOutputElements = outputInfo.GetNumElements();
49 
50  TensorShape outputShape = outputInfo.GetShape();
51  TensorShape inputShape = inputInfo.GetShape();
52 
53  unsigned int numInputDimensions = inputShape.GetNumDimensions();
54 
55 #ifndef NDEBUG
56 
57  unsigned int numOutputDimensions = outputShape.GetNumDimensions();
58  assert(numInputDimensions == numOutputDimensions);
59 
60 #endif
61 
62  unsigned int inputBatches = 0;
63  unsigned int inputChannels = 0;
64  unsigned int inputHeight = 0;
65  unsigned int inputWidth = 0;
66  unsigned int inputDim5 = 0;
67 
68  unsigned int outputBatches = 0;
69  unsigned int outputChannels = 0;
70  unsigned int outputHeight = 0;
71  unsigned int outputWidth = 0;
72 
73  auto inputData = MakeDecoder<float>(inputInfo, inputHandle->Map());
74  auto outData = MakeEncoder<float>(outputInfo, outputHandle->Map());
75 
76  // Fill the output tensor with Pad value first
77  if (outputInfo.IsQuantized())
78  {
79  // For Quantized types Pad Value should not be quantized with scale and offset of the tensor info
80  auto temporaryInfo = TensorInfo(outputInfo.GetShape(), outputInfo.GetDataType(), 1.0f, 0);
81 
82  auto outputData = MakeEncoder<float>(temporaryInfo, outputHandle->Map());
83  FillOutputWithPadValue(*outputData, padValue, numOutputElements);
84  }
85  else
86  {
87  FillOutputWithPadValue(*outData, padValue, numOutputElements);
88  }
89 
90  Decoder<float>& input = *inputData;
91  Encoder<float>& output = *outData;
92 
93  switch(numInputDimensions) {
94 
95  case 1:
96  inputWidth = inputShape[0];
97  for (unsigned int w = 0; w < inputWidth ; w++)
98  {
99  input[w];
100  auto inputValue = input.Get();
101  auto outputIndex = w + padList[0].first;
102  output[outputIndex];
103  output.Set(inputValue);
104  }
105 
106  break;
107  case 2:
108  inputHeight = inputShape[0];
109  inputWidth = inputShape[1];
110  outputWidth = outputShape[1];
111 
112  for (unsigned int h = 0; h < inputHeight; h++)
113  {
114  for (unsigned int w = 0; w < inputWidth ; w++)
115  {
116  input[h * inputWidth + w];
117  auto inputValue = input.Get();
118  auto outputIndex = (h + padList[0].first) * outputWidth + (w + padList[1].first);
119  output[outputIndex];
120  output.Set(inputValue);
121  }
122  }
123 
124  break;
125  case 3:
126  inputChannels = inputShape[0];
127  inputHeight = inputShape[1];
128  inputWidth = inputShape[2];
129  outputHeight = outputShape[1];
130  outputWidth = outputShape[2];
131 
132  for (unsigned int c = 0; c < inputChannels; c++)
133  {
134  for (unsigned int h = 0; h < inputHeight; h++)
135  {
136  for (unsigned int w = 0; w < inputWidth ; w++)
137  {
138  input[c * inputHeight * inputWidth + h * inputWidth + w];
139  auto inputValue = input.Get();
140  auto outputIndex = (c + padList[0].first) * outputHeight * outputWidth
141  + (h + padList[1].first) * outputWidth
142  + (w + padList[2].first);
143  output[outputIndex];
144  output.Set(inputValue);
145  }
146  }
147  }
148 
149  break;
150  case 4:
151  inputBatches = inputShape[0];
152  inputChannels = inputShape[1];
153  inputHeight = inputShape[2];
154  inputWidth = inputShape[3];
155  outputChannels = outputShape[1];
156  outputHeight = outputShape[2];
157  outputWidth = outputShape[3];
158 
159  for (unsigned int b = 0; b < inputBatches; b++)
160  {
161  for (unsigned int c = 0; c < inputChannels; c++)
162  {
163  for (unsigned int h = 0; h < inputHeight; h++)
164  {
165  for (unsigned int w = 0; w < inputWidth ; w++)
166  {
167  input[b * inputChannels * inputHeight * inputWidth
168  + c * inputHeight * inputWidth
169  + h * inputWidth
170  + w];
171  auto inputValue = input.Get();
172  auto outputIndex = (b + padList[0].first)
173  * outputChannels * outputHeight * outputWidth
174  + (c + padList[1].first) * outputHeight * outputWidth
175  + (h + padList[2].first) * outputWidth
176  + (w + padList[3].first);
177  output[outputIndex];
178  output.Set(inputValue);
179  }
180  }
181  }
182  }
183  break;
184 
185  case 5:
186  inputBatches = inputShape[0];
187  inputChannels = inputShape[1];
188  inputHeight = inputShape[2];
189  inputWidth = inputShape[3];
190  inputDim5 = inputShape[4];
191 
192  outputBatches = outputShape[1];
193  outputChannels = outputShape[2];
194  outputHeight = outputShape[3];
195  outputWidth = outputShape[4];
196 
197  for (unsigned int b = 0; b < inputBatches; ++b)
198  {
199  for (unsigned int c = 0; c < inputChannels; ++c)
200  {
201  for (unsigned int h = 0; h < inputHeight; ++h)
202  {
203  for (unsigned int w = 0; w < inputWidth ; ++w)
204  {
205  for (unsigned int d = 0; d < inputDim5 ; ++d)
206  {
207  input[b * inputChannels * inputHeight * inputWidth * inputDim5
208  + c * inputHeight * inputWidth * inputDim5
209  + h * inputWidth * inputDim5
210  + d];
211 
212  auto inputValue = input.Get();
213 
214  auto outputIndex = (b + padList[0].first)
215  * outputBatches * outputChannels * outputHeight * outputWidth
216  + (c + padList[1].first) * outputChannels * outputHeight*outputWidth
217  + (h + padList[2].first) * outputHeight * outputWidth
218  + (w + padList[3].first) * outputWidth
219  + (d + padList[4].first);
220 
221  output[outputIndex];
222  output.Set(inputValue);
223  }
224  }
225  }
226  }
227  }
228  break;
229 
230  default:
231  break;
232  }
233 }
234 
235 } //namespace armnn
armnn::Decoder< float >
armnn::TensorInfo::GetNumElements
unsigned int GetNumElements() const
Definition: Tensor.hpp:198
armnn::Encoder::Set
virtual void Set(IType right)=0
BaseIterator.hpp
armnn::TensorInfo
Definition: Tensor.hpp:152
armnn::ITensorHandle
Definition: ITensorHandle.hpp:16
TensorUtils.hpp
armnn::TensorShape
Definition: Tensor.hpp:20
armnn::Encoder< float >
armnn::QueueDescriptorWithParameters::m_Parameters
LayerDescriptor m_Parameters
Definition: WorkloadData.hpp:66
armnn::TensorShape::GetNumDimensions
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
Definition: Tensor.cpp:174
armnn::TensorInfo::IsQuantized
bool IsQuantized() const
Definition: Tensor.cpp:508
armnn::PadDescriptor::m_PadValue
float m_PadValue
Optional value to use for padding, defaults to 0.
Definition: Descriptors.hpp:1221
armnn::TensorInfo::GetDataType
DataType GetDataType() const
Definition: Tensor.hpp:200
armnn::Decoder::Get
virtual IType Get() const =0
armnn::Pad
void Pad(const TensorInfo &inputInfo, const TensorInfo &outputInfo, const ITensorHandle *inputHandle, ITensorHandle *outputHandle, const PadQueueDescriptor &data)
Definition: Pad.cpp:39
armnn::TensorInfo::GetShape
const TensorShape & GetShape() const
Definition: Tensor.hpp:193
armnn::PadQueueDescriptor
Definition: WorkloadData.hpp:294
armnn::PadDescriptor::m_PadList
std::vector< std::pair< unsigned int, unsigned int > > m_PadList
Specifies the padding for input dimension.
Definition: Descriptors.hpp:1218
Pad.hpp
Decoders.hpp
armnn
Copyright (c) 2021 ARM Limited and Contributors.
Definition: 01_00_quick_start.dox:6
Encoders.hpp
armnn::ITensorHandle::Map
virtual const void * Map(bool blocking=true) const =0
Map the tensor data for access.