ArmNN
 25.11
Loading...
Searching...
No Matches
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
20namespace
21{
22
23void 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
36namespace armnn
37{
38
39void 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
virtual IType Get() const =0
virtual void Set(IType right)=0
virtual const void * Map(bool blocking=true) const =0
Map the tensor data for access.
const TensorShape & GetShape() const
Definition Tensor.hpp:193
bool IsQuantized() const
Definition Tensor.cpp:508
unsigned int GetNumElements() const
Definition Tensor.hpp:198
DataType GetDataType() const
Definition Tensor.hpp:200
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
Definition Tensor.cpp:174
Copyright (c) 2021 ARM Limited and Contributors.
std::unique_ptr< Decoder< T > > MakeDecoder(const TensorInfo &info, const void *data=nullptr)
std::unique_ptr< Encoder< T > > MakeEncoder(const TensorInfo &info, void *data=nullptr)
float m_PadValue
Optional value to use for padding, defaults to 0.
std::vector< std::pair< unsigned int, unsigned int > > m_PadList
Specifies the padding for input dimension.