Compute Library
 21.02
PoolingLayer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2020 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #include "PoolingLayer.h"
25 
26 #include "arm_compute/core/Types.h"
29 
30 namespace arm_compute
31 {
32 namespace test
33 {
34 namespace validation
35 {
36 namespace reference
37 {
39 
40 template <typename T, typename ACC_T, typename std::enable_if<is_floating_point<T>::value, int>::type>
42 {
43  ARM_COMPUTE_ERROR_ON(info.is_global_pooling && (src.shape().x() != src.shape().y()));
44  // Create reference
45  SimpleTensor<T> dst{ compute_pool_shape(TensorInfo(src.shape(), 1, src.data_type()), info), src.data_type(), 1 };
46  auto pooled_shape = compute_pool_shape(TensorInfo(src.shape(), 1, src.data_type()), info);
47  if(indices)
48  {
49  *indices = SimpleTensor<uint32_t> { pooled_shape, DataType::U32, 1 };
50  }
51  const int pool_size_x = info.is_global_pooling ? src.shape().x() : info.pool_size.width;
52  const int pool_size_y = info.is_global_pooling ? src.shape().y() : info.pool_size.height;
53  PoolingType type = info.pool_type;
54  int pool_stride_x = info.pad_stride_info.stride().first;
55  int pool_stride_y = info.pad_stride_info.stride().second;
56  int pad_left = info.pad_stride_info.pad_left();
57  int pad_top = info.pad_stride_info.pad_top();
58  int pad_right = info.pad_stride_info.pad_right();
59  int pad_bottom = info.pad_stride_info.pad_bottom();
60  bool exclude_padding = info.exclude_padding;
61 
62  const auto w_src = static_cast<int>(src.shape()[0]);
63  const auto h_src = static_cast<int>(src.shape()[1]);
64  const auto z_src = static_cast<int>(src.shape()[2]);
65  const auto b_src = static_cast<int>(src.shape()[3]);
66 
67  const int upper_dims = src.shape().total_size() / (w_src * h_src);
68 
69  const auto w_dst = static_cast<int>(dst.shape()[0]);
70  const auto h_dst = static_cast<int>(dst.shape()[1]);
71  const auto z_dst = static_cast<int>(dst.shape()[2]);
72 
73  TensorShape shape_nhwc(src.shape());
74  permute(shape_nhwc, PermutationVector(2U, 0U, 1U));
75  if(type == PoolingType::MAX)
76  {
77  for(int b = 0; b < b_src; ++b)
78  {
79  for(int r = 0; r < z_src; ++r)
80  {
81  for(int h = 0; h < h_dst; ++h)
82  {
83  for(int w = 0; w < w_dst; ++w)
84  {
85  int wstart = w * pool_stride_x - pad_left;
86  int hstart = h * pool_stride_y - pad_top;
87  int wend = std::min(wstart + pool_size_x, w_src);
88  int hend = std::min(hstart + pool_size_y, h_src);
89  wstart = std::max(wstart, 0);
90  hstart = std::max(hstart, 0);
91  auto max_val = std::numeric_limits<ACC_T>::lowest();
92  int max_index{ 0 };
93  for(int y = hstart; y < hend; ++y)
94  {
95  for(int x = wstart; x < wend; ++x)
96  {
97  const auto val = static_cast<ACC_T>(src[b * z_src * h_src * w_src + r * h_src * w_src + y * w_src + x]);
98  if(val > max_val)
99  {
100  max_val = val;
101  if(data_layout == DataLayout::NCHW)
102  {
103  max_index = coord2index(src.shape(), Coordinates(x, y, r, 0));
104  }
105  else
106  {
107  max_index = coord2index(shape_nhwc, Coordinates(r, x, y, 0));
108  }
109  }
110  }
111  }
112 
113  dst[b * z_dst * h_dst * w_dst + r * h_dst * w_dst + h * w_dst + w] = static_cast<T>(max_val);
114  if(indices)
115  {
116  (*indices)[b * z_dst * h_dst * w_dst + r * h_dst * w_dst + h * w_dst + w] = max_index;
117  }
118  }
119  }
120  }
121  }
122  }
123  else // Average or l2 pooling
124  {
125  for(int r = 0; r < upper_dims; ++r)
126  {
127  for(int h = 0; h < h_dst; ++h)
128  {
129  for(int w = 0; w < w_dst; ++w)
130  {
131  ACC_T avg_val(0);
132  int wstart = w * pool_stride_x - pad_left;
133  int hstart = h * pool_stride_y - pad_top;
134  int wend = std::min(wstart + pool_size_x, w_src + pad_right);
135  int hend = std::min(hstart + pool_size_y, h_src + pad_bottom);
136  int pool = (hend - hstart) * (wend - wstart);
137  wstart = std::max(wstart, 0);
138  hstart = std::max(hstart, 0);
139  wend = std::min(wend, w_src);
140  hend = std::min(hend, h_src);
141  // Exclude padding pixels from the average
142  if(exclude_padding)
143  {
144  pool = (hend - hstart) * (wend - wstart);
145  }
146 
147  if(type == PoolingType::AVG)
148  {
149  for(int y = hstart; y < hend; ++y)
150  {
151  for(int x = wstart; x < wend; ++x)
152  {
153  avg_val += static_cast<ACC_T>(src[r * h_src * w_src + y * w_src + x]);
154  }
155  }
156  dst[r * h_dst * w_dst + h * w_dst + w] = avg_val / pool;
157  }
158  else
159  {
160  for(int y = hstart; y < hend; ++y)
161  {
162  for(int x = wstart; x < wend; ++x)
163  {
164  const auto val = static_cast<ACC_T>(src[r * h_src * w_src + y * w_src + x]);
165  avg_val += val * val;
166  }
167  }
168  dst[r * h_dst * w_dst + h * w_dst + w] = static_cast<T>(std::sqrt(avg_val / pool));
169  }
170  }
171  }
172  }
173  }
174  return dst;
175 }
176 
178 
180 
182 
183 template <typename T>
185 {
186  ARM_COMPUTE_UNUSED(output_qinfo);
187  return pooling_layer_internal<T, T>(src, info, indices, data_layout);
188 }
189 
190 template <>
193 {
196  SimpleTensor<uint8_t> dst = convert_to_asymmetric<uint8_t>(dst_tmp, output_qinfo);
197  return dst;
198 }
199 
200 template <>
202 {
205  SimpleTensor<int8_t> dst = convert_to_asymmetric<int8_t>(dst_tmp, output_qinfo);
206  return dst;
207 }
208 
209 template <>
211 {
212  ARM_COMPUTE_UNUSED(output_qinfo);
213  if(src.data_type() == DataType::F16 && info.fp_mixed_precision)
214  {
216  }
217 
219 }
220 
222 
223 } // namespace reference
224 } // namespace validation
225 } // namespace test
226 } // namespace arm_compute
SimpleTensor< float > w
Definition: DFT.cpp:156
Shape of a tensor.
Definition: TensorShape.h:39
SimpleTensor< float > b
Definition: DFT.cpp:157
DataType data_type() const override
Data type of the tensor.
Definition: SimpleTensor.h:357
Strides PermutationVector
Permutation vector.
Definition: Types.h:49
SimpleTensor< T > permute(const SimpleTensor< T > &src, PermutationVector perm)
Definition: Permute.cpp:38
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
const DataLayout data_layout
Definition: Im2Col.cpp:151
SimpleTensor< float > convert_from_asymmetric(const SimpleTensor< uint8_t > &src)
Definition: Helpers.cpp:112
TensorShape shape() const override
Shape of the tensor.
Definition: SimpleTensor.h:320
unsigned int pad_top() const
Get the top padding.
Definition: Types.h:806
decltype(strategy::transforms) typedef type
SimpleTensor< float > src
Definition: DFT.cpp:155
int pool_stride_x
Copyright (c) 2017-2021 Arm Limited.
int coord2index(const TensorShape &shape, const Coordinates &coord)
Linearise the given coordinate.
Definition: Utils.h:489
size_t height
Height of the image region or rectangle.
Definition: Size2D.h:90
1 channel, 1 F16 per channel
TensorShape compute_pool_shape(const ITensorInfo &input, PoolingLayerInfo pool_info)
Calculate the output pool shape of a tensor.
template SimpleTensor< half > pooling_layer_internal< half >(const SimpleTensor< half > &src, const PoolingLayerInfo &info, SimpleTensor< uint32_t > *indices, DataLayout data_layout)
Quantization information.
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:152
1 channel, 1 U32 per channel
Coordinates of an item.
Definition: Coordinates.h:37
std::pair< unsigned int, unsigned int > stride() const
Get the stride.
Definition: Types.h:770
Pooling Layer Information struct.
Definition: Types.h:1214
unsigned int pad_right() const
Get the right padding.
Definition: Types.h:801
template SimpleTensor< float > pooling_layer_internal< float >(const SimpleTensor< float > &src, const PoolingLayerInfo &info, SimpleTensor< uint32_t > *indices, DataLayout data_layout)
template SimpleTensor< half > pooling_layer_internal< half, float >(const SimpleTensor< half > &src, const PoolingLayerInfo &info, SimpleTensor< uint32_t > *indices, DataLayout data_layout)
SimpleTensor< uint8_t > pooling_layer< uint8_t >(const SimpleTensor< uint8_t > &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo, SimpleTensor< uint32_t > *indices, DataLayout data_layout)
Num samples, channels, height, width.
Simple tensor object that stores elements in a consecutive chunk of memory.
Definition: SimpleTensor.h:58
SimpleTensor< T > pooling_layer_internal(const SimpleTensor< T > &src, const PoolingLayerInfo &info, SimpleTensor< uint32_t > *indices, DataLayout data_layout)
PoolingType
Available pooling types.
Definition: Types.h:610
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
PadStrideInfo pad_stride_info
Definition: Types.h:1302
SimpleTensor< int8_t > pooling_layer< int8_t >(const SimpleTensor< int8_t > &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo, SimpleTensor< uint32_t > *indices, DataLayout data_layout)
size_t width
Width of the image region or rectangle.
Definition: Size2D.h:89
SimpleTensor< T > pooling_layer(const SimpleTensor< T > &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo, SimpleTensor< uint32_t > *indices, DataLayout data_layout)
Store the tensor&#39;s metadata.
Definition: TensorInfo.h:45
unsigned int pad_bottom() const
Get the bottom padding.
Definition: Types.h:811
unsigned int pad_left() const
Get the left padding.
Definition: Types.h:796
DataLayout
[DataLayout enum definition]
Definition: Types.h:120