blob: f58dbaea615d5c61f44e94bbc5e4c640bd3809f1 [file] [log] [blame]
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "Pad.hpp"
Sadik Armagan041b3c02020-06-04 10:32:18 +01007
8#include "BaseIterator.hpp"
9#include "Decoders.hpp"
David Monahan34757812019-06-19 11:47:21 +010010#include "Encoders.hpp"
11
Sadik Armagan041b3c02020-06-04 10:32:18 +010012#include <armnnUtils/TensorUtils.hpp>
13
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010014#include <cmath>
15#include <cstddef>
16#include <functional>
17#include <limits>
18#include <cassert>
19
Sadik Armagan041b3c02020-06-04 10:32:18 +010020namespace
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
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010036namespace armnn
37{
David Monahan34757812019-06-19 11:47:21 +010038
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010039void Pad(const TensorInfo& inputInfo,
40 const TensorInfo& outputInfo,
Finn Williams01097942021-04-26 12:06:34 +010041 const ITensorHandle* inputHandle,
42 ITensorHandle* outputHandle,
Sadik Armagan041b3c02020-06-04 10:32:18 +010043 const PadQueueDescriptor& data)
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010044{
Sadik Armagan041b3c02020-06-04 10:32:18 +010045 auto padList = data.m_Parameters.m_PadList;
46 auto padValue = data.m_Parameters.m_PadValue;
47
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010048 unsigned int numOutputElements = outputInfo.GetNumElements();
49
50 TensorShape outputShape = outputInfo.GetShape();
Sadik Armagan041b3c02020-06-04 10:32:18 +010051 TensorShape inputShape = inputInfo.GetShape();
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010052
53 unsigned int numInputDimensions = inputShape.GetNumDimensions();
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010054
Sadik Armagan041b3c02020-06-04 10:32:18 +010055#ifndef NDEBUG
Mohamed Nour Abouelseouddd6acea2018-10-18 12:26:19 +010056
57 unsigned int numOutputDimensions = outputShape.GetNumDimensions();
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010058 assert(numInputDimensions == numOutputDimensions);
Mohamed Nour Abouelseouddd6acea2018-10-18 12:26:19 +010059
Sadik Armagan041b3c02020-06-04 10:32:18 +010060#endif
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010061
Sadik Armagan041b3c02020-06-04 10:32:18 +010062 unsigned int inputBatches = 0;
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010063 unsigned int inputChannels = 0;
Sadik Armagan041b3c02020-06-04 10:32:18 +010064 unsigned int inputHeight = 0;
65 unsigned int inputWidth = 0;
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010066
67 unsigned int outputChannels = 0;
Sadik Armagan041b3c02020-06-04 10:32:18 +010068 unsigned int outputHeight = 0;
69 unsigned int outputWidth = 0;
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010070
Finn Williams01097942021-04-26 12:06:34 +010071 auto inputData = MakeDecoder<float>(inputInfo, inputHandle->Map());
72 auto outData = MakeEncoder<float>(outputInfo, outputHandle->Map());
David Monahan34757812019-06-19 11:47:21 +010073
Sadik Armagan041b3c02020-06-04 10:32:18 +010074 // Fill the output tensor with Pad value first
75 if (outputInfo.IsQuantized())
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010076 {
Sadik Armagan041b3c02020-06-04 10:32:18 +010077 // For Quantized types Pad Value should not be quantized with scale and offset of the tensor info
78 auto temporaryInfo = TensorInfo(outputInfo.GetShape(), outputInfo.GetDataType(), 1.0f, 0);
Finn Williams01097942021-04-26 12:06:34 +010079 auto outputData = MakeEncoder<float>(temporaryInfo, outputHandle->Map());
Sadik Armagan041b3c02020-06-04 10:32:18 +010080 FillOutputWithPadValue(*outputData, padValue, numOutputElements);
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010081 }
Sadik Armagan041b3c02020-06-04 10:32:18 +010082 else
83 {
84 FillOutputWithPadValue(*outData, padValue, numOutputElements);
85 }
86
87 Decoder<float>& input = *inputData;
88 Encoder<float>& output = *outData;
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010089
90 switch(numInputDimensions) {
Mohamed Nour Abouelseouddd6acea2018-10-18 12:26:19 +010091
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010092 case 1:
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010093 inputWidth = inputShape[0];
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +010094 for (unsigned int w = 0; w < inputWidth ; w++)
95 {
Sadik Armagan041b3c02020-06-04 10:32:18 +010096 input[w];
97 auto inputValue = input.Get();
98 auto outputIndex = w + std::get<0>(padList[0]);
99 output[outputIndex];
100 output.Set(inputValue);
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100101 }
102
103 break;
104 case 2 :
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100105 inputHeight = inputShape[0];
Sadik Armagan041b3c02020-06-04 10:32:18 +0100106 inputWidth = inputShape[1];
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100107 outputWidth = outputShape[1];
108
109 for (unsigned int h = 0; h < inputHeight; h++)
110 {
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100111 for (unsigned int w = 0; w < inputWidth ; w++)
112 {
Sadik Armagan041b3c02020-06-04 10:32:18 +0100113 input[h * inputWidth + w];
114 auto inputValue = input.Get();
115 auto outputIndex = (h + std::get<0>(padList[0])) * outputWidth + (w + std::get<0>(padList[1]));
116 output[outputIndex];
117 output.Set(inputValue);
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100118 }
119 }
120
121 break;
122 case 3 :
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100123 inputChannels = inputShape[0];
Sadik Armagan041b3c02020-06-04 10:32:18 +0100124 inputHeight = inputShape[1];
125 inputWidth = inputShape[2];
126 outputHeight = outputShape[1];
127 outputWidth = outputShape[2];
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100128
129 for (unsigned int c = 0; c < inputChannels; c++)
130 {
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100131 for (unsigned int h = 0; h < inputHeight; h++)
132 {
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100133 for (unsigned int w = 0; w < inputWidth ; w++)
134 {
Sadik Armagan041b3c02020-06-04 10:32:18 +0100135 input[c * inputHeight * inputWidth + h * inputWidth + w];
136 auto inputValue = input.Get();
137 auto outputIndex = (c + std::get<0>(padList[0])) * outputHeight * outputWidth
138 + (h + std::get<0>(padList[1])) * outputWidth
139 + (w + std::get<0>(padList[2]));
140 output[outputIndex];
141 output.Set(inputValue);
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100142 }
143 }
144 }
145
146 break;
147 case 4 :
Sadik Armagan041b3c02020-06-04 10:32:18 +0100148 inputBatches = inputShape[0];
149 inputChannels = inputShape[1];
150 inputHeight = inputShape[2];
151 inputWidth = inputShape[3];
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100152 outputChannels = outputShape[1];
Sadik Armagan041b3c02020-06-04 10:32:18 +0100153 outputHeight = outputShape[2];
154 outputWidth = outputShape[3];
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100155
156 for (unsigned int b = 0; b < inputBatches; b++)
157 {
158 for (unsigned int c = 0; c < inputChannels; c++)
159 {
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100160 for (unsigned int h = 0; h < inputHeight; h++)
161 {
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100162 for (unsigned int w = 0; w < inputWidth ; w++)
163 {
Sadik Armagan041b3c02020-06-04 10:32:18 +0100164 input[b * inputChannels * inputHeight * inputWidth
165 + c * inputHeight * inputWidth
166 + h * inputWidth
167 + w];
168 auto inputValue = input.Get();
169 auto outputIndex = (b + std::get<0>(padList[0]))
170 * outputChannels * outputHeight * outputWidth
171 + (c + std::get<0>(padList[1])) * outputHeight * outputWidth
172 + (h + std::get<0>(padList[2])) * outputWidth
173 + (w + std::get<0>(padList[3]));
174 output[outputIndex];
175 output.Set(inputValue);
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100176 }
177 }
178 }
179 }
180
181 break;
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100182 default :
183 break;
184 }
Mohamed Nour Abouelseoud7420e552018-10-12 12:26:24 +0100185}
186
Mohamed Nour Abouelseouddd6acea2018-10-18 12:26:19 +0100187} //namespace armnn