40 inline void fill_constant_value_single_channel_special(ITensor *tensor,
const Window &window,
unsigned int right,
unsigned int bottom,
const PixelValue &constant_border_value)
43 constant_border_value.get(border_value);
44 uint8_t *
const start_valid_region = tensor->ptr_to_element(tensor->info()->valid_region().anchor);
45 const size_t width = tensor->info()->valid_region().shape[0];
46 const size_t height = tensor->info()->valid_region().shape[1];
47 const int stridey = tensor->info()->strides_in_bytes()[1];
50 Window vertical(window);
51 vertical.set(
Window::DimY, Window::Dimension(0, height, 1));
53 Iterator vertical_it(tensor, vertical);
57 const auto row_start =
reinterpret_cast<float *
>(start_valid_region + vertical_it.offset());
60 *(row_start - 1) = border_value;
61 std::fill_n(row_start + width, right, border_value);
66 Iterator plane_it(tensor, window);
71 uint8_t *base_addr = start_valid_region + plane_it.offset();
73 const auto row_start =
reinterpret_cast<float *
>(base_addr - stridey);
75 std::fill_n(row_start - 1, 1 + width + right, border_value);
78 const unsigned low_border_size = height + bottom;
79 for(
unsigned int i = height; i < low_border_size; ++i)
81 const auto row_start =
reinterpret_cast<float *
>(base_addr + i * stridey);
84 std::fill_n(row_start - 1, 1 + width + right, border_value);
92 : _tensor(nullptr), _border_size(0), _mode(
BorderMode::
UNDEFINED), _constant_border_value(static_cast<float>(0.f))
111 _constant_border_value = constant_border_value;
113 _border_size.limit(tensor->
padding());
119 INEKernel::configure(win);
127 if(_border_size.
empty())
141 fill_constant_value_single_channel_special(_tensor, window, _border_size.
right, _border_size.
bottom, _constant_border_value);
145 fill_constant_value_single_channel(window);
151 fill_replicate_single_channel(window);
167 void NEFillBorderKernel::fill_replicate_single_channel(
const Window &window)
177 Iterator vertical_it(_tensor, vertical);
181 uint8_t *base_addr = start_valid_region + vertical_it.
offset();
183 for(
unsigned int i = 0; i < _border_size.
left; ++i)
185 std::memcpy(base_addr + static_cast<int>(i - _border_size.
left) * element_size, vertical_it.
ptr(), element_size);
188 for(
unsigned int i = 0; i < _border_size.
right; ++i)
190 std::memcpy(base_addr + (width + i) * element_size, vertical_it.
ptr() + (width - 1) * element_size, element_size);
201 uint8_t *base_addr = start_valid_region + plane_it.offset();
203 for(
int i = -_border_size.
top; i < 0; ++i)
206 std::memcpy(base_addr + i * static_cast<int>(_tensor->
info()->
strides_in_bytes()[1]) - _border_size.
left * element_size,
207 base_addr - _border_size.
left * element_size, (_border_size.
left + width + _border_size.
right) * element_size);
211 for(
unsigned int i = height; i < height + _border_size.
bottom; ++i)
215 base_addr + (height - 1) * _tensor->
info()->
strides_in_bytes()[1] - _border_size.
left * element_size, (_border_size.
left + width + _border_size.
right) * element_size);
221 void NEFillBorderKernel::fill_constant_value_single_channel(
const Window &window)
233 Iterator vertical_it(_tensor, vertical);
237 uint8_t *base_addr = start_valid_region + vertical_it.
offset();
239 for(
unsigned int i = 0; i < _border_size.
left; ++i)
241 std::memcpy(base_addr + static_cast<int>(i - _border_size.
left) * element_size, &_constant_border_value, element_size);
244 for(
unsigned int i = 0; i < _border_size.
right; ++i)
246 std::memcpy(base_addr + (width + i) * element_size, &_constant_border_value, element_size);
257 uint8_t *base_addr = start_valid_region + plane_it.offset();
259 for(
int i = -_border_size.
top; i < 0; ++i)
262 for(
unsigned int j = 0; j < (_border_size.
left + width + _border_size.
right); ++j)
264 std::memcpy(base_addr + i * stridey + static_cast<int>(j - _border_size.
left) * element_size, &_constant_border_value, element_size);
269 const unsigned low_border_size = height + _border_size.
bottom;
270 for(
unsigned int i = height; i < low_border_size; ++i)
273 for(
unsigned int j = 0; j < (_border_size.
left + width + _border_size.
right); ++j)
275 std::memcpy(base_addr + i * stridey + static_cast<int>(j - _border_size.
left) * element_size, &_constant_border_value, element_size);
BorderMode
Methods available to handle borders.
NEFillBorderKernel()
Default Constructor.
unsigned int top
top of the border
Class describing the value of a pixel for any image format.
const Window & window() const
The maximum window the kernel can be executed on.
uint8_t * ptr_to_element(const Coordinates &id) const
Return a pointer to the element at the passed coordinates.
TensorShape shape
Shape of the valid region.
Container for 2D border size.
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
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.
Store the tensor's metadata.
Describe one of the image's dimensions with a start, end and step.
unsigned int bottom
bottom of the border
void configure(ITensor *tensor, BorderSize border_size, BorderMode border_mode, const PixelValue &constant_border_value=PixelValue())
Initialise the function.
Interface for CPU tensor.
void use_tensor_dimensions(const TensorShape &shape, size_t first_dimension=Window::DimX)
Use the tensor's dimensions to fill the window dimensions.
Copyright (c) 2017-2021 Arm Limited.
virtual ValidRegion valid_region() const =0
Valid region of the tensor.
static constexpr size_t DimX
Alias for dimension 0 also known as X dimension.
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
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.
constexpr uint8_t * ptr() const
Return a pointer to the current pixel.
virtual BorderSize border_size() const
The size of the border for that kernel.
virtual size_t element_size() const =0
Element size in bytes calculated as data_size() * num_channels()
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
unsigned int right
right of the border
#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k)
void run(const Window &window, const ThreadInfo &info) override
Execute the kernel on the passed window.
void run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info) override
Execute the kernel on the passed window.
static constexpr size_t DimY
Alias for dimension 1 also known as Y dimension.
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.
Information about executing thread and CPU.
constexpr bool empty() const
Check if the entire border is zero.
static constexpr size_t DimZ
Alias for dimension 2 also known as Z dimension.
Borders are left undefined.
Pixels outside the image are assumed to have the same value as the closest image pixel.
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
void execute_window_loop(const Window &w, L &&lambda_function, Ts &&... iterators)
Iterate through the passed window, automatically adjusting the iterators and calling the lambda_funct...
virtual const Strides & strides_in_bytes() const =0
The strides in bytes for accessing each dimension of the tensor.
constexpr size_t offset() const
Return the offset in bytes from the first element to the current position of the iterator.
Iterator updated by execute_window_loop for each window element.
Describe a multidimensional execution window.
Coordinates anchor
Anchor for the start of the valid region.
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s)