Compute Library
 19.08
NECropKernel Class Reference

Interface for the kernel to perform tensor cropping. More...

#include <NECropKernel.h>

Collaboration diagram for NECropKernel:
[legend]

Public Types

using InBoundsCropFunction = void(const ITensor *, const ITensor *, float *, Coordinates, int32_t, int32_t, int32_t)
 Function to use for in bounds crop for the particular tensor types passed to configure() More...
 

Public Member Functions

const char * name () const override
 Name of the kernel. More...
 
 NECropKernel ()
 Default constructor. More...
 
 NECropKernel (const NECropKernel &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
NECropKerneloperator= (const NECropKernel &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
 NECropKernel (NECropKernel &&)=default
 Allow instances of this class to be moved. More...
 
NECropKerneloperator= (NECropKernel &&)=default
 Allow instances of this class to be moved. More...
 
 ~NECropKernel ()=default
 Default destructor. More...
 
void configure (const ITensor *input, const ITensor *crop_boxes, const ITensor *box_ind, ITensor *output, uint32_t crop_box_ind=0, float extrapolation_value=0)
 Configure kernel. More...
 
void configure_output_shape ()
 Configure output tensor's shape as this can only be determined at runtime. More...
 
void run (const Window &window, const ThreadInfo &info) override
 Execute the kernel on the passed window. More...
 
- Public Member Functions inherited from ICPPKernel
virtual ~ICPPKernel ()=default
 Default destructor. 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...
 
virtual BorderSize border_size () const
 The size of the border for that kernel. 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 *crop_boxes, const ITensorInfo *box_ind, const ITensorInfo *output, uint32_t crop_box_ind=0, float extrapolation_value=0)
 Static function to check if given info will lead to a valid configuration of CLStridedSliceKernel. More...
 

Detailed Description

Interface for the kernel to perform tensor cropping.

Definition at line 40 of file NECropKernel.h.

Member Typedef Documentation

◆ InBoundsCropFunction

using InBoundsCropFunction = void(const ITensor *, const ITensor *, float *, Coordinates, int32_t, int32_t, int32_t)

Function to use for in bounds crop for the particular tensor types passed to configure()

Definition at line 97 of file NECropKernel.h.

Constructor & Destructor Documentation

◆ NECropKernel() [1/3]

Default constructor.

Definition at line 231 of file NECropKernel.cpp.

232  : _input(nullptr), _crop_boxes(nullptr), _box_ind(nullptr), _output(nullptr), _start(), _end(), _crop_box_ind(0), _extrapolation_value(0), _rows_out_of_bounds(), _cols_out_of_bounds(),
233  _in_bounds_crop_functions(), _in_bounds_crop_function(nullptr), _crop_function(nullptr)
234 {
235 }

◆ NECropKernel() [2/3]

NECropKernel ( const NECropKernel )
delete

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

◆ NECropKernel() [3/3]

NECropKernel ( NECropKernel &&  )
default

Allow instances of this class to be moved.

◆ ~NECropKernel()

~NECropKernel ( )
default

Default destructor.

Member Function Documentation

◆ configure()

void configure ( const ITensor input,
const ITensor crop_boxes,
const ITensor box_ind,
ITensor output,
uint32_t  crop_box_ind = 0,
float  extrapolation_value = 0 
)

Configure kernel.

Note
Supported tensor rank: up to 4
Padding not supported.
Parameters
[in]inputSource tensor. Data type supported: U16/S16/U32/S32/F16/F32. Data layouts supported: NHWC.
[in]crop_boxesTensor containing all possible boxes used to crop the image, each represented by 4 normalized values. Data type supported: F32
[in]box_indOne dimensional tensor mapping the crop_box_ind to the index of the 3D image in input. Data type supported: F32
[out]outputDestination tensor. Data type supported: F32
[in]crop_box_indIndex of the crop box to be used from crop_boxes. Default is 0.
[in]extrapolation_valueValue to be used for values outside of the image. Default is 0.

Definition at line 237 of file NECropKernel.cpp.

238 {
239  ARM_COMPUTE_ERROR_ON_NULLPTR(input, output);
240  ARM_COMPUTE_ERROR_THROW_ON(validate(input->info(), crop_boxes->info(), box_ind->info(), output->info(), crop_box_ind, extrapolation_value));
241 
242  _input = input;
243  _crop_boxes = crop_boxes;
244  _box_ind = box_ind;
245  _output = output;
246  _crop_box_ind = crop_box_ind;
247  _extrapolation_value = extrapolation_value;
248 
249  const static std::map<std::pair<DataType, bool>, std::pair<NECropKernel::InBoundsCropFunction *, NECropKernel::InBoundsCropFunction *>> in_map_function =
250  {
251  { { DataType::F32, false }, { &in_bounds_crop_window<float, false, false>, &in_bounds_crop_window<float, false, true> } },
252  { { DataType::F32, true }, { &in_bounds_crop_window<float, true, false>, &in_bounds_crop_window<float, true, true> } },
253  { { DataType::U16, false }, { &in_bounds_crop_window<uint16_t, false, false>, &in_bounds_crop_window<uint16_t, false, true> } },
254  { { DataType::U16, true }, { &in_bounds_crop_window<uint16_t, true, false>, &in_bounds_crop_window<uint16_t, true, true> } },
255  { { DataType::S16, false }, { &in_bounds_crop_window<int16_t, false, false>, &in_bounds_crop_window<int16_t, false, true> } },
256  { { DataType::S16, true }, { &in_bounds_crop_window<int16_t, true, false>, &in_bounds_crop_window<int16_t, true, true> } },
257  { { DataType::U32, false }, { &in_bounds_crop_window<uint32_t, false, false>, &in_bounds_crop_window<uint32_t, false, true> } },
258  { { DataType::U32, true }, { &in_bounds_crop_window<uint32_t, true, false>, &in_bounds_crop_window<uint32_t, true, true> } },
259  { { DataType::S32, false }, { &in_bounds_crop_window<int32_t, false, false>, &in_bounds_crop_window<int32_t, false, true> } },
260  { { DataType::S32, true }, { &in_bounds_crop_window<int32_t, true, false>, &in_bounds_crop_window<int32_t, true, true> } },
261 #ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
262  { { DataType::F16, false }, { &in_bounds_crop_window<float16_t, false, false>, &in_bounds_crop_window<float16_t, false, true> } },
263  { { DataType::F16, false }, { &in_bounds_crop_window<float16_t, true, false>, &in_bounds_crop_window<float16_t, true, true> } }
264 #endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
265  };
266 
267  auto in_it = in_map_function.find({ input->info()->data_type(), input->info()->dimension(0) == 1 });
268 
269  if(in_it != in_map_function.end())
270  {
271  _in_bounds_crop_functions = in_it->second;
272  }
273 }
1 channel, 1 F32 per channel
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:327
1 channel, 1 U16 per channel
1 channel, 1 F16 per channel
1 channel, 1 S32 per channel
1 channel, 1 U32 per channel
static Status validate(const ITensorInfo *input, const ITensorInfo *crop_boxes, const ITensorInfo *box_ind, const ITensorInfo *output, uint32_t crop_box_ind=0, float extrapolation_value=0)
Static function to check if given info will lead to a valid configuration of CLStridedSliceKernel.
1 channel, 1 S16 per channel
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:161

References ARM_COMPUTE_ERROR_ON_NULLPTR, ARM_COMPUTE_ERROR_THROW_ON, ITensorInfo::data_type(), ITensorInfo::dimension(), arm_compute::F16, arm_compute::F32, ITensor::info(), arm_compute::S16, arm_compute::S32, arm_compute::U16, arm_compute::U32, and NECropKernel::validate().

◆ configure_output_shape()

void configure_output_shape ( )

Configure output tensor's shape as this can only be determined at runtime.

Definition at line 296 of file NECropKernel.cpp.

297 {
298  // _crop_box_ind is used to index _crop_boxes and retrieve the appropriate crop box.
299  // The crop box is specified by normalized coordinates [y0, x0, y1, x1].
300  const float x0 = *reinterpret_cast<const float *>(_crop_boxes->ptr_to_element(Coordinates(1, _crop_box_ind)));
301  const float y0 = *reinterpret_cast<const float *>(_crop_boxes->ptr_to_element(Coordinates(0, _crop_box_ind)));
302  const float x1 = *reinterpret_cast<const float *>(_crop_boxes->ptr_to_element(Coordinates(3, _crop_box_ind)));
303  const float y1 = *reinterpret_cast<const float *>(_crop_boxes->ptr_to_element(Coordinates(2, _crop_box_ind)));
304  // The normalized coordiantes are scaled to retrieve the floating point image coordinates which are rounded to integers.
305  _start = Coordinates(std::floor(x0 * (_input->info()->tensor_shape()[1] - 1) + 0.5f),
306  std::floor(y0 * (_input->info()->tensor_shape()[2] - 1) + 0.5f));
307  _end = Coordinates(std::floor(x1 * (_input->info()->tensor_shape()[1] - 1) + 0.5f),
308  std::floor(y1 * (_input->info()->tensor_shape()[2] - 1) + 0.5f));
309  const TensorShape out_shape(_input->info()->tensor_shape()[0], abs(_end[0] - _start[0]) + 1, abs(_end[1] - _start[1]) + 1);
310  _output->info()->set_tensor_shape(out_shape);
311 
312  _in_bounds_crop_function = _start[0] <= _end[0] ? _in_bounds_crop_functions.first : _in_bounds_crop_functions.second;
313 
314  bool is_width_flipped = _end[0] < _start[0];
315  bool is_height_flipped = _end[1] < _start[1];
316  if(is_height_flipped)
317  {
318  _rows_out_of_bounds[0] = _start[1] >= static_cast<int32_t>(_input->info()->dimension(2)) ? std::min(static_cast<uint32_t>(_start[1] - _input->info()->dimension(2) + 1),
319  static_cast<uint32_t>(_output->info()->dimension(2))) :
320  0;
321  _rows_out_of_bounds[1] = _end[1] < 0 ? std::min(static_cast<uint32_t>(-_end[1]),
322  static_cast<uint32_t>(_output->info()->dimension(2))) :
323  0;
324  }
325  else
326  {
327  _rows_out_of_bounds[0] = _start[1] < 0 ? std::min(static_cast<uint32_t>(-_start[1]),
328  static_cast<uint32_t>(_output->info()->dimension(2))) :
329  0;
330  _rows_out_of_bounds[1] = _end[1] >= static_cast<int32_t>(_input->info()->dimension(2)) ? std::min(static_cast<uint32_t>(_end[1] - _input->info()->dimension(2) + 1),
331  static_cast<uint32_t>(_output->info()->dimension(2))) :
332  0;
333  }
334  if(is_width_flipped)
335  {
336  _cols_out_of_bounds[0] = _start[0] >= static_cast<int32_t>(_input->info()->dimension(1)) ? std::min(static_cast<uint32_t>(_start[0] - _input->info()->dimension(1) + 1),
337  static_cast<uint32_t>(_output->info()->dimension(1))) :
338  0;
339  _cols_out_of_bounds[1] = _end[0] < 0 ? std::min(static_cast<uint32_t>(-_end[0]),
340  static_cast<uint32_t>(_output->info()->dimension(1))) :
341  0;
342  }
343  else
344  {
345  _cols_out_of_bounds[0] = _start[0] < 0 ? std::min(static_cast<uint32_t>(-_start[0]),
346  static_cast<uint32_t>(_output->info()->dimension(1))) :
347  0;
348  _cols_out_of_bounds[1] = _end[0] >= static_cast<int32_t>(_input->info()->dimension(1)) ? std::min(static_cast<uint32_t>(_end[0] - _input->info()->dimension(1) + 1),
349  static_cast<uint32_t>(_output->info()->dimension(1))) :
350  0;
351  }
352 
353  const static std::map<std::tuple<bool, bool, bool, bool>, NECropKernel::CropFunction *> map_function =
354  {
355  { std::make_tuple(false, false, false, false), &execute_window<false, false, false, false> },
356  { std::make_tuple(false, false, false, true), &execute_window<false, false, false, true> },
357  { std::make_tuple(false, false, true, false), &execute_window<false, false, true, false> },
358  { std::make_tuple(false, false, true, true), &execute_window<false, false, true, true> },
359  { std::make_tuple(false, true, false, false), &execute_window<false, true, false, false> },
360  { std::make_tuple(false, true, false, true), &execute_window<false, true, false, true> },
361  { std::make_tuple(false, true, true, false), &execute_window<false, true, true, false> },
362  { std::make_tuple(false, true, true, true), &execute_window<false, true, true, true> },
363  { std::make_tuple(true, false, false, false), &execute_window<true, false, false, false> },
364  { std::make_tuple(true, false, false, true), &execute_window<true, false, false, true> },
365  { std::make_tuple(true, false, true, false), &execute_window<true, false, true, false> },
366  { std::make_tuple(true, false, true, true), &execute_window<true, false, true, true> },
367  { std::make_tuple(true, true, false, false), &execute_window<true, true, false, false> },
368  { std::make_tuple(true, true, false, true), &execute_window<true, true, false, true> },
369  { std::make_tuple(true, true, true, false), &execute_window<true, true, true, false> },
370  { std::make_tuple(true, true, true, true), &execute_window<true, true, true, true> },
371  };
372 
373  auto it = map_function.find(std::make_tuple(is_height_flipped,
374  _cols_out_of_bounds[0] + _cols_out_of_bounds[1] < _output->info()->dimension(1),
375  _cols_out_of_bounds[0] > 0,
376  _cols_out_of_bounds[1] > 0));
377 
378  if(it != map_function.end())
379  {
380  _crop_function = it->second;
381  }
382 
383  INEKernel::configure(calculate_max_window(*_output->info()));
384 }
uint8_t * ptr_to_element(const Coordinates &id) const
Return a pointer to the element at the passed coordinates.
Definition: ITensor.h:63
virtual size_t dimension(size_t index) const =0
Return the size of the requested dimension.
virtual ITensorInfo & set_tensor_shape(const TensorShape &shape)=0
Set the shape of an already initialized tensor.
Window calculate_max_window(const ValidRegion &valid_region, const Steps &steps=Steps(), bool skip_border=false, BorderSize border_size=BorderSize())
Calculate the maximum window for a given tensor shape and border setting.
Definition: Helpers.cpp:28
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor's metadata.

References arm_compute::calculate_max_window(), ITensorInfo::dimension(), ITensor::info(), ITensor::ptr_to_element(), ITensorInfo::set_tensor_shape(), and ITensorInfo::tensor_shape().

◆ name()

const char* name ( ) const
inlineoverridevirtual

Name of the kernel.

Returns
Kernel name

Implements ICPPKernel.

Definition at line 43 of file NECropKernel.h.

44  {
45  return "NECropKernel";
46  }

◆ operator=() [1/2]

NECropKernel& operator= ( const NECropKernel )
delete

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

◆ operator=() [2/2]

NECropKernel& operator= ( NECropKernel &&  )
default

Allow instances of this class to be moved.

◆ run()

void run ( const Window window,
const ThreadInfo info 
)
overridevirtual

Execute the kernel on the passed window.

Warning
If is_parallelisable() returns false then the passed window must be equal to window()
Note
The window has to be a region within the window returned by the window() method
The width of the window has to be a multiple of num_elems_processed_per_iteration().
Parameters
[in]windowRegion on which to execute the kernel. (Must be a region of the window returned by window())
[in]infoInfo about executing thread and CPU.

Implements ICPPKernel.

Definition at line 386 of file NECropKernel.cpp.

387 {
391 
392  ARM_COMPUTE_ERROR_ON(_input->info()->has_padding());
393  ARM_COMPUTE_ERROR_ON(_output->info()->has_padding());
394 
395  uint32_t batch_index = *(reinterpret_cast<int32_t *>(_box_ind->ptr_to_element(Coordinates(_crop_box_ind))));
396  Coordinates input_offset(0, _end[0] < _start[0] ? _start[0] - _cols_out_of_bounds[0] : _start[0] + _cols_out_of_bounds[0],
397  _end[1] < _start[1] ? _start[1] - _rows_out_of_bounds[0] : _start[1] + _rows_out_of_bounds[0], batch_index);
398  (*_crop_function)(_input, _output, input_offset, _extrapolation_value, _rows_out_of_bounds, _cols_out_of_bounds, _in_bounds_crop_function);
399 }
const Window & window() const
The maximum window the kernel can be executed on.
Definition: IKernel.cpp:28
uint8_t * ptr_to_element(const Coordinates &id) const
Return a pointer to the element at the passed coordinates.
Definition: ITensor.h:63
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:337
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:160
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor's metadata.
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s)
Definition: Validate.h:205
#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k)
Definition: Validate.h:940
virtual bool has_padding() const =0
Checks if the tensor has been allocated with padding or not.

