Compute Library
 23.11
NESpaceToDepthLayerKernel.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2020 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 
28 #include "arm_compute/core/Types.h"
31 
35 
36 #include <arm_neon.h>
37 #include <cstdint>
38 
40 
41 namespace arm_compute
42 {
43 namespace
44 {
45 Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, int32_t block_shape)
46 {
49  ARM_COMPUTE_RETURN_ERROR_ON(input->num_dimensions() > 4);
50 
51  ARM_COMPUTE_RETURN_ERROR_ON(block_shape < 1);
52 
53  // Validate output if initialized
54  if (output->total_size() != 0)
55  {
56  const DataLayout data_layout = input->data_layout();
61  ARM_COMPUTE_RETURN_ERROR_ON(input->tensor_shape()[idx_width] % block_shape != 0);
62  ARM_COMPUTE_RETURN_ERROR_ON(input->tensor_shape()[idx_height] % block_shape != 0);
63  ARM_COMPUTE_RETURN_ERROR_ON(input->tensor_shape()[idx_batch] != output->tensor_shape()[idx_batch]);
64  ARM_COMPUTE_RETURN_ERROR_ON(output->tensor_shape()[idx_channel] % (block_shape * block_shape) != 0);
65  ARM_COMPUTE_RETURN_ERROR_ON(input->tensor_shape().total_size() != output->tensor_shape().total_size());
67  }
68 
69  return Status{};
70 }
71 } // namespace
72 
74  : _input(nullptr), _output(nullptr), _block_shape(), _data_layout(DataLayout::UNKNOWN)
75 {
76 }
77 
78 void NESpaceToDepthLayerKernel::configure(const ITensor *input, ITensor *output, int32_t block_shape)
79 {
81 
83  auto_init_if_empty(*output->info(), output_shape, 1, input->info()->data_type());
84 
85  ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), block_shape));
86 
87  _input = input;
88  _block_shape = block_shape;
89  _output = output;
90  _data_layout = input->info()->data_layout();
91 
92  // Configure kernel window
93  Window win = calculate_max_window(*output->info(), Steps());
94  INEKernel::configure(win);
95 }
96 
97 Status NESpaceToDepthLayerKernel::validate(const ITensorInfo *input, const ITensorInfo *output, int32_t block_shape)
98 {
100  return Status{};
101 }
102 
104 {
108 
110  const int element_size = _input->info()->element_size();
111 
112  const size_t channel_size = _input->info()->dimension(channel_idx);
113 
114  Window slice_out = window.first_slice_window_3D();
115 
116  int batch_id = 0;
117 
118  // Main loop for NCHW and NHWC
119  if (_data_layout == DataLayout::NCHW)
120  {
121  do
122  {
123  Iterator out(_output, slice_out);
125  slice_out,
126  [&](const Coordinates &id)
127  {
128  const size_t channel_id = id.z();
129  const size_t in_x = id.x() * _block_shape + (channel_id / channel_size) % _block_shape;
130  const size_t in_y = id.y() * _block_shape + (channel_id / channel_size) / _block_shape;
131  const int z = channel_id % channel_size;
132  Coordinates input_coords{in_x, in_y, z, batch_id};
133  memcpy(out.ptr(), _input->ptr_to_element(input_coords), element_size);
134  },
135  out);
136  ++batch_id;
137  } while (window.slide_window_slice_3D(slice_out));
138  }
139  else
140  {
141  do
142  {
143  Iterator out(_output, slice_out);
145  slice_out,
146  [&](const Coordinates &id)
147  {
148  const size_t channel_id = id.x();
149  const size_t in_x = id.y() * _block_shape + (channel_id / channel_size) % _block_shape;
150  const size_t in_y = id.z() * _block_shape + (channel_id / channel_size) / _block_shape;
151  const int z = channel_id % channel_size;
152  Coordinates input_coords{z, in_x, in_y, batch_id};
153  memcpy(out.ptr(), _input->ptr_to_element(input_coords), element_size);
154  },
155  out);
156  ++batch_id;
157  } while (window.slide_window_slice_3D(slice_out));
158  }
159 }
160 } // namespace arm_compute
arm_compute::DataLayout::NCHW
@ NCHW
Num samples, channels, height, width.
arm_compute::Steps
Class to describe a number of elements in each dimension.
Definition: Steps.h:40
arm_compute::NESpaceToDepthLayerKernel::NESpaceToDepthLayerKernel
NESpaceToDepthLayerKernel()
Default constructor.
Definition: NESpaceToDepthLayerKernel.cpp:73
arm_compute::NESpaceToDepthLayerKernel::configure
void configure(const ITensor *input, ITensor *output, int32_t block_shape)
Initialise the kernel's inputs and output.
Definition: NESpaceToDepthLayerKernel.cpp:78
arm_compute::test::validation::idx_height
const int idx_height
Definition: Scale.cpp:263
Helpers.h
arm_compute::DataLayout
DataLayout
[DataLayout enum definition]
Definition: CoreTypes.h:110
arm_compute::DataLayoutDimension::CHANNEL
@ CHANNEL
channel
arm_compute::calculate_max_window
Window calculate_max_window(const ValidRegion &valid_region, const Steps &steps, bool skip_border, BorderSize border_size)
Definition: WindowHelpers.cpp:29
arm_compute::test::validation::output_shape
TensorShape output_shape
Definition: LSTMLayerQuantized.cpp:469
arm_compute::TensorShape
Shape of a tensor.
Definition: TensorShape.h:39
arm_compute::cpu::kernels::validate_arguments
Status validate_arguments(const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *dst, const PadStrideInfo &conv_info)
Definition: CpuDirectConv2dKernel.cpp:57
ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL
#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k)
Definition: Validate.h:1079
arm_compute::ITensorInfo::element_size
virtual size_t element_size() const =0
Element size in bytes calculated as data_size() * num_channels()
Types.h
arm_compute::ITensor
Interface for CPU tensor.
Definition: ITensor.h:36
arm_compute::NESpaceToDepthLayerKernel::validate
static Status validate(const ITensorInfo *input, const ITensorInfo *output, int32_t block_shape)
Static function to check if given info will lead to a valid configuration of NESpaceToDepthLayerKerne...
Definition: NESpaceToDepthLayerKernel.cpp:97
arm_compute::test::validation::idx_width
const int idx_width
Definition: Scale.cpp:262
wrapper.h
Includes all wrapper headers at once.
ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...)
Definition: Validate.h:677
arm_compute::DataLayoutDimension::WIDTH
@ WIDTH
width
arm_compute::cpu::data_layout
constexpr auto data_layout
Definition: impl.h:36
ARM_COMPUTE_RETURN_ON_ERROR
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:205
arm_compute::ITensorInfo::dimension
virtual size_t dimension(size_t index) const =0
Return the size of the requested dimension.
NESpaceToDepthLayerKernel.h
ARM_COMPUTE_ERROR_ON_NULLPTR
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:159
arm_compute::ITensor::info
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor's metadata.
arm_compute::Iterator::ptr
constexpr uint8_t * ptr() const
Return a pointer to the current pixel.
Definition: Helpers.inl:147
ARM_COMPUTE_ERROR_THROW_ON
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:455
arm_compute::execute_window_loop
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...
Definition: Helpers.inl:74
arm_compute::DataLayoutDimension::HEIGHT
@ HEIGHT
height
arm_compute::Iterator
Iterator updated by execute_window_loop for each window element.
Definition: Helpers.h:46
ARM_COMPUTE_RETURN_ERROR_ON
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
Definition: Error.h:298
arm_compute::auto_init_if_empty
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...
Definition: AutoConfiguration.h:43
arm_compute::Status
Status class.
Definition: Error.h:52
WindowHelpers.h
ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s)
Definition: Validate.h:203
arm_compute::Window::slide_window_slice_3D
bool slide_window_slice_3D(Window &slice) const
Slide the passed 3D window slice.
Definition: Window.h:350
ARM_COMPUTE_UNUSED
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:151
arm_compute::Coordinates
Coordinates of an item.
Definition: Coordinates.h:37
AutoConfiguration.h
arm_compute::Window::first_slice_window_3D
Window first_slice_window_3D() const
First 3D slice of the window.
Definition: Window.h:306
arm_compute::IKernel::window
const Window & window() const
The maximum window the kernel can be executed on.
Definition: IKernel.cpp:28
arm_compute::ThreadInfo
Information about executing thread and CPU.
Definition: CPPTypes.h:180
arm_compute::get_data_layout_dimension_index
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:201
ShapeCalculator.h
arm_compute::Window
Describe a multidimensional execution window.
Definition: Window.h:39
arm_compute
Copyright (c) 2017-2023 Arm Limited.
Definition: introduction.dox:24
arm_compute::ITensor::ptr_to_element
uint8_t * ptr_to_element(const Coordinates &id) const
Return a pointer to the element at the passed coordinates.
Definition: ITensor.h:63
arm_compute::UNKNOWN
@ UNKNOWN
Unknown CL kernel type.
Definition: CLTypes.h:80
ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR
#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...)
Definition: Validate.h:161
arm_compute::misc::shape_calculator::compute_space_to_depth_shape
TensorShape compute_space_to_depth_shape(const ITensorInfo *input, int32_t block_shape)
Calculate the space to batch output shape of a tensor.
Definition: ShapeCalculator.h:1322
arm_compute::cpu::channel_idx
const size_t channel_idx
Definition: impl.h:39
arm_compute::ITensorInfo
Store the tensor's metadata.
Definition: ITensorInfo.h:44
arm_compute::DataLayoutDimension::BATCHES
@ BATCHES
batches
arm_compute::misc::shape_calculator
Definition: ShapeCalculator.h:41
ITensor.h
arm_compute::test::validation::info
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
arm_compute::DataType::UNKNOWN
@ UNKNOWN
Unknown data type.
Validate.h
arm_compute::Window::x
constexpr const Dimension & x() const
Alias to access the first dimension of the window.
Definition: Window.h:158
arm_compute::NESpaceToDepthLayerKernel::run
void run(const Window &window, const ThreadInfo &info) override
Execute the kernel on the passed window.
Definition: NESpaceToDepthLayerKernel.cpp:103
arm_compute::test::validation::input
auto input
Definition: LSTMLayerQuantized.cpp:486
arm_compute::Window::z
constexpr const Dimension & z() const
Alias to access the third dimension of the window.
Definition: Window.h:176