Compute Library
 21.02
GCPoolingLayerKernel Class Reference

Interface for the pooling layer kernel. More...

#include <GCPoolingLayerKernel.h>

Collaboration diagram for GCPoolingLayerKernel:
[legend]

Public Member Functions

 GCPoolingLayerKernel ()
 Default constructor. More...
 
 GCPoolingLayerKernel (const GCPoolingLayerKernel &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
GCPoolingLayerKerneloperator= (const GCPoolingLayerKernel &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
 GCPoolingLayerKernel (GCPoolingLayerKernel &&)=default
 Allow instances of this class to be moved. More...
 
GCPoolingLayerKerneloperator= (GCPoolingLayerKernel &&)=default
 Allow instances of this class to be moved. More...
 
 ~GCPoolingLayerKernel ()=default
 Default destructor. More...
 
void configure (const IGCTensor *input, IGCTensor *output, const PoolingLayerInfo &pool_info, IGCTensor *indices=nullptr)
 Set the input and output tensors. More...
 
void run (const Window &window) override
 Enqueue the OpenGL ES shader to process the given window. More...
 
BorderSize border_size () const override
 The size of the border for that kernel. More...
 
- Public Member Functions inherited from IGCKernel
 IGCKernel ()
 Constructor. More...
 
GCKernelkernel ()
 Returns a reference to the GLES kernel of this object. More...
 
void add_1D_tensor_argument (unsigned int &idx, const IGCTensor *tensor, const unsigned int binding_point, const Window &window)
 Add the passed 1D tensor's parameters to the object's kernel's arguments starting from the index idx. More...
 
void add_2D_tensor_argument (unsigned int &idx, const IGCTensor *tensor, const unsigned int binding_point, const Window &window)
 Add the passed 2D tensor's parameters to the object's kernel's arguments starting from the index idx. More...
 
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. More...
 
unsigned int num_arguments_per_1D_tensor () const
 Returns the number of arguments enqueued per 1D tensor object. More...
 
unsigned int num_arguments_per_2D_tensor () const
 Returns the number of arguments enqueued per 2D tensor object. More...
 
unsigned int num_arguments_per_3D_tensor () const
 Returns the number of arguments enqueued per 3D tensor object. More...
 
void set_lws_hint (gles::NDRange &lws_hint)
 Set the Local-Workgroup-Size hint. More...
 
void set_target (GPUTarget target)
 Set the targeted GPU architecture. More...
 
GPUTarget get_target () const
 Get the targeted GPU architecture. More...
 
- Public Member Functions inherited from IKernel
 IKernel ()
 Constructor. More...
 
virtual ~IKernel ()=default
 Destructor. More...
 
virtual bool is_parallelisable () const
 Indicates whether or not the kernel is parallelisable. More...
 
const Windowwindow () const
 The maximum window the kernel can be executed on. More...
 

Static Public Member Functions

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. More...
 

Detailed Description

Interface for the pooling layer kernel.

Definition at line 36 of file GCPoolingLayerKernel.h.

Constructor & Destructor Documentation

◆ GCPoolingLayerKernel() [1/3]

Default constructor.

Definition at line 220 of file GCPoolingLayerKernel.cpp.

221  : _input(nullptr), _output(nullptr), _indices(nullptr), _pool_info(), _border_size(0), _num_elems_processed_per_iteration(1)
222 {
223 }

◆ GCPoolingLayerKernel() [2/3]

Prevent instances of this class from being copied (As this class contains pointers)

◆ GCPoolingLayerKernel() [3/3]

Allow instances of this class to be moved.

◆ ~GCPoolingLayerKernel()

~GCPoolingLayerKernel ( )
default

Default destructor.

Member Function Documentation

◆ border_size()

BorderSize border_size ( ) const
overridevirtual

The size of the border for that kernel.

Returns
The width in number of elements of the border.

Reimplemented from IKernel.

Definition at line 225 of file GCPoolingLayerKernel.cpp.

226 {
227  return _border_size;
228 }

◆ configure()

void configure ( const IGCTensor input,
IGCTensor output,
const PoolingLayerInfo pool_info,
IGCTensor indices = nullptr 
)

Set the input and output tensors.

Parameters
[in]inputSource tensor. Data types supported: F16/F32.
[out]outputDestination tensor. Data types supported: Same as input.
[in]pool_infoContains pooling operation information described in PoolingLayerInfo.
[out]indices(optional) The indices of the maximal values. Data type supported: U32.

Definition at line 230 of file GCPoolingLayerKernel.cpp.

References ARM_COMPUTE_ERROR_ON_NULLPTR, ARM_COMPUTE_ERROR_THROW_ON, GCKernelLibrary::create_kernel(), ITensorInfo::data_type(), ITensorInfo::dimension(), PoolingLayerInfo::exclude_padding, arm_compute::F32, GCKernelLibrary::get(), ITensor::info(), arm_compute::test::validation::input, PoolingLayerInfo::is_global_pooling, kernel_name, PadStrideInfo::pad(), PoolingLayerInfo::pad_stride_info, pool_size, PoolingLayerInfo::pool_size, PoolingLayerInfo::pool_type, arm_compute::scaled_dimensions(), PadStrideInfo::stride(), arm_compute::string_from_pooling_type(), arm_compute::support::cpp11::to_string(), arm_compute::validate_arguments(), and Size2D::width.

231 {
232  int pool_pad_x = 0;
233  int pool_pad_y = 0;
234  int pool_stride_x = 0;
235  int pool_stride_y = 0;
236  unsigned int pooled_w = 0;
237  unsigned int pooled_h = 0;
238  const PoolingType pool_type = pool_info.pool_type;
239  int pool_size = pool_info.pool_size.width;
240  const PadStrideInfo pad_stride_info = pool_info.pad_stride_info;
241  const bool exclude_padding = pool_info.exclude_padding;
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();
244 
245  ARM_COMPUTE_ERROR_ON_NULLPTR(input, output);
246 
247  // Update pool size in case of global pooling
248  pool_size = pool_info.is_global_pooling ? input->info()->dimension(0) : pool_size;
249 
250  // Check output dimensions
251  std::tie(pooled_w, pooled_h) = scaled_dimensions(input->info()->dimension(0),
252  input->info()->dimension(1),
253  pool_size,
254  pool_size,
255  pad_stride_info);
256 
257  auto_init(input->info(), output->info(), pooled_w, pooled_h);
258 
259  ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), pool_info, (indices) ? indices->info() : nullptr));
260 
261  // Set instance variables
262  _input = input;
263  _output = output;
264  _pool_info = pool_info;
265  _indices = indices;
266  // Set build options
267  std::set<std::string> build_opts;
268  build_opts.emplace("#define LOCAL_SIZE_X " + support::cpp11::to_string(1));
269  build_opts.emplace("#define LOCAL_SIZE_Y " + support::cpp11::to_string(1));
270  build_opts.emplace("#define LOCAL_SIZE_Z " + support::cpp11::to_string(1));
271  if(input->info()->data_type() == DataType::F32)
272  {
273  build_opts.insert("#define DATA_TYPE_FP32");
274  }
275  else
276  {
277  build_opts.insert("#define DATA_TYPE_FP16");
278  }
279  if(exclude_padding)
280  {
281  build_opts.emplace("#define EXCLUDE_PADDING");
282  }
283  build_opts.emplace(("#define POOL_" + string_from_pooling_type(pool_type)));
284  build_opts.emplace(("#define STRIDE_X " + support::cpp11::to_string(pool_stride_x)));
285  build_opts.emplace(("#define MAX_WIDTH " + support::cpp11::to_string(input->info()->dimension(0) + (exclude_padding ? 0 : pool_pad_x))));
286  build_opts.emplace(("#define MAX_HEIGHT " + support::cpp11::to_string(input->info()->dimension(1) + (exclude_padding ? 0 : pool_pad_y))));
287  build_opts.emplace(("#define STRIDE_Y " + support::cpp11::to_string(pool_stride_y)));
288  build_opts.emplace(("#define PAD_X " + support::cpp11::to_string(pool_pad_x)));
289  build_opts.emplace(("#define PAD_Y " + support::cpp11::to_string(pool_pad_y)));
290 
291  // Create kernel
292  if((pool_size == 2) || (pool_size == 3) || (pool_size == 7))
293  {
294  // Check if we have pool3x3 with stride_x less equal than 3. In these cases, run an optimized OpenGLES kernel where
295  // each thread computes 4 output elements
296  const bool is_pool3x3_stride_le3 = (pool_size == 3) && (pool_stride_x <= 3);
297 
298  std::string kernel_name = "pooling_layer_" + support::cpp11::to_string(pool_size);
299  if(is_pool3x3_stride_le3)
300  {
301  build_opts.insert("#define POOLING_LAYER_3_OPTIMIZED");
302  _kernel = static_cast<GCKernel>(GCKernelLibrary::get().create_kernel(kernel_name + "_optimized", build_opts));
303  }
304  else
305  {
306  build_opts.insert("#define POOLING_LAYER_" + support::cpp11::to_string(pool_size));
307  _kernel = static_cast<GCKernel>(GCKernelLibrary::get().create_kernel(kernel_name, build_opts));
308  }
309  }
310  else // Run general case
311  {
312  build_opts.emplace(("#define POOL_SIZE " + support::cpp11::to_string(pool_size)));
313 
314  build_opts.insert("#define POOLING_LAYER_N");
315  _kernel = static_cast<GCKernel>(GCKernelLibrary::get().create_kernel("pooling_layer_n", build_opts));
316  }
317  // Configure kernel window
318  auto win_config = validate_and_configure_window(input->info(), output->info(), pool_info);
319  ARM_COMPUTE_ERROR_THROW_ON(std::get<0>(win_config));
320 
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;
325 }
virtual size_t dimension(size_t index) const =0
Return the size of the requested dimension.
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
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:455
GCKernel class.
int pool_stride_x
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...
Definition: Utils.cpp:419
std::pair< unsigned int, unsigned int > stride() const
Get the stride.
Definition: Types.h:770
std::string kernel_name
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor&#39;s metadata.
Padding and stride information class.
Definition: Types.h:722
static GCKernelLibrary & get()
Get the static instance of GCKernelLibrary.
PoolingType
Available pooling types.
Definition: Types.h:610
PadStrideInfo pad_stride_info
Definition: Types.h:1302
size_t width
Width of the image region or rectangle.
Definition: Size2D.h:89
Status validate_arguments(const ITensorInfo *input, const ITensorInfo *bias, const ITensorInfo *output, const GEMMLowpOutputStageInfo *output_stage)
Size2D pool_size
GCKernel create_kernel(const std::string &shader_name, const StringSet &build_options_set={}) const
Creates a kernel from the kernel library.
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:161
std::pair< unsigned int, unsigned int > pad() const
Get the padding.
Definition: Types.h:788
const std::string & string_from_pooling_type(PoolingType type)
Translates a given pooling type to a string.
Definition: Utils.cpp:248

