Compute Library
 21.11
CpuPool2dKernel.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2021 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  */
25 
32 #include "src/core/CPP/Validate.h"
33 #include "src/core/NEON/NEAsymm.h"
35 #include "src/core/NEON/NEMath.h"
41 
43 #include <arm_neon.h>
44 
45 namespace arm_compute
46 {
47 namespace cpu
48 {
49 namespace kernels
50 {
51 namespace
52 {
53 using namespace misc::shape_calculator;
54 
55 struct PoolingSelectorData
56 {
60  Size2D pool_size;
61 };
62 
65 struct PoolingKernel
66 {
67  const char *name;
68  const PoolingSelectorPtr is_selected;
69  PoolingKernelPtr ukernel;
70 };
71 
72 static const PoolingKernel available_kernels[] =
73 {
74  {
75  "neon_qu8_nhwc_poolMxN",
76  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NHWC) && (data.dt == DataType::QASYMM8)); },
78  },
79  {
80  "neon_qs8_nhwc_poolMxN",
81  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NHWC) && (data.dt == DataType::QASYMM8_SIGNED)); },
83  },
84 #if defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
85  {
86  "neon_f16_nhwc_poolMxN",
87  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NHWC) && (data.dt == DataType::F16)); },
89  },
90 #endif /* defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) */
91  {
92  "neon_fp32_nhwc_poolMxN",
93  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NHWC) && (data.dt == DataType::F32)); },
95  },
96 #if defined(ENABLE_NCHW_KERNELS)
97  {
98  "neon_qu8_nchw_pool2",
99  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::QASYMM8) && (data.pool_size.x() == data.pool_size.y()) && (data.pool_size.x() == 2) && (data.pool_stride_x < 3)); },
100  REGISTER_QASYMM8_NEON(arm_compute::cpu::pooling2_quantized_neon_nchw<uint8_t>)
101  },
102  {
103  "neon_qu8_nchw_pool3",
104  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::QASYMM8) && (data.pool_size.x() == data.pool_size.y()) && (data.pool_size.x() == 3) && (data.pool_stride_x < 3)); },
105  REGISTER_QASYMM8_NEON(arm_compute::cpu::pooling3_quantized_neon_nchw<uint8_t>)
106  },
107  {
108  "neon_qu8_nchw_poolMxN",
109  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::QASYMM8)); },
110  REGISTER_QASYMM8_NEON(arm_compute::cpu::poolingMxN_quantized_neon_nchw<uint8_t>)
111  },
112  {
113  "neon_qs8_nchw_pool2",
114  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::QASYMM8_SIGNED) && (data.pool_size.x() == data.pool_size.y()) && (data.pool_size.x() == 2) && (data.pool_stride_x < 3)); },
115  REGISTER_QASYMM8_SIGNED_NEON(arm_compute::cpu::pooling2_quantized_neon_nchw<int8_t>)
116  },
117  {
118  "neon_qs8_nchw_pool3",
119  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::QASYMM8_SIGNED) && (data.pool_size.x() == data.pool_size.y()) && (data.pool_size.x() == 3) && (data.pool_stride_x < 3)); },
120  REGISTER_QASYMM8_SIGNED_NEON(arm_compute::cpu::pooling3_quantized_neon_nchw<int8_t>)
121  },
122  {
123  "neon_qs8_nchw_poolMxN",
124  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::QASYMM8_SIGNED)); },
125  REGISTER_QASYMM8_SIGNED_NEON(arm_compute::cpu::poolingMxN_quantized_neon_nchw<int8_t>)
126  },
127 #if defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
128  {
129  "neon_fp16_nchw_pool2",
130  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::F16) && (data.pool_size.x() == data.pool_size.y()) && (data.pool_size.x() == 2)); },
131  REGISTER_FP16_NEON(arm_compute::cpu::pooling2_fp16_neon_nchw)
132  },
133  {
134  "neon_fp16_nchw_pool3",
135  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::F16) && (data.pool_size.x() == data.pool_size.y()) && (data.pool_size.x() == 3)); },
136  REGISTER_FP16_NEON(arm_compute::cpu::pooling3_fp16_neon_nchw)
137  },
138  {
139  "neon_fp16_nchw_poolMxN",
140  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::F16)); },
141  REGISTER_FP16_NEON(arm_compute::cpu::poolingMxN_fp16_neon_nchw)
142  },
143 #endif /* defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) */
144  {
145  "neon_fp32_nchw_pool2",
146  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::F32) && (data.pool_size.x() == data.pool_size.y()) && (data.pool_size.x() == 2)); },
147  REGISTER_FP32_NEON(arm_compute::cpu::pooling2_fp32_neon_nchw)
148  },
149  {
150  "neon_fp32_nchw_pool3",
151  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::F32) && (data.pool_size.x() == data.pool_size.y()) && (data.pool_size.x() == 3)); },
152  REGISTER_FP32_NEON(arm_compute::cpu::pooling3_fp32_neon_nchw)
153  },
154  {
155  "neon_fp32_nchw_pool7",
156  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::F32) && (data.pool_size.x() == data.pool_size.y()) && (data.pool_size.x() == 7)); },
157  REGISTER_FP32_NEON(arm_compute::cpu::pooling7_fp32_neon_nchw)
158  },
159  {
160  "neon_fp32_nchw_poolMxN",
161  [](const PoolingSelectorData & data) { return ((data.dl == DataLayout::NCHW) && (data.dt == DataType::F32)); },
162  REGISTER_FP32_NEON(arm_compute::cpu::poolingMxN_fp32_neon_nchw)
163  },
164 #endif /* defined(ENABLE_NCHW_KERNELS) */
165 };
166 
167 /** Micro-kernel selector
168  *
169  * @param[in] data Selection data passed to help pick the appropriate micro-kernel
170  *
171  * @return A matching micro-kernel else nullptr
172  */
173 const PoolingKernel *get_implementation(DataType dt, DataLayout dl, int pool_stride_x, Size2D pool_size)
174 {
175  for(const auto &uk : available_kernels)
176  {
177  if(uk.is_selected({ dt, dl, pool_stride_x, pool_size }))
178  {
179  return &uk;
180  }
181  }
182  return nullptr;
183 }
184 
185 Status validate_arguments(const ITensorInfo *src, const ITensorInfo *dst, const PoolingLayerInfo &pool_info,
186  const ITensorInfo *indices, Size2D pool_size)
187 {
189  ARM_COMPUTE_RETURN_ERROR_ON(pool_size.x() == 0);
190  ARM_COMPUTE_RETURN_ERROR_ON(pool_size.y() == 0);
191 
192  int pool_stride_x = 0;
193  int pool_stride_y = 0;
194  int output_width = 0;
195  int output_height = 0;
196  PoolingType pool_type = pool_info.pool_type;
197  const PadStrideInfo pad_stride_info = pool_info.pad_stride_info;
198  const auto data_layout = pool_info.data_layout == DataLayout::UNKNOWN ? src->data_layout() : pool_info.data_layout;
201 
202  std::tie(output_width, output_height) = scaled_dimensions_signed(src->tensor_shape()[idx_width], src->tensor_shape()[idx_height],
203  pool_size.x(), pool_size.y(), pool_info.pad_stride_info);
204  ARM_COMPUTE_RETURN_ERROR_ON_MSG((output_width < 1 || output_height < 1), "Calculated output dimension size is invalid");
205 
206  TensorInfo out_info(TensorInfo(compute_pool_shape(*src, pool_info), 1, dst->data_type()));
207  std::tie(pool_stride_x, pool_stride_y) = pad_stride_info.stride();
208 
210  if(indices)
211  {
214  ARM_COMPUTE_RETURN_ERROR_ON_MSG(pool_type != PoolingType::MAX, "Pooling indices only supported for MAX pooling method");
215  }
217  ARM_COMPUTE_RETURN_ERROR_ON(pool_type == PoolingType::L2 && is_data_type_quantized(src->data_type()));
218  ARM_COMPUTE_RETURN_ERROR_ON_MSG(is_data_type_quantized(src->data_type()) && !pool_info.exclude_padding && (pool_info.pool_type == PoolingType::AVG) && pool_info.pad_stride_info.has_padding()
219  && (src->data_layout() == DataLayout::NHWC),
220  "exclude_padding equal false is not supported for AVG Pooling with padding on quantized types");
221 
222  if(dst->total_size() != 0)
223  {
227  if(indices)
228  {
229  ARM_COMPUTE_RETURN_ERROR_ON_MSG((pool_size != Size2D(2, 2)), "Pooling indices only supported for pool size 2x2");
231  }
232  }
233 
234  const auto *uk = get_implementation(src->data_type(), src->data_layout(), pool_stride_x, pool_size);
235  ARM_COMPUTE_RETURN_ERROR_ON(uk == nullptr || uk->ukernel == nullptr);
236 
237  return Status{};
238 }
239 
240 std::pair<Status, Window> validate_and_configure_window(ITensorInfo *src, ITensorInfo *dst, ITensorInfo *indices, const PoolingLayerInfo &pool_info,
241  unsigned int &num_elems_processed_per_iteration,
242  int pool_size_x, int pool_size_y)
243 {
244  // dst auto inizialitation if not yet initialized
245  auto_init_if_empty(*dst, src->clone()->set_tensor_shape(compute_pool_shape(*src, pool_info)));
246  if(indices)
247  {
248  // Indices auto inizialitation if not yet initialized
249  auto_init_if_empty(*indices, (src->clone()->set_tensor_shape(compute_pool_shape(*src,
250  pool_info)))
251  .set_data_type(DataType::U32) /* we store the offset to the element */);
252  }
253  const auto data_layout = pool_info.data_layout == DataLayout::UNKNOWN ? src->data_layout() : pool_info.data_layout;
254 
255  int pool_stride_x = 0;
256  int pool_stride_y = 0;
259  const PadStrideInfo pad_stride_info = pool_info.pad_stride_info;
260 
261  std::tie(pool_stride_x, pool_stride_y) = pad_stride_info.stride();
262  const bool is_square = pool_size_x == pool_size_y;
263  const unsigned int pooled_w = dst->dimension(idx_width);
264  const unsigned int pooled_h = dst->dimension(idx_height);
265 
266  //If it's not squared and optimized will be executed the MxN
267  num_elems_processed_per_iteration = 1;
268 
269  if(is_square)
270  {
271  switch(src->data_type())
272  {
273  case DataType::QASYMM8:
275  switch(pool_size_x)
276  {
277  case 2:
278  num_elems_processed_per_iteration = (pool_stride_x == 2) ? 8 : 15;
279  break;
280  case 3:
281  num_elems_processed_per_iteration = (pool_stride_x == 2) ? 7 : 14;
282  break;
283  default:
284  break;
285  }
286  break;
287 #ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
288  case DataType::F16:
289  num_elems_processed_per_iteration = 1;
290  break;
291 #endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
292  case DataType::F32:
293  num_elems_processed_per_iteration = 1;
294  break;
295  default:
296  ARM_COMPUTE_ERROR("Element size not supported");
297  break;
298  }
299  }
300 
301  bool window_changed = false;
302  Window win{};
303  // Upper limit for the number of right/bottom border elements that are accessed
304  TensorShape dst_shape{ src->tensor_shape() };
305  dst_shape.set(0, pooled_w);
306  dst_shape.set(1, pooled_h);
307  TensorInfo dst_info(src->clone()->set_tensor_shape(dst_shape));
308  win = calculate_max_window(dst_info, Steps(num_elems_processed_per_iteration));
309 
310  Status err = (window_changed) ? ARM_COMPUTE_CREATE_ERROR(ErrorCode::RUNTIME_ERROR, "Insufficient Padding!") : Status{};
311  return std::make_pair(err, win);
312 }
313 } // namespace
314 
316 {
318  const PadStrideInfo pad_stride_info = pool_info.pad_stride_info;
319  const bool is_global_pooling = pool_info.is_global_pooling;
320 
321  // Get data layout
322  const auto data_layout = pool_info.data_layout == DataLayout::UNKNOWN ? src->data_layout() : pool_info.data_layout;
325 
326  // Update pool size in case of global pooling
327  const Size2D pool_size(
328  is_global_pooling ? src->dimension(idx_width) : pool_info.pool_size.width,
329  is_global_pooling ? src->dimension(idx_height) : pool_info.pool_size.height);
330 
331  // Perform validation step
332  ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(src, dst, pool_info, indices, pool_size));
333 
334  const auto *uk = get_implementation(src->data_type(), src->data_layout(), pad_stride_info.stride().first, pool_size);
335  ARM_COMPUTE_ERROR_ON(uk == nullptr);
336 
337  // Set instance variables
338  _pool_info = pool_info;
339  _data_layout = src->data_layout();
340  _pool_size = pool_size;
341  _pool_stride_x = pad_stride_info.stride().first;
342  _run_method = uk->ukernel;
343  _name = std::string("CpuPool2dKernel").append("/").append(uk->name);
344 
345  if(_data_layout == DataLayout::NHWC)
346  {
347  // Configure kernel window
348  Window win = calculate_max_window(*dst, Steps());
349  ICpuKernel::configure(win);
350  }
351  else
352  {
353  // Configure kernel window
354  auto win_config = validate_and_configure_window(src, dst, indices, pool_info, _num_elems_processed_per_iteration,
355  pool_size.x(), pool_size.y());
356  ARM_COMPUTE_ERROR_THROW_ON(win_config.first);
357  ICpuKernel::configure(win_config.second);
358  }
359 }
360 
362 {
364 
365  unsigned int num_elems_processed_per_iteration = 0;
366 
367  const bool is_global_pooling = pool_info.is_global_pooling;
368 
369  // Get data layout
370  const auto data_layout = pool_info.data_layout == DataLayout::UNKNOWN ? src->data_layout() : pool_info.data_layout;
373 
374  unsigned int pool_size_x = is_global_pooling ? src->dimension(idx_width) : pool_info.pool_size.width;
375  unsigned int pool_size_y = is_global_pooling ? src->dimension(idx_height) : pool_info.pool_size.height;
376 
377  ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(src, dst, pool_info, indices, Size2D(pool_size_x, pool_size_y)));
378  ARM_COMPUTE_RETURN_ON_ERROR(validate_and_configure_window(src->clone().get(), dst->clone().get(),
379  (indices) ? indices->clone().get() : nullptr, pool_info, num_elems_processed_per_iteration,
380  pool_size_x, pool_size_y)
381  .first);
382 
383  return Status{};
384 }
385 
386 void CpuPool2dKernel::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info)
387 {
388  ARM_COMPUTE_UNUSED(info);
391  ARM_COMPUTE_ERROR_ON(_run_method == nullptr);
392 
395  ITensor *indices = tensors.get_tensor(TensorType::ACL_DST_1);
396 
397  const unsigned int pool_stride_x = _pool_info.pad_stride_info.stride().first;
398  const unsigned int pool_stride_y = _pool_info.pad_stride_info.stride().second;
399  const unsigned int pool_size = _pool_info.pool_size.width;
400 
401  Window window_src(window);
402  if(_data_layout == DataLayout::NCHW)
403  {
404  // Set step for src in x and y direction for the src
405  unsigned int window_x_inc = 0;
406  switch(src->info()->data_type())
407  {
408  case DataType::QASYMM8:
410  {
411  window_x_inc = pool_stride_x;
412  if((pool_size == 2 || pool_size == 3) && pool_stride_x < 3)
413  {
414  window_x_inc = (pool_stride_x == 2) ? _num_elems_processed_per_iteration * 2 : _num_elems_processed_per_iteration;
415  }
416  break;
417  }
418 
419  case DataType::F16:
420  case DataType::F32:
421  {
422  window_x_inc = pool_stride_x;
423  break;
424  }
425  default:
426  {
427  ARM_COMPUTE_ERROR("Not supported");
428  }
429  }
430  window_src.set(Window::DimX, Window::Dimension(window.x().start() * pool_stride_x, window.x().end() * pool_stride_x, window_x_inc));
431  window_src.set(Window::DimY, Window::Dimension(window.y().start() * pool_stride_y, window.y().end() * pool_stride_y, pool_stride_y));
432  }
433  else
434  {
435  window_src.set(Window::DimX, Window::Dimension(0, 1, 1));
436  window_src.set(Window::DimY, Window::Dimension(0, src->info()->dimension(1), pool_stride_x));
437  window_src.set(Window::DimZ, Window::Dimension(0, src->info()->dimension(2), pool_stride_y));
438  }
439  _run_method(src, dst, indices, _pool_info, window_src, window);
440 }
441 
442 const char *CpuPool2dKernel::name() const
443 {
444  return _name.c_str();
445 }
446 } // namespace kernels
447 } // namespace cpu
448 } // namespace arm_compute
static Status validate(const ITensorInfo *src, const ITensorInfo *dst, const PoolingLayerInfo &pool_info, const ITensorInfo *indices=nullptr)
Static function to check if given info will lead to a valid configuration.
bool is_data_type_quantized(DataType dt)
Check if a given data type is of quantized type.
Definition: Utils.h:981
PoolingKernelPtr ukernel
Window calculate_max_window(const ValidRegion &valid_region, const Steps &steps, bool skip_border, BorderSize border_size)
const char * name
const Window & window() const
The maximum window the kernel can be executed on.
Definition: IKernel.cpp:28
void poolingMxN_qasymm8_neon_nhwc(const ITensor *src0, ITensor *dst0, ITensor *dst1, PoolingLayerInfo &, const Window &window_src, const Window &window)
Definition: qasymm8.cpp:36
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(...)
Definition: Validate.h:490
#define ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(tensor)
Definition: Validate.h:115
#define REGISTER_FP16_NEON(func_name)
Definition: Registrars.h:42
virtual size_t dimension(size_t index) const =0
Return the size of the requested dimension.
void poolingMxN_fp32_neon_nhwc(const ITensor *src, ITensor *dst0, ITensor *dst1, PoolingLayerInfo &pool_info, const Window &window_src, const Window &window)
Definition: fp32.cpp:146
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
Definition: Error.h:352
#define REGISTER_FP32_NEON(func_name)
Definition: Registrars.h:61
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:204
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_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
#define REGISTER_QASYMM8_SIGNED_NEON(func_name)
Definition: Registrars.h:76
Store the tensor&#39;s metadata.
Definition: ITensorInfo.h:40
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:455
Describe one of the image&#39;s dimensions with a start, end and step.
Definition: Window.h:77
Status class.
Definition: Error.h:52
void run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info) override
Execute the kernel on the passed window.
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
Definition: Error.h:296
decltype(strategy::transforms) typedef type
Interface for CPU tensor.
Definition: ITensor.h:36
SimpleTensor< float > src
Definition: DFT.cpp:155
Copyright (c) 2017-2021 Arm Limited.
size_t height
Height of the image region or rectangle.
Definition: Size2D.h:91
1 channel, 1 F16 per channel
#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...)
Definition: Validate.h:159
std::pair< int, int > scaled_dimensions_signed(int width, int height, int kernel_width, int kernel_height, const PadStrideInfo &pad_stride_info)
Returns calculated width and height of output scaled tensor depending on dimensions rounding mode...
Definition: Utils.cpp:429
TensorShape compute_pool_shape(const ITensorInfo &input, PoolingLayerInfo pool_info)
Calculate the output pool shape of a tensor.
const ITensor * get_const_tensor(int id) const
Get constant tensor of a given id.
Definition: ITensorPack.cpp:54
Size2D pool_size
static constexpr size_t DimX
Alias for dimension 0 also known as X dimension.
Definition: Window.h:43
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:152
#define REGISTER_QASYMM8_NEON(func_name)
Definition: Registrars.h:90
1 channel, 1 U32 per channel
quantized, asymmetric fixed-point 8-bit number unsigned
Class to describe a number of elements in each dimension.
Definition: Steps.h:40
DataType dt
std::pair< unsigned int, unsigned int > stride() const
Get the stride.
Definition: Types.h:704
unsigned int num_elems_processed_per_iteration
Pooling Layer Information struct.
Definition: Types.h:1173
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...
void poolingMxN_fp16_neon_nhwc(const ITensor *src0, ITensor *dst0, ITensor *dst1, PoolingLayerInfo &, const Window &window_src, const Window &window)
virtual std::unique_ptr< T > clone() const =0
Provide a clone of the current object of class T.
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:656
void set(size_t dimension, const Dimension &dim)
Set the values of a given dimension.
Definition: Window.inl:49
#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k)
Definition: Validate.h:915
Num samples, channels, height, width.
static constexpr size_t DimY
Alias for dimension 1 also known as Y dimension.
Definition: Window.h:45
const char * name() const override
Name of the kernel.
PoolingType
Available pooling types.
Definition: Types.h:544
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
ITensor * get_tensor(int id)
Get tensor of a given id from the pac.
Definition: ITensorPack.cpp:64
PadStrideInfo pad_stride_info
Definition: Types.h:1261
Information about executing thread and CPU.
Definition: CPPTypes.h:158
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(...)
Definition: Validate.h:439
#define ARM_COMPUTE_CREATE_ERROR(error_code, msg)
Creates an error with a given message.
Definition: Error.h:159
size_t width
Width of the image region or rectangle.
Definition: Size2D.h:90
static constexpr size_t DimZ
Alias for dimension 2 also known as Z dimension.
Definition: Window.h:47
size_t get_data_layout_dimension_index(const DataLayout &data_layout, const DataLayoutDimension &data_layout_dimension)
Get the index of the given dimension.
Definition: Helpers.inl:193
void poolingMxN_qasymm8_signed_neon_nhwc(const ITensor *src0, ITensor *dst0, ITensor *dst1, PoolingLayerInfo &, const Window &window_src, const Window &window)
Class for specifying the size of an image or rectangle.
Definition: Size2D.h:34
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...)
Definition: Validate.h:541
Num samples, height, width, channels.
int pool_stride_x
constexpr const Dimension & y() const
Alias to access the second dimension of the window.
Definition: Window.h:154
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
Definition: Validate.h:788
const PoolingSelectorPtr is_selected
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, msg)
If the condition is true, an error is returned.
Definition: Error.h:244
Tensor packing service.
Definition: ITensorPack.h:39
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:157
quantized, asymmetric fixed-point 8-bit number signed
DataLayout dl
Includes all wrapper headers at once.
constexpr int end() const
Return the end of the dimension.
Definition: Window.h:99
DataType
Available data types.
Definition: Types.h:79
void configure(ITensorInfo *src, ITensorInfo *dst, const PoolingLayerInfo &pool_info, ITensorInfo *indices=nullptr)
Configure kernel for a given list of arguments.
DataLayout
[DataLayout enum definition]
Definition: Types.h:113
constexpr int start() const
Return the start of the dimension.
Definition: Window.h:94
Describe a multidimensional execution window.
Definition: Window.h:39
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.
Definition: TensorShape.h:79
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s)
Definition: Validate.h:201
virtual DataLayout data_layout() const =0
Get the data layout of the tensor.
constexpr const Dimension & x() const
Alias to access the first dimension of the window.
Definition: Window.h:145