49 using GCPoolingConfig = std::pair<unsigned int, BorderSize>;
66 "Unsupported combination of parameters!");
73 "Global pooling is supported only with rectangular inputs!");
75 "Invalid pool size and pool pad combination!");
83 unsigned int pooled_w = 0;
84 unsigned int pooled_h = 0;
91 "Invalid output pooling dimensions!");
102 int pool_stride_y = 0;
103 unsigned int pooled_w = 0;
104 unsigned int pooled_h = 0;
107 std::tie(pool_pad_x, pool_pad_y) = pad_stride_info.
pad();
108 std::tie(pool_stride_x, pool_stride_y) = pad_stride_info.
stride();
122 auto_init(input, output, pooled_w, pooled_h);
136 const bool is_pool3x3_stride_le3 = (pool_size == 3) && (pool_stride_x <= 3);
138 int num_elems_read_per_iteration =
pool_size;
142 if(is_pool3x3_stride_le3)
145 num_elems_processed_per_iteration = 4;
146 num_elems_read_per_iteration = pool_size * (pool_stride_x + 1);
151 if(is_pool3x3_stride_le3)
153 num_elems_processed_per_iteration = 4;
157 num_elems_processed_per_iteration = 2;
161 const int upper_bound_w = ((pooled_w - 1) * pool_stride_x - pool_pad_x + num_elems_read_per_iteration) -
input_width;
162 const int upper_bound_h = ((pooled_h - 1) * pool_stride_y - pool_pad_y + pool_size) -
input_height;
164 border_size.
right = std::max(upper_bound_w, pool_pad_x);
165 border_size.
bottom = std::max(upper_bound_h, pool_pad_y);
171 num_elems_processed_per_iteration = 1;
175 num_elems_processed_per_iteration = 2;
178 const int upper_bound_w = ((pooled_w - 1) * pool_stride_x - pool_pad_x + pool_size) -
input_width;
179 const int upper_bound_h = ((pooled_h - 1) * pool_stride_y - pool_pad_y + pool_size) -
input_height;
181 border_size.
right = std::max(upper_bound_w, pool_pad_x);
182 border_size.
bottom = std::max(upper_bound_h, pool_pad_y);
194 return std::make_tuple(err, win, GCPoolingConfig(num_elems_processed_per_iteration, border_size));
199 const int output_width = output->
dimension(0);
200 const int output_height = output->
dimension(1);
201 const int output_padding_right =
ceil_to_multiple(output_width, num_elems_processed_per_iteration) - output_width;
202 const int output_padding_bottom =
ceil_to_multiple(output_height, 1) - output_height;
204 const int input_total_width = std::max(
int(input->
padding().
left),
int(pool_pad_x)) + input_width + std::max(
int(input->
padding().
right),
int(pool_pad_x));
205 const int input_padding_right =
ceil_to_multiple(input_total_width, num_elems_processed_per_iteration) - input_width - pool_pad_x;
206 const int input_total_height = std::max(
int(input->
padding().
top),
int(pool_pad_y)) + input_height + std::max(
int(input->
padding().
bottom),
int(pool_pad_y));
207 const int input_padding_bottom = input_total_height - input_height - pool_pad_y;
210 AccessWindowStatic input_access(input, -pool_pad_x, -pool_pad_y, input_width + input_padding_right, input_height + input_padding_bottom);
211 AccessWindowStatic output_access(output, 0, 0, output_width + output_padding_right, output_height + output_padding_bottom);
215 return std::make_tuple(err, win, GCPoolingConfig(num_elems_processed_per_iteration, border_size));
221 : _input(nullptr), _output(nullptr), _indices(nullptr), _pool_info(), _border_size(0), _num_elems_processed_per_iteration(1)
234 int pool_stride_x = 0;
235 int pool_stride_y = 0;
236 unsigned int pooled_w = 0;
237 unsigned int pooled_h = 0;
242 std::tie(pool_pad_x, pool_pad_y) = pad_stride_info.
pad();
243 std::tie(pool_stride_x, pool_stride_y) = pad_stride_info.
stride();
257 auto_init(input->
info(), output->
info(), pooled_w, pooled_h);
264 _pool_info = pool_info;
267 std::set<std::string> build_opts;
273 build_opts.insert(
"#define DATA_TYPE_FP32");
277 build_opts.insert(
"#define DATA_TYPE_FP16");
281 build_opts.emplace(
"#define EXCLUDE_PADDING");
292 if((pool_size == 2) || (pool_size == 3) || (pool_size == 7))
296 const bool is_pool3x3_stride_le3 = (pool_size == 3) && (pool_stride_x <= 3);
299 if(is_pool3x3_stride_le3)
301 build_opts.insert(
"#define POOLING_LAYER_3_OPTIMIZED");
314 build_opts.insert(
"#define POOLING_LAYER_N");
318 auto win_config = validate_and_configure_window(input->
info(), output->
info(), pool_info);
321 IGCKernel::configure(std::get<1>(win_config));
322 GCPoolingConfig pooling_config = std::get<2>(win_config);
323 _num_elems_processed_per_iteration = pooling_config.first;
324 _border_size = pooling_config.second;
340 unsigned int pool_pad_x;
341 unsigned int pool_pad_y;
343 unsigned int pool_stride_y;
361 Window in_slice(slice_in_orig);
366 unsigned int idx = 0;
370 _kernel.update_shader_params();
unsigned int top
top of the border
Window calculate_max_window(const ValidRegion &valid_region, const Steps &steps, bool skip_border, BorderSize border_size)
void configure(const IGCTensor *input, IGCTensor *output, const PoolingLayerInfo &pool_info, IGCTensor *indices=nullptr)
Set the input and output tensors.
const Window & window() const
The maximum window the kernel can be executed on.
void add_3D_tensor_argument(unsigned int &idx, const IGCTensor *tensor, const unsigned int binding_point, const Window &window)
Add the passed 3D tensor's parameters to the object's kernel's arguments starting from the index idx...
static Status validate(const ITensorInfo *input, const ITensorInfo *output, const PoolingLayerInfo &pool_info, const ITensorInfo *indices=nullptr)
Static function to check if given info will lead to a valid configuration of GCPoolingLayerKernel.
void enqueue(IGCKernel &kernel, const Window &window, const gles::NDRange &lws=gles::NDRange(1U, 1U, 1U))
Add the kernel to the command queue with the given window.
virtual size_t dimension(size_t index) const =0
Return the size of the requested dimension.
void shift(size_t dimension, int shift_value)
Shift the values of a given dimension by the given shift_value.
Container for 2D border size.
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
std::string to_string(T &&value)
Convert integer and float values to string.
virtual DataType data_type() const =0
Data type used for each element of the tensor.
1 channel, 1 F32 per channel
const size_t input_height
Store the tensor's metadata.
Interface for GLES Compute tensor.
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Describe one of the image's dimensions with a start, end and step.
unsigned int bottom
bottom of the border
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
Copyright (c) 2017-2021 Arm Limited.
size_t height
Height of the image region or rectangle.
1 channel, 1 F16 per channel
std::pair< unsigned int, unsigned int > scaled_dimensions(int width, int height, int kernel_width, int kernel_height, const PadStrideInfo &pad_stride_info, const Size2D &dilation=Size2D(1U, 1U))
Returns expected width and height of output scaled tensor depending on dimensions rounding mode...
Implementation of a static rectangular access pattern.
#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...)
T x() const
Alias to access the size of the first dimension.
static constexpr size_t DimX
Alias for dimension 0 also known as X dimension.
bool update_window_and_padding(Window &win, Ts &&... patterns)
Update window and padding size for each of the access patterns.
Window collapse_if_possible(const Window &full_window, size_t first, size_t last, bool *has_collapsed=nullptr) const
Collapse the dimensions between first and last if possible.
bool padding_is_symmetric() const
Check whether the padding is symmetric.
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
auto ceil_to_multiple(S value, T divisor) -> decltype(((value+divisor - 1)/divisor) *divisor)
Computes the smallest number larger or equal to value that is a multiple of divisor.
Manages all the GLES kernels compilation and caching, provides accessors for the GLES Context...
Class to describe a number of elements in each dimension.
void set_needs_shifting(bool needs_shifting)
Set the flag indicating whether or not a tensor needs shifting.
Implementation of a row access pattern.
std::pair< unsigned int, unsigned int > stride() const
Get the stride.
Pooling Layer Information struct.
BorderSize border_size() const override
The size of the border for that kernel.
bool auto_init_if_empty(ITensorInfo &info, const TensorShape &shape, int num_channels, DataType data_type, QuantizationInfo quantization_info=QuantizationInfo())
Auto initialize the tensor info (shape, number of channels and data type) if the current assignment i...
virtual std::unique_ptr< T > clone() const =0
Provide a clone of the current object of class T.
void run(const Window &window) override
Enqueue the OpenGL ES shader to process the given window.
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor's metadata.
Padding and stride information class.
void set(size_t dimension, const Dimension &dim)
Set the values of a given dimension.
virtual PaddingSize padding() const =0
Padding of tensor.
unsigned int left
left of the border
bool slide_window_slice_3D(Window &slice) const
Slide the passed 3D window slice.
unsigned int right
right of the border
#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k)
bool is_data_type_quantized_asymmetric(DataType dt)
Check if a given data type is of asymmetric quantized type.
static constexpr size_t DimY
Alias for dimension 1 also known as Y dimension.
Wrapper to configure the Khronos EGL and OpenGL ES C header.
static GCKernelLibrary & get()
Get the static instance of GCKernelLibrary.
PoolingType
Available pooling types.
PadStrideInfo pad_stride_info
virtual size_t total_size() const =0
Returns the total size of the tensor in bytes.
#define ARM_COMPUTE_CREATE_ERROR(error_code, msg)
Creates an error with a given message.
size_t width
Width of the image region or rectangle.
static constexpr size_t DimZ
Alias for dimension 2 also known as Z dimension.
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...)
constexpr const Dimension & y() const
Alias to access the second dimension of the window.
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
Status validate_arguments(const ITensorInfo *input, const ITensorInfo *bias, const ITensorInfo *output, const GEMMLowpOutputStageInfo *output_stage)
GCKernel create_kernel(const std::string &shader_name, const StringSet &build_options_set={}) const
Creates a kernel from the kernel library.
unsigned int num_elems_processed_per_iteration
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, msg)
If the condition is true, an error is returned.
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
std::pair< unsigned int, unsigned int > pad() const
Get the padding.
T y() const
Alias to access the size of the second dimension.
GCPoolingLayerKernel()
Default constructor.
Container for valid region of a window.
constexpr int end() const
Return the end of the dimension.
Window first_slice_window_3D() const
First 3D slice of the window.
const std::string & string_from_pooling_type(PoolingType type)
Translates a given pooling type to a string.
constexpr int start() const
Return the start of the dimension.
Describe a multidimensional execution window.
TensorShape & set(size_t dimension, size_t value, bool apply_dim_correction=true, bool increase_dim_unit=true)
Accessor to set the value of one of the dimensions.
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s)
SimpleTensor< T > slice(const SimpleTensor< T > &src, Coordinates starts, Coordinates ends)
constexpr const Dimension & x() const
Alias to access the first dimension of the window.