24.02.1
|
Go to the documentation of this file.
45 struct CropSelectorData
50 using CropSelectorPtr = std::add_pointer<bool(
const CropSelectorData &data)>
::type;
51 using CropUKernelPtr = std::add_pointer<void(
52 const ITensor *,
const ITensor *,
float *, Coordinates, int32_t, int32_t, int32_t,
bool,
bool)>
::type;
61 static const CropUKernel available_kernels[] = {
62 {
"fp16_neon_crop", [](
const CropSelectorData &data) {
return data.dt ==
DataType::F16; },
64 {
"f32_neon_crop", [](
const CropSelectorData &data) {
return data.dt ==
DataType::F32; },
66 {
"u8_neon_crop", [](
const CropSelectorData &data) {
return data.dt ==
DataType::U8; },
68 {
"u16_neon_crop", [](
const CropSelectorData &data) {
return data.dt ==
DataType::U16; },
70 {
"u32_neon_crop", [](
const CropSelectorData &data) {
return data.dt ==
DataType::U32; },
72 {
"s8_neon_crop", [](
const CropSelectorData &data) {
return data.dt ==
DataType::S8; },
74 {
"s16_neon_crop", [](
const CropSelectorData &data) {
return data.dt ==
DataType::S16; },
76 {
"s32_neon_crop", [](
const CropSelectorData &data) {
return data.dt ==
DataType::S32; },
86 const CropUKernel *get_implementation(
const CropSelectorData &data)
88 for (
const auto &uk : available_kernels)
90 if (uk.is_selected(data))
99 inline void out_of_bounds_crop_window(
const ITensor *output,
101 float extrapolation_value,
102 int32_t window_step_x,
103 int32_t output_width_start,
104 int32_t output_width_limit)
106 auto in =
wrapper::vdup_n(extrapolation_value, wrapper::traits::vector_128_tag());
108 int32_t limit = (output_width_limit - output_width_start) *
static_cast<int32_t
>(output->info()->dimension(0));
109 float *output_start_ptr = output_ptr + output_width_start * output->info()->dimension(0);
110 for (; x <= limit - window_step_x; x += window_step_x)
114 for (; x < limit; ++x)
116 *(output_start_ptr + x) = extrapolation_value;
120 inline void execute_window(
const ITensor *
input,
121 const ITensor *output,
122 Coordinates input_offset,
123 float extrapolation_value,
124 const std::array<uint32_t, 2> &rows_out_of_bounds,
125 const std::array<uint32_t, 2> &cols_out_of_bounds,
127 bool is_height_flipped,
128 bool has_cols_in_bounds,
129 bool has_cols_out_of_bounds_before,
130 bool has_cols_out_of_bounds_after,
131 bool input_has_single_channel,
132 bool is_width_flipped)
135 const int window_step_x = 16 /
sizeof(float);
136 auto *output_ptr =
reinterpret_cast<float *
>(output->buffer());
153 out_of_bounds_crop_window(output, output_ptr, extrapolation_value, window_step_x, 0,
154 rows_out_of_bounds[0] * output->info()->dimension(1));
155 output_ptr += rows_out_of_bounds[0] * output->info()->dimension(1) * output->info()->dimension(0);
157 for (uint32_t row = rows_out_of_bounds[0];
158 static_cast<int32_t
>(row) <
static_cast<int32_t
>(output->info()->dimension(2) - rows_out_of_bounds[1]);
159 ++row, is_height_flipped ? --input_offset[2] : ++input_offset[2])
163 if (has_cols_out_of_bounds_before)
165 out_of_bounds_crop_window(output, output_ptr, extrapolation_value, window_step_x, 0, cols_out_of_bounds[0]);
168 if (has_cols_in_bounds)
170 (*in_bounds_crop_function)(
input, output, output_ptr, input_offset, window_step_x, cols_out_of_bounds[0],
171 output->info()->dimension(1) - cols_out_of_bounds[1], input_has_single_channel,
175 if (has_cols_out_of_bounds_after)
177 out_of_bounds_crop_window(output, output_ptr, extrapolation_value, window_step_x,
178 output->info()->dimension(1) - cols_out_of_bounds[1],
179 output->info()->dimension(1));
181 output_ptr += output->info()->dimension(1) * output->info()->dimension(0);
184 out_of_bounds_crop_window(output, output_ptr, extrapolation_value, window_step_x, 0,
185 rows_out_of_bounds[1] * output->info()->dimension(1));
191 _crop_boxes(nullptr),
197 _extrapolation_value(0),
198 _rows_out_of_bounds(),
199 _cols_out_of_bounds()
207 uint32_t crop_box_ind,
208 float extrapolation_value)
212 crop_box_ind, extrapolation_value));
215 _crop_boxes = crop_boxes;
218 _crop_box_ind = crop_box_ind;
219 _extrapolation_value = extrapolation_value;
226 uint32_t crop_box_ind,
227 float extrapolation_value)
230 const auto *uk = get_implementation(CropSelectorData{
input->data_type()});
266 abs(_end[1] - _start[1]) + 1);
269 bool is_width_flipped = _end[0] < _start[0];
270 bool is_height_flipped = _end[1] < _start[1];
271 if (is_height_flipped)
273 _rows_out_of_bounds[0] = _start[1] >=
static_cast<int32_t
>(_input->
info()->
dimension(2))
274 ? std::min(
static_cast<uint32_t
>(_start[1] - _input->
info()->
dimension(2) + 1),
277 _rows_out_of_bounds[1] = _end[1] < 0 ? std::min(
static_cast<uint32_t
>(-_end[1]),
283 _rows_out_of_bounds[0] = _start[1] < 0 ? std::min(
static_cast<uint32_t
>(-_start[1]),
286 _rows_out_of_bounds[1] = _end[1] >=
static_cast<int32_t
>(_input->
info()->
dimension(2))
287 ? std::min(
static_cast<uint32_t
>(_end[1] - _input->
info()->
dimension(2) + 1),
291 if (is_width_flipped)
293 _cols_out_of_bounds[0] = _start[0] >=
static_cast<int32_t
>(_input->
info()->
dimension(1))
294 ? std::min(
static_cast<uint32_t
>(_start[0] - _input->
info()->
dimension(1) + 1),
297 _cols_out_of_bounds[1] = _end[0] < 0 ? std::min(
static_cast<uint32_t
>(-_end[0]),
303 _cols_out_of_bounds[0] = _start[0] < 0 ? std::min(
static_cast<uint32_t
>(-_start[0]),
306 _cols_out_of_bounds[1] = _end[0] >=
static_cast<int32_t
>(_input->
info()->
dimension(1))
307 ? std::min(
static_cast<uint32_t
>(_end[0] - _input->
info()->
dimension(1) + 1),
324 const auto *uk = get_implementation(CropSelectorData{_input->
info()->
data_type()});
328 0, _end[0] < _start[0] ? _start[0] - _cols_out_of_bounds[0] : _start[0] + _cols_out_of_bounds[0],
329 _end[1] < _start[1] ? _start[1] - _rows_out_of_bounds[0] : _start[1] + _rows_out_of_bounds[0], batch_index);
330 execute_window(_input, _output, input_offset, _extrapolation_value, _rows_out_of_bounds, _cols_out_of_bounds,
333 _cols_out_of_bounds[0] +
334 _cols_out_of_bounds[1]<_output->
info()->
dimension(1), _cols_out_of_bounds[0]> 0,
335 _cols_out_of_bounds[1]> 0,
336 _start[0] <= _end[0], _end[0] < _start[0]);
void u32_in_bounds_crop_window(const ITensor *input, const ITensor *output, float *output_ptr, Coordinates input_offset, int32_t window_step_x, int32_t output_width_start, int32_t output_width_limit, bool input_has_single_channel, bool is_width_flipped)
decltype(strategy::transforms) typedef type
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
Window calculate_max_window(const ValidRegion &valid_region, const Steps &steps, bool skip_border, BorderSize border_size)
@ NHWC
Num samples, height, width, channels.
@ U16
unsigned 16-bit number
#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k)
virtual ITensorInfo & set_tensor_shape(const TensorShape &shape)=0
Set the shape of an already initialized tensor.
const CropSelectorPtr is_selected
void fp32_in_bounds_crop_window(const ITensor *input, const ITensor *output, float *output_ptr, Coordinates input_offset, int32_t window_step_x, int32_t output_width_start, int32_t output_width_limit, bool input_has_single_channel, bool is_width_flipped)
Interface for CPU tensor.
#define REGISTER_FP16_NEON(func_name)
Includes all wrapper headers at once.
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
virtual size_t dimension(size_t index) const =0
Return the size of the requested dimension.
virtual bool has_padding() const =0
Checks if the tensor has been allocated with padding or not.
#define REGISTER_FP32_NEON(func_name)
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor's metadata.
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
void fp16_in_bounds_crop_window(const ITensor *input, const ITensor *output, float *output_ptr, Coordinates input_offset, int32_t window_step_x, int32_t output_width_start, int32_t output_width_limit, bool input_has_single_channel, bool is_width_flipped)
#define ARM_COMPUTE_ERROR_THROW_ON(status)
@ U32
unsigned 32-bit number
void u16_in_bounds_crop_window(const ITensor *input, const ITensor *output, float *output_ptr, Coordinates input_offset, int32_t window_step_x, int32_t output_width_start, int32_t output_width_limit, bool input_has_single_channel, bool is_width_flipped)
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_NOT_IN(t,...)
void run(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.
#define ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(tensor)
@ U8
unsigned 8-bit number
@ S16
signed 16-bit number
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s)
#define REGISTER_INTEGER_NEON(func_name)
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(...)
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.
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
void s16_in_bounds_crop_window(const ITensor *input, const ITensor *output, float *output_ptr, Coordinates input_offset, int32_t window_step_x, int32_t output_width_start, int32_t output_width_limit, bool input_has_single_channel, bool is_width_flipped)
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_LAYOUT_NOT_IN(t,...)
void s8_in_bounds_crop_window(const ITensor *input, const ITensor *output, float *output_ptr, Coordinates input_offset, int32_t window_step_x, int32_t output_width_start, int32_t output_width_limit, bool input_has_single_channel, bool is_width_flipped)
const Window & window() const
The maximum window the kernel can be executed on.
Information about executing thread and CPU.
void configure_output_shape()
Configure output tensor's shape as this can only be determined at runtime.
void u8_in_bounds_crop_window(const ITensor *input, const ITensor *output, float *output_ptr, Coordinates input_offset, int32_t window_step_x, int32_t output_width_start, int32_t output_width_limit, bool input_has_single_channel, bool is_width_flipped)
void vstore(uint8_t *ptr, uint8x8_t val)
Describe a multidimensional execution window.
void(const ITensor *, const ITensor *, float *, Coordinates, int32_t, int32_t, int32_t, bool, bool) InBoundsCropFunction
Function to use for in bounds crop for the particular tensor types passed to configure()
Copyright (c) 2017-2024 Arm Limited.
uint8_t * ptr_to_element(const Coordinates &id) const
Return a pointer to the element at the passed coordinates.
@ F16
16-bit floating-point number
@ S32
signed 32-bit number
Store the tensor's metadata.
@ F32
32-bit floating-point number
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
virtual size_t total_size() const =0
Returns the total size of the tensor in bytes.
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.
DataType
Available data types.
virtual size_t num_dimensions() const =0
The number of dimensions of the tensor (rank)
NECropKernel()
Default constructor.
uint8x8_t vdup_n(uint8_t value, traits::vector_64_tag)
void s32_in_bounds_crop_window(const ITensor *input, const ITensor *output, float *output_ptr, Coordinates input_offset, int32_t window_step_x, int32_t output_width_start, int32_t output_width_limit, bool input_has_single_channel, bool is_width_flipped)