◆ operator=() [1/2]

GCPoolingLayerKernel& operator= ( const GCPoolingLayerKernel )
delete

Prevent instances of this class from being copied (As this class contains pointers)

◆ operator=() [2/2]

GCPoolingLayerKernel& operator= ( GCPoolingLayerKernel &&  )
default

Allow instances of this class to be moved.

◆ run()

void run ( const Window window)
overridevirtual

Enqueue the OpenGL ES shader to process the given window.

Parameters
[in]windowRegion on which to execute the kernel. (Must be a valid region of the window returned by window()).

Implements IGCKernel.

Definition at line 335 of file GCPoolingLayerKernel.cpp.

References IGCKernel::add_3D_tensor_argument(), ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW, ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL, Window::collapse_if_possible(), Window::DimX, Window::DimY, Window::DimZ, Window::Dimension::end(), arm_compute::enqueue(), Window::first_slice_window_3D(), ITensor::info(), PadStrideInfo::pad(), PoolingLayerInfo::pad_stride_info, ITensorInfo::padding(), pool_stride_x, Window::set(), IGCTensor::set_needs_shifting(), Window::shift(), arm_compute::test::validation::reference::slice(), Window::slide_window_slice_3D(), Window::Dimension::start(), PadStrideInfo::stride(), IKernel::window(), Window::x(), and Window::y().

