ArmNN
 22.08
EthosnRefPooling2d.hpp
Go to the documentation of this file.
1 #pragma once
3 
4 #include <armnn/Descriptors.hpp>
5 #include <armnn/Tensor.hpp>
6 
8 #include "EthosnRefConvImpl.hpp"
9 
10 #include <armnn/Exceptions.hpp>
11 
13 
15 
16 #include <limits>
17 #include <algorithm>
18 #include <functional>
19 #include <cmath>
20 
21 namespace armnn
22 {
23 
24 constexpr std::pair<unsigned int, unsigned int> GetAccumulationLimits(const unsigned int i,
25  const unsigned int inputSize,
26  const unsigned int padBefore,
27  const unsigned int poolSize,
28  const unsigned int stride)
29 {
30  const unsigned int start = std::max(i * stride, padBefore) - padBefore;
31  const unsigned int end = std::min(std::max((i * stride) + poolSize, padBefore) - padBefore, inputSize);
32 
33  return { start, end };
34 }
35 
36 // Computes the Pooling2d operation.
37 template<typename InputType>
39  const InputType* inputData)
40 {
41 
42  const TensorInfo& inputInfo = armnn::ethosnref::GetTensorInfo(data.m_Inputs[0]);
43  const TensorInfo& outputInfo = armnn::ethosnref::GetTensorInfo(data.m_Outputs[0]);
44 
45  TensorBufferArrayView<InputType> output(outputInfo.GetShape(),
46  armnn::ethosnref::GetOutputTensorData<InputType>(0, data),
48 
50  auto channelsIndex = dataLayout.GetChannelsIndex();
51  auto heightIndex = dataLayout.GetHeightIndex();
52  auto widthIndex = dataLayout.GetWidthIndex();
53 
54  const unsigned int batchSize = outputInfo.GetShape()[0];
55  const unsigned int channels = outputInfo.GetShape()[channelsIndex];
56  const unsigned int outputHeight = outputInfo.GetShape()[heightIndex];
57  const unsigned int outputWidth = outputInfo.GetShape()[widthIndex];
58  const unsigned int inputHeight = inputInfo.GetShape()[heightIndex];
59  const unsigned int inputWidth = inputInfo.GetShape()[widthIndex];
60  const unsigned int paddingLeft = data.m_Parameters.m_PadLeft;
61  const unsigned int paddingTop = data.m_Parameters.m_PadTop;
62  const PaddingMethod method = data.m_Parameters.m_PaddingMethod;
63  const unsigned int strideX = data.m_Parameters.m_StrideX;
64  const unsigned int strideY = data.m_Parameters.m_StrideY;
65  const unsigned int poolHeight = data.m_Parameters.m_PoolHeight;
66  const unsigned int poolWidth = data.m_Parameters.m_PoolWidth;
67 
68  unsigned int inputDataStrides[4] = {};
70  {
71  inputDataStrides[0] = inputHeight * inputWidth * channels;
72  inputDataStrides[1] = 1;
73  inputDataStrides[2] = inputWidth * channels;
74  inputDataStrides[3] = channels;
75  }
76  else
77  {
78  inputDataStrides[0] = inputWidth * inputHeight * channels;
79  inputDataStrides[1] = inputWidth * inputHeight;
80  inputDataStrides[2] = inputWidth;
81  inputDataStrides[3] = 1;
82  }
83 
85 
86  for (unsigned int n = 0; n < batchSize; ++n)
87  {
88  for (unsigned int c = 0; c < channels; ++c)
89  {
90  for (unsigned int yOutput = 0; yOutput < outputHeight; ++yOutput)
91  {
92  for (unsigned int xOutput = 0; xOutput < outputWidth; ++xOutput)
93  {
94  int result = 0;
95  int poolAreaSize = numeric_cast<int>(poolWidth * poolHeight);
96 
97  const auto ySpan = GetAccumulationLimits(yOutput, inputHeight, paddingTop, poolHeight, strideY);
98  const auto xSpan = GetAccumulationLimits(xOutput, inputWidth, paddingLeft, poolWidth, strideX);
99 
100  for (auto yInput = ySpan.first; yInput < ySpan.second; ++yInput)
101  {
102  for (auto xInput = xSpan.first; xInput < xSpan.second; ++xInput)
103  {
104  unsigned int inputIndex = n * inputDataStrides[0] +
105  c * inputDataStrides[1] +
106  yInput * inputDataStrides[2] +
107  xInput * inputDataStrides[3];
108 
109  result += numeric_cast<int>(inputData[inputIndex]);
110  }
111  }
112 
113  if (method == PaddingMethod::Exclude)
114  {
115  poolAreaSize = numeric_cast<int>((xSpan.second - xSpan.first) * (ySpan.second - ySpan.first));
116  }
117 
118  result = (result + (poolAreaSize / 2)) / poolAreaSize;
119 
120  output.Get(n, c, yOutput, xOutput) = numeric_cast<InputType>(result);
121  }
122  }
123  }
124  }
125 }
126 } //namespace armnn
unsigned int GetWidthIndex() const
const TensorShape & GetShape() const
Definition: Tensor.hpp:191
uint32_t m_PadLeft
Padding left value in the width dimension.
uint32_t m_PoolWidth
Pooling width value.
The padding fields don&#39;t count and are ignored.
PaddingMethod m_PaddingMethod
The padding method to be used. (Exclude, IgnoreValue).
uint32_t m_PadTop
Padding top value in the height dimension.
constexpr std::pair< unsigned int, unsigned int > GetAccumulationLimits(const unsigned int i, const unsigned int inputSize, const unsigned int padBefore, const unsigned int poolSize, const unsigned int stride)
Copyright (c) 2021 ARM Limited and Contributors.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
unsigned int GetHeightIndex() const
DataType & Get(unsigned int b, unsigned int c, unsigned int h, unsigned int w) const
PaddingMethod
The padding method modifies the output of pooling layers.
Definition: Types.hpp:174
uint32_t m_PoolHeight
Pooling height value.
const TensorInfo & GetTensorInfo(const ITensorHandle *tensorHandle)
Provides access to the appropriate indexes for Channels, Height and Width based on DataLayout...
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
void EthosnRefPooling2d(const Pooling2dQueueDescriptor &data, const InputType *inputData)
PoolingAlgorithm m_PoolType
The pooling algorithm to use (Max. Average, L2).
std::vector< ITensorHandle * > m_Outputs
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
Definition: NumericCast.hpp:35
std::vector< ITensorHandle * > m_Inputs
unsigned int GetChannelsIndex() const
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.