References ARM_COMPUTE_ERROR_ON, ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW, ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL, ARM_COMPUTE_UNUSED, ITensorInfo::has_padding(), ITensor::info(), arm_compute::test::validation::info, ITensor::ptr_to_element(), and IKernel::window().

◆ validate()

Status validate ( const ITensorInfo input,
const ITensorInfo crop_boxes,
const ITensorInfo box_ind,
const ITensorInfo output,
uint32_t  crop_box_ind = 0,
float  extrapolation_value = 0 
)
static

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

Note
Supported tensor rank: up to 4
Padding not supported.
Parameters
[in]inputSource tensor info. Data type supported: U16/S16/U32/S32/F16/F32. Data layouts supported: NHWC.
[in]crop_boxesTensor info for tensor containing all possible boxes used to crop the image. Data type supported: F32
[in]box_indTensor info for the one dimensional tensor mapping the crop_box_ind to the index of the 3D image in input. Data type supported: F32
[in]outputDestination tensor. Data type supported: F32
[in]crop_box_indIndex of the crop box to be used from crop_boxes. Default is 0.
[in]extrapolation_valueValue to be used for values outside of the image. Default is 0.

Definition at line 275 of file NECropKernel.cpp.

276 {
277  ARM_COMPUTE_UNUSED(extrapolation_value);
281  ARM_COMPUTE_RETURN_ERROR_ON(input->tensor_shape().num_dimensions() > 4);
282  ARM_COMPUTE_RETURN_ERROR_ON(crop_boxes->tensor_shape()[0] != 4);
283  ARM_COMPUTE_RETURN_ERROR_ON(crop_boxes->tensor_shape()[1] != box_ind->tensor_shape()[0]);
284  ARM_COMPUTE_RETURN_ERROR_ON(crop_boxes->tensor_shape()[1] <= crop_box_ind);
285  ARM_COMPUTE_RETURN_ERROR_ON(box_ind->tensor_shape()[0] <= crop_box_ind);
286  if(output->total_size() > 0)
287  {
290  ARM_COMPUTE_RETURN_ERROR_ON(output->num_dimensions() != 3);
291  ARM_COMPUTE_RETURN_ERROR_ON(output->has_padding());
292  }
293  return Status{};
294 }
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(...)
Definition: Validate.h:494
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
Definition: Validate.h:791
1 channel, 1 F32 per channel
1 channel, 1 U16 per channel
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_NOT_IN(t,...)
Definition: Validate.h:693
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
Definition: Error.h:244
#define ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(tensor)
Definition: Validate.h:71
1 channel, 1 F16 per channel
1 channel, 1 S32 per channel
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:160
1 channel, 1 U32 per channel
1 channel, 1 S16 per channel
Num samples, height, width, channels.
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_LAYOUT_NOT_IN(t,...)
Definition: Validate.h:745

References ARM_COMPUTE_RETURN_ERROR_ON, ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED, ARM_COMPUTE_RETURN_ERROR_ON_DATA_LAYOUT_NOT_IN, ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN, ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_NOT_IN, ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT, ARM_COMPUTE_UNUSED, arm_compute::F16, arm_compute::F32, ITensorInfo::has_padding(), arm_compute::NHWC, Dimensions< T >::num_dimensions(), ITensorInfo::num_dimensions(), arm_compute::S16, arm_compute::S32, ITensorInfo::tensor_shape(), ITensorInfo::total_size(), arm_compute::U16, and arm_compute::U32.

Referenced by NECropKernel::configure(), and NECropResize::validate().


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