Compute Library
 23.11
Helpers.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-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 
26 namespace arm_compute
27 {
29  const TensorShape &dst_shape,
30  InterpolationPolicy interpolate_policy,
32  bool border_undefined)
33 {
37 
38  const float scale_x = static_cast<float>(dst_shape[idx_width]) / src_info.tensor_shape()[idx_width];
39  const float scale_y = static_cast<float>(dst_shape[idx_height]) / src_info.tensor_shape()[idx_height];
40  const float sampling_point = (sampling_policy == SamplingPolicy::CENTER) ? 0.5f : 0.0f;
41 
42  // Get input's valid region start and end points
43  const int valid_start_in_x = src_info.valid_region().anchor[idx_width];
44  const int valid_start_in_y = src_info.valid_region().anchor[idx_height];
45  const int valid_end_in_x = src_info.valid_region().anchor[idx_width] + src_info.valid_region().shape[idx_width];
46  const int valid_end_in_y = src_info.valid_region().anchor[idx_height] + src_info.valid_region().shape[idx_height];
47 
48  // Initialize output's valid region start and end points
49  auto valid_start_out_x = static_cast<int>(valid_start_in_x * scale_x);
50  auto valid_start_out_y = static_cast<int>(valid_start_in_y * scale_y);
51  auto valid_end_out_x = std::min<int>(std::ceil(valid_end_in_x * scale_x), dst_shape[idx_width]);
52  auto valid_end_out_y = std::min<int>(std::ceil(valid_end_in_y * scale_y), dst_shape[idx_height]);
53 
54  // Handle valid points in case of the bi-linear interpolation
55  if (border_undefined)
56  {
57  switch (interpolate_policy)
58  {
60  {
61  // (start_out + sampling_point) >= (start_in * scale)
62  // start_out = ceil((start_in * scale) - sampling_point)
63  valid_start_out_x = std::ceil(valid_start_in_x * scale_x - sampling_point);
64  valid_start_out_y = std::ceil(valid_start_in_y * scale_y - sampling_point);
65 
66  // (end_out - 1 + sampling_point) < (end_in * scale)
67  // end_out = ceil((end_in * scale) - sampling_point); // <-- ceil(x - 1) strictly less
68  valid_end_out_x = std::ceil(valid_end_in_x * scale_x - sampling_point);
69  valid_end_out_y = std::ceil(valid_end_in_y * scale_y - sampling_point);
70  break;
71  }
73  {
74  // (start_out + sampling_point) >= ((start_in + sampling_point) * scale)
75  // start_out = ceil(((start_in + sampling_point) * scale) - sampling_point)
76  valid_start_out_x = std::ceil((valid_start_in_x + sampling_point) * scale_x - sampling_point);
77  valid_start_out_y = std::ceil((valid_start_in_y + sampling_point) * scale_y - sampling_point);
78 
79  // (end_out - 1 + sampling_point) <= ((end_in - 1 + sampling_point) * scale)
80  // end_out = floor(((end_in - 1 + sampling_point) * scale) - sampling_point + 1)
81  valid_end_out_x = std::floor((valid_end_in_x - 1.f + sampling_point) * scale_x - sampling_point + 1.f);
82  valid_end_out_y = std::floor((valid_end_in_y - 1.f + sampling_point) * scale_y - sampling_point + 1.f);
83  break;
84  }
86  break;
87  default:
88  {
89  ARM_COMPUTE_ERROR("Invalid InterpolationPolicy");
90  break;
91  }
92  }
93  }
94 
95  // Setup output valid region
97 
98  valid_region.anchor.set(idx_width, std::max(0, valid_start_out_x));
99  valid_region.anchor.set(idx_height, std::max(0, valid_start_out_y));
100 
101  valid_region.shape.set(idx_width, std::min<size_t>(valid_end_out_x - valid_start_out_x, dst_shape[idx_width]));
102  valid_region.shape.set(idx_height, std::min<size_t>(valid_end_out_y - valid_start_out_y, dst_shape[idx_height]));
103 
104  return valid_region;
105 }
106 
107 const std::map<DataLayout, std::vector<DataLayoutDimension>> &get_layout_map()
108 {
114 
115  static const std::map<DataLayout, std::vector<DataLayoutDimension>> layout_map = {
116  {DataLayout::NDHWC, {C, W, H, D, N}},
117  {DataLayout::NCDHW, {W, H, D, C, N}},
118  {DataLayout::NHWC, {C, W, H, N}},
119  {DataLayout::NCHW, {W, H, C, N}}};
120 
121  return layout_map;
122 }
123 } // namespace arm_compute
arm_compute::DataLayout::NCHW
@ NCHW
Num samples, channels, height, width.
arm_compute::test::validation::dst_shape
TensorShape dst_shape
Definition: DFT.cpp:164
N
unsigned int N
Definition: CpuGemmAssemblyDispatch.cpp:103
arm_compute::test::validation::idx_height
const int idx_height
Definition: Scale.cpp:263
arm_compute::Dimensions::set
void set(size_t dimension, T value, bool increase_dim_unit=true)
Accessor to set the value of one of the dimensions.
Definition: Dimensions.h:75
Helpers.h
arm_compute::DataLayout
DataLayout
[DataLayout enum definition]
Definition: CoreTypes.h:110
arm_compute::DataLayoutDimension::CHANNEL
@ CHANNEL
channel
arm_compute::DataLayout::NCDHW
@ NCDHW
Num samples, channels, depth, height, width.
arm_compute::DataLayout::NHWC
@ NHWC
Num samples, height, width, channels.
arm_compute::DataLayoutDimension
DataLayoutDimension
[DataLayout enum definition]
Definition: CoreTypes.h:121
arm_compute::InterpolationPolicy::AREA
@ AREA
Output values are determined by averaging the source pixels whose areas fall under the area of the de...
arm_compute::SamplingPolicy
SamplingPolicy
Available Sampling Policies.
Definition: Types.h:84
arm_compute::TensorShape
Shape of a tensor.
Definition: TensorShape.h:39
arm_compute::TensorInfo::valid_region
ValidRegion valid_region() const override
Valid region of the tensor.
Definition: TensorInfo.h:291
arm_compute::TensorInfo::data_layout
DataLayout data_layout() const override
Get the data layout of the tensor.
Definition: TensorInfo.h:303
arm_compute::test::validation::sampling_policy
sampling_policy
Definition: Scale.cpp:250
ARM_COMPUTE_ERROR
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
Definition: Error.h:354
arm_compute::InterpolationPolicy
InterpolationPolicy
Interpolation method.
Definition: Types.h:360
arm_compute::test::validation::idx_width
const int idx_width
Definition: Scale.cpp:262
arm_compute::DataLayoutDimension::WIDTH
@ WIDTH
width
arm_compute::cpu::data_layout
constexpr auto data_layout
Definition: impl.h:36
arm_compute::test::validation::valid_region
const ValidRegion valid_region
Definition: Scale.cpp:214
arm_compute::DataLayoutDimension::DEPTH
@ DEPTH
depth
arm_compute::get_layout_map
const std::map< DataLayout, std::vector< DataLayoutDimension > > & get_layout_map()
Returns a static map used to find an index or dimension based on a data layout.
Definition: Helpers.cpp:107
arm_compute::DataLayoutDimension::HEIGHT
@ HEIGHT
height
arm_compute::ValidRegion
Container for valid region of a window.
Definition: Types.h:143
arm_compute::test::validation::scale_y
const float scale_y
Definition: Scale.cpp:260
arm_compute::Coordinates
Coordinates of an item.
Definition: Coordinates.h:37
arm_compute::test::validation::scale_x
const float scale_x
Definition: Scale.cpp:259
arm_compute::InterpolationPolicy::BILINEAR
@ BILINEAR
Output values are defined by bilinear interpolation between the pixels.
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
arm_compute::ValidRegion::shape
TensorShape shape
Shape of the valid region.
Definition: Types.h:223
arm_compute::calculate_valid_region_scale
ValidRegion calculate_valid_region_scale(const ITensorInfo &src_info, const TensorShape &dst_shape, InterpolationPolicy interpolate_policy, SamplingPolicy sampling_policy, bool border_undefined)
Helper function to calculate the Valid Region for Scale.
Definition: Helpers.cpp:28
arm_compute
Copyright (c) 2017-2023 Arm Limited.
Definition: introduction.dox:24
arm_compute::test::validation::src_info
TensorInfo src_info(src_shape, 1, data_type)
arm_compute::InterpolationPolicy::NEAREST_NEIGHBOR
@ NEAREST_NEIGHBOR
Output values are defined to match the source pixel whose center is nearest to the sample position.
arm_compute::SamplingPolicy::CENTER
@ CENTER
Samples are taken at pixel center.
arm_compute::ITensorInfo
Store the tensor's metadata.
Definition: ITensorInfo.h:44
arm_compute::DataLayoutDimension::BATCHES
@ BATCHES
batches
arm_compute::TensorShape::set
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:78
arm_compute::Dimensions::num_dimensions
unsigned int num_dimensions() const
Returns the effective dimensionality of the tensor.
Definition: Dimensions.h:142
arm_compute::TensorInfo::tensor_shape
const TensorShape & tensor_shape() const override
Size for each dimension of the tensor.
Definition: TensorInfo.h:245
arm_compute::DataLayout::NDHWC
@ NDHWC
Num samples, depth, height, width, channels.
arm_compute::ValidRegion::anchor
Coordinates anchor
Anchor for the start of the valid region.
Definition: Types.h:222