336 {
339 
340  unsigned int pool_pad_x;
341  unsigned int pool_pad_y;
342  unsigned int pool_stride_x;
343  unsigned int pool_stride_y;
344  std::tie(pool_pad_x, pool_pad_y) = _pool_info.pad_stride_info.pad();
345  std::tie(pool_stride_x, pool_stride_y) = _pool_info.pad_stride_info.stride();
346 
347  _kernel.use();
348 
349  _output->set_needs_shifting(true);
350 
351  Window window_collapsed = window.collapse_if_possible(IGCKernel::window(), Window::DimZ);
352 
353  Window slice = window_collapsed.first_slice_window_3D();
354  Window slice_in_orig = window_collapsed.first_slice_window_3D();
355 
356  slice.shift(Window::DimX, -(_output->info()->padding()).left);
357 
358  do
359  {
360  // Upsample input by pool size
361  Window in_slice(slice_in_orig); // NOLINT
362  in_slice.set(Window::DimX, Window::Dimension(in_slice.x().start() - pool_pad_x, in_slice.x().end() * pool_stride_x, pool_stride_x * _num_elems_processed_per_iteration));
363  in_slice.set(Window::DimY, Window::Dimension(in_slice.y().start() - pool_pad_y, in_slice.y().end() * pool_stride_y, pool_stride_y));
364 
365  // Set inputs
366  unsigned int idx = 0;
367  add_3D_tensor_argument(idx, _input, 1, in_slice);
368  add_3D_tensor_argument(idx, _output, 2, slice);
369 
370  _kernel.update_shader_params();
371  enqueue(*this, slice);
372  }
373  while(window_collapsed.slide_window_slice_3D(slice) && window_collapsed.slide_window_slice_3D(slice_in_orig));
374 }
const Window & window() const
The maximum window the kernel can be executed on.
Definition: IKernel.cpp:28
void add_3D_tensor_argument(unsigned int &idx, const IGCTensor *tensor, const unsigned int binding_point, const Window &window)
Add the passed 3D tensor&#39;s parameters to the object&#39;s kernel&#39;s arguments starting from the index idx...
Definition: IGCKernel.cpp:132
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.
Definition: IGCKernel.cpp:41
void shift(size_t dimension, int shift_value)
Shift the values of a given dimension by the given shift_value.
Definition: Window.inl:133
Describe one of the image&#39;s dimensions with a start, end and step.
Definition: Window.h:77
int pool_stride_x
static constexpr size_t DimX
Alias for dimension 0 also known as X dimension.
Definition: Window.h:43
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.
Definition: Window.inl:68
void set_needs_shifting(bool needs_shifting)
Set the flag indicating whether or not a tensor needs shifting.
Definition: IGCTensor.cpp:61
std::pair< unsigned int, unsigned int > stride() const
Get the stride.
Definition: Types.h:770
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor&#39;s metadata.
virtual PaddingSize padding() const =0
Padding of tensor.
bool slide_window_slice_3D(Window &slice) const
Slide the passed 3D window slice.
Definition: Window.h:335
#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k)
Definition: Validate.h:941
static constexpr size_t DimY
Alias for dimension 1 also known as Y dimension.
Definition: Window.h:45
PadStrideInfo pad_stride_info
Definition: Types.h:1302
static constexpr size_t DimZ
Alias for dimension 2 also known as Z dimension.
Definition: Window.h:47
std::pair< unsigned int, unsigned int > pad() const
Get the padding.
Definition: Types.h:788
Window first_slice_window_3D() const
First 3D slice of the window.
Definition: Window.h:291
Describe a multidimensional execution window.
Definition: Window.h:39
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s)
Definition: Validate.h:205
SimpleTensor< T > slice(const SimpleTensor< T > &src, Coordinates starts, Coordinates ends)

◆ validate()

Status validate ( const ITensorInfo input,
const ITensorInfo output,
const PoolingLayerInfo pool_info,
const ITensorInfo indices = nullptr 
)
static

Static function to check if given info will lead to a valid configuration of GCPoolingLayerKernel.

Parameters
[in]inputSource tensor info. Data types supported: F16/F32.
[in]outputDestination tensor info. Data types supported: Same as input.
[in]pool_infoContains pooling operation information described in PoolingLayerInfo.
[in]indices(optional) The indices of the maximal values. Data type supported: U32.
Returns
a status

Definition at line 327 of file GCPoolingLayerKernel.cpp.

References ARM_COMPUTE_RETURN_ON_ERROR, ICloneable< T >::clone(), and arm_compute::validate_arguments().

Referenced by GCPoolingLayer::validate().

328 {
329  ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, output, pool_info, indices));
330  ARM_COMPUTE_RETURN_ON_ERROR(std::get<0>(validate_and_configure_window(input->clone().get(), output->clone().get(), pool_info)));
331 
332  return Status{};
333 }
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:204
Status class.
Definition: Error.h:52
virtual std::unique_ptr< T > clone() const =0
Provide a clone of the current object of class T.
Status validate_arguments(const ITensorInfo *input, const ITensorInfo *bias, const ITensorInfo *output, const GEMMLowpOutputStageInfo *output_stage)

The documentation for this class was generated from the following files: