26 case PoolingAlgorithm::Max:
28 return std::numeric_limits<float>::lowest();
30 case PoolingAlgorithm::Average:
31 case PoolingAlgorithm::L2:
42 using Accumulator = std::function<void(
float & accu,
float value)>;
48 case PoolingAlgorithm::Max:
50 return [](
float & accu,
float value) {
57 case PoolingAlgorithm::Average:
59 return [](
float & accu,
float value) {
64 case PoolingAlgorithm::L2:
66 return [](
float & accu,
float value) {
67 accu += (value*value);
78 using Executor = std::function<void(
float & accumulated,
float kernelSize)>;
84 case PoolingAlgorithm::Max:
86 return [](
float & ,
float ) {};
89 case PoolingAlgorithm::Average:
91 return [](
float & accumulated,
float kernelSize) {
92 accumulated /= kernelSize;
96 case PoolingAlgorithm::L2:
98 return [](
float & accumulated,
float kernelSize) {
99 accumulated = sqrtf(accumulated / kernelSize);
110 bool OnPaddingOnly(
int start,
int end,
int maxRange)
112 if (end <= 0 || start > maxRange)
123 bool ClampRange(
int & start,
int & end,
int maxRange)
125 if (start < 0 || end > maxRange)
127 start = std::min(std::max(start, 0), maxRange);
128 end = std::min(std::max(end, 0), maxRange);
153 const int batchSize = armnn::numeric_cast<int>(outputInfo.
GetShape()[0]);
154 const int channels = armnn::numeric_cast<int>(outputInfo.
GetShape()[channelsIndex]);
155 const int heightOutput = armnn::numeric_cast<int>(outputInfo.
GetShape()[heightIndex]);
156 const int widthOutput = armnn::numeric_cast<int>(outputInfo.
GetShape()[widthIndex]);
157 const int heightInput = armnn::numeric_cast<int>(inputInfo.
GetShape()[heightIndex]);
158 const int widthInput = armnn::numeric_cast<int>(inputInfo.
GetShape()[widthIndex]);
159 const int padLeft = armnn::numeric_cast<int>(params.
m_PadLeft);
160 const int padRight = armnn::numeric_cast<int>(params.
m_PadRight);
161 const int padTop = armnn::numeric_cast<int>(params.
m_PadTop);
162 const int padBottom = armnn::numeric_cast<int>(params.
m_PadBottom);
163 const int strideX = armnn::numeric_cast<int>(params.
m_StrideX);
164 const int strideY = armnn::numeric_cast<int>(params.
m_StrideY);
165 const int poolHeight = armnn::numeric_cast<int>(params.
m_PoolHeight);
166 const int poolWidth = armnn::numeric_cast<int>(params.
m_PoolWidth);
168 float defaultInitializer = DefaultInitializer(params.
m_PoolType);
170 Accumulator accumulate = GetAccumulator(params.
m_PoolType);
171 Executor execute = GetExecutor(params.
m_PoolType);
183 for (
int n = 0; n < batchSize; n++)
185 for (
int c = 0; c < channels; c++)
187 for (
int yOutput = 0; yOutput < heightOutput; yOutput++)
190 int hstart = (yOutput * strideY) - padTop;
191 int hend = hstart + poolHeight;
194 hend = std::min(hend, heightInput + padBottom);
196 int height = hend - hstart;
197 bool hclamped = ClampRange(hstart, hend, heightInput);
199 for (
int xOutput = 0; xOutput < widthOutput; xOutput++)
201 int wstart = (xOutput * strideX) - padLeft;
202 int wend = wstart + poolWidth;
206 wend = std::min(wend, widthInput + padRight);
208 float result = defaultInitializer;
209 float poolAreaSize = armnn::numeric_cast<float>(height * (wend - wstart));
216 if (OnPaddingOnly(hstart, hend, heightInput) ||
217 OnPaddingOnly(wstart, wend, widthInput))
225 outputIndex = n * heightOutput * widthOutput * channels +
226 yOutput * widthOutput * channels +
232 outputIndex = n * heightOutput * widthOutput * channels +
233 c * heightOutput * widthOutput +
234 yOutput * widthOutput +
238 rOutputEncoder[
static_cast<unsigned int>(outputIndex)];
239 rOutputEncoder.
Set(result);
243 bool clamped = hclamped |= ClampRange(wstart, wend, widthInput);
249 poolAreaSize = armnn::numeric_cast<float>((hend - hstart) * (wend - wstart));
252 for (
auto yInput = hstart; yInput < hend; yInput++)
254 for (
auto xInput = wstart; xInput < wend; xInput++)
260 inputIndex = n * heightInput * widthInput * channels +
261 yInput * widthInput * channels +
268 inputIndex = n * heightInput * widthInput * channels +
269 c * heightInput * widthInput +
270 yInput * widthInput +
274 accumulate(result, decodedInputVec[
static_cast<unsigned int>(inputIndex)]);
278 execute(result, poolAreaSize);
284 outputIndex = n * heightOutput * widthOutput * channels +
285 yOutput * widthOutput * channels +
291 outputIndex = n * heightOutput * widthOutput * channels +
292 c * heightOutput * widthOutput +
293 yOutput * widthOutput +
297 rOutputEncoder[
static_cast<unsigned int>(outputIndex)];
298 rOutputEncoder.
Set(result);