13 #include <boost/numeric/conversion/cast.hpp> 27 case PoolingAlgorithm::Max:
29 return std::numeric_limits<float>::lowest();
31 case PoolingAlgorithm::Average:
32 case PoolingAlgorithm::L2:
43 using Accumulator = std::function<void(float & accu, float value)>;
49 case PoolingAlgorithm::Max:
51 return [](
float & accu,
float value) {
58 case PoolingAlgorithm::Average:
60 return [](
float & accu,
float value) {
65 case PoolingAlgorithm::L2:
67 return [](
float & accu,
float value) {
68 accu += (value*value);
79 using Executor = std::function<void(float & accumulated, float kernelSize)>;
85 case PoolingAlgorithm::Max:
87 return [](
float & ,
float ) {};
90 case PoolingAlgorithm::Average:
92 return [](
float & accumulated,
float kernelSize) {
93 accumulated /= kernelSize;
97 case PoolingAlgorithm::L2:
99 return [](
float & accumulated,
float kernelSize) {
100 accumulated = sqrtf(accumulated / kernelSize);
111 bool OnPaddingOnly(
int start,
int end,
int maxRange)
113 if (end <= 0 || start > maxRange)
124 bool ClampRange(
int & start,
int & end,
int maxRange)
126 if (start < 0 || end > maxRange)
128 start = std::min(std::max(start, 0), maxRange);
129 end = std::min(std::max(end, 0), maxRange);
169 float defaultInitializer = DefaultInitializer(params.
m_PoolType);
171 Accumulator accumulate = GetAccumulator(params.
m_PoolType);
172 Executor execute = GetExecutor(params.
m_PoolType);
185 for (
int n = 0; n < batchSize; n++)
187 for (
int c = 0; c < channels; c++)
189 for (
int yOutput = 0; yOutput < heightOutput; yOutput++)
192 int hstart = (yOutput * strideY) - padTop;
193 int hend = hstart + poolHeight;
196 hend = std::min(hend, heightInput + padBottom);
198 int height = hend - hstart;
199 bool hclamped = ClampRange(hstart, hend, heightInput);
201 for (
int xOutput = 0; xOutput < widthOutput; xOutput++)
203 int wstart = (xOutput * strideX) - padLeft;
204 int wend = wstart + poolWidth;
208 wend = std::min(wend, widthInput + padRight);
210 float result = defaultInitializer;
218 if (OnPaddingOnly(hstart, hend, heightInput) ||
219 OnPaddingOnly(wstart, wend, widthInput))
223 unsigned int outputIndex = dataLayout.
GetIndex(outputShape,
224 boost::numeric_cast<unsigned int>(n),
225 boost::numeric_cast<unsigned int>(c),
226 boost::numeric_cast<unsigned int>(yOutput),
227 boost::numeric_cast<unsigned int>(xOutput));
228 rOutputEncoder[outputIndex];
229 rOutputEncoder.
Set(result);
233 bool clamped = hclamped |= ClampRange(wstart, wend, widthInput);
242 for (
auto yInput = hstart; yInput < hend; yInput++)
244 for (
auto xInput = wstart; xInput < wend; xInput++)
246 unsigned int inputIndex = dataLayout.
GetIndex(inputShape,
247 boost::numeric_cast<unsigned int>(n),
248 boost::numeric_cast<unsigned int>(c),
249 boost::numeric_cast<unsigned int>(yInput),
250 boost::numeric_cast<unsigned int>(xInput));
252 rInputDecoder[inputIndex];
253 float inval = rInputDecoder.
Get();
255 accumulate(result, inval);
259 execute(result, poolAreaSize);
261 unsigned int outputIndex = dataLayout.
GetIndex(outputShape,
262 boost::numeric_cast<unsigned int>(n),
263 boost::numeric_cast<unsigned int>(c),
264 boost::numeric_cast<unsigned int>(yOutput),
265 boost::numeric_cast<unsigned int>(xOutput));
267 rOutputEncoder[outputIndex];
268 rOutputEncoder.
Set(result);
uint32_t m_PadBottom
Padding bottom value in the height dimension.
unsigned int GetWidthIndex() const
const TensorShape & GetShape() const
uint32_t m_PadLeft
Padding left value in the width dimension.
uint32_t m_PoolWidth
Pooling width value.
virtual void Set(IType right)=0
PaddingMethod m_PaddingMethod
The padding method to be used. (Exclude, IgnoreValue).
uint32_t m_PadTop
Padding top value in the height dimension.
Copyright (c) 2020 ARM Limited.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
unsigned int GetHeightIndex() const
virtual IType Get() const =0
uint32_t m_PoolHeight
Pooling height value.
uint32_t m_PadRight
Padding right value in the width dimension.
Provides access to the appropriate indexes for Channels, Height and Width based on DataLayout...
unsigned int GetIndex(const armnn::TensorShape &shape, unsigned int batchIndex, unsigned int channelIndex, unsigned int heightIndex, unsigned int widthIndex) const
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
PoolingAlgorithm m_PoolType
The pooling algorithm to use (Max. Average, L2).
A Pooling2dDescriptor for the Pooling2dLayer.
void Pooling2d(Decoder< float > &rInputDecoder, Encoder< float > &rOutputEncoder, const TensorInfo &inputInfo, const TensorInfo &outputInfo, const Pooling2dDescriptor ¶ms)
Computes the Pooling2d operation.
unsigned int GetChannelsIndex() const
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.