Compute Library
 22.05
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  InterpolationPolicy interpolate_policy, SamplingPolicy sampling_policy, bool border_undefined)
30 {
31  const DataLayout data_layout = src_info.data_layout();
34 
35  const float scale_x = static_cast<float>(dst_shape[idx_width]) / src_info.tensor_shape()[idx_width];
36  const float scale_y = static_cast<float>(dst_shape[idx_height]) / src_info.tensor_shape()[idx_height];
37  const float sampling_point = (sampling_policy == SamplingPolicy::CENTER) ? 0.5f : 0.0f;
38 
39  // Get input's valid region start and end points
40  const int valid_start_in_x = src_info.valid_region().anchor[idx_width];
41  const int valid_start_in_y = src_info.valid_region().anchor[idx_height];
42  const int valid_end_in_x = src_info.valid_region().anchor[idx_width] + src_info.valid_region().shape[idx_width];
43  const int valid_end_in_y = src_info.valid_region().anchor[idx_height] + src_info.valid_region().shape[idx_height];
44 
45  // Initialize output's valid region start and end points
46  auto valid_start_out_x = static_cast<int>(valid_start_in_x * scale_x);
47  auto valid_start_out_y = static_cast<int>(valid_start_in_y * scale_y);
48  auto valid_end_out_x = std::min<int>(std::ceil(valid_end_in_x * scale_x), dst_shape[idx_width]);
49  auto valid_end_out_y = std::min<int>(std::ceil(valid_end_in_y * scale_y), dst_shape[idx_height]);
50 
51  // Handle valid points in case of the bi-linear interpolation
52  if(border_undefined)
53  {
54  switch(interpolate_policy)
55  {
57  {
58  // (start_out + sampling_point) >= (start_in * scale)
59  // start_out = ceil((start_in * scale) - sampling_point)
60  valid_start_out_x = std::ceil(valid_start_in_x * scale_x - sampling_point);
61  valid_start_out_y = std::ceil(valid_start_in_y * scale_y - sampling_point);
62 
63  // (end_out - 1 + sampling_point) < (end_in * scale)
64  // end_out = ceil((end_in * scale) - sampling_point); // <-- ceil(x - 1) strictly less
65  valid_end_out_x = std::ceil(valid_end_in_x * scale_x - sampling_point);
66  valid_end_out_y = std::ceil(valid_end_in_y * scale_y - sampling_point);
67  break;
68  }
70  {
71  // (start_out + sampling_point) >= ((start_in + sampling_point) * scale)
72  // start_out = ceil(((start_in + sampling_point) * scale) - sampling_point)
73  valid_start_out_x = std::ceil((valid_start_in_x + sampling_point) * scale_x - sampling_point);
74  valid_start_out_y = std::ceil((valid_start_in_y + sampling_point) * scale_y - sampling_point);
75 
76  // (end_out - 1 + sampling_point) <= ((end_in - 1 + sampling_point) * scale)
77  // end_out = floor(((end_in - 1 + sampling_point) * scale) - sampling_point + 1)
78  valid_end_out_x = std::floor((valid_end_in_x - 1.f + sampling_point) * scale_x - sampling_point + 1.f);
79  valid_end_out_y = std::floor((valid_end_in_y - 1.f + sampling_point) * scale_y - sampling_point + 1.f);
80  break;
81  }
83  break;
84  default:
85  {
86  ARM_COMPUTE_ERROR("Invalid InterpolationPolicy");
87  break;
88  }
89  }
90  }
91 
92  // Setup output valid region
94 
95  valid_region.anchor.set(idx_width, std::max(0, valid_start_out_x));
96  valid_region.anchor.set(idx_height, std::max(0, valid_start_out_y));
97 
98  valid_region.shape.set(idx_width, std::min<size_t>(valid_end_out_x - valid_start_out_x, dst_shape[idx_width]));
99  valid_region.shape.set(idx_height, std::min<size_t>(valid_end_out_y - valid_start_out_y, dst_shape[idx_height]));
100 
101  return valid_region;
102 }
103 
104 const std::map<DataLayout, std::vector<DataLayoutDimension>> &get_layout_map()
105 {
111 
112  static const std::map<DataLayout, std::vector<DataLayoutDimension>> layout_map =
113  {
114  { DataLayout::NDHWC, { C, W, H, D, N } },
115  { DataLayout::NCDHW, { W, H, D, C, N } },
116  { DataLayout::NHWC, { C, W, H, N } },
117  { DataLayout::NCHW, { W, H, C, N } }
118  };
119 
120  return layout_map;
121 }
122 } // namespace arm_compute
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:76
InterpolationPolicy
Interpolation method.
Definition: Types.h:411
Shape of a tensor.
Definition: TensorShape.h:39
TensorShape shape
Shape of the valid region.
Definition: Types.h:266
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
Definition: Error.h:352
DataLayoutDimension
[DataLayout enum definition]
Definition: Types.h:124
Output values are defined by bilinear interpolation between the pixels.
Store the tensor&#39;s metadata.
Definition: ITensorInfo.h:40
Output values are defined to match the source pixel whose center is nearest to the sample position...
const ValidRegion valid_region
Definition: Scale.cpp:214
Copyright (c) 2017-2022 Arm Limited.
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:104
virtual ValidRegion valid_region() const =0
Valid region of the tensor.
Samples are taken at pixel center.
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
Coordinates of an item.
Definition: Coordinates.h:37
unsigned int N
Num samples, depth, height, width, channels.
Output values are determined by averaging the source pixels whose areas fall under the area of the de...
Num samples, channels, depth, height, width.
Num samples, channels, height, width.
TensorInfo src_info(src_shape, 1, data_type)
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
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:193
unsigned int num_dimensions() const
Returns the effective dimensionality of the tensor.
Definition: Dimensions.h:143
Num samples, height, width, channels.
Container for valid region of a window.
Definition: Types.h:184
DataLayout
[DataLayout enum definition]
Definition: Types.h:113
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:79
Coordinates anchor
Anchor for the start of the valid region.
Definition: Types.h:265
SamplingPolicy
Available Sampling Policies.
Definition: Types.h:104
virtual DataLayout data_layout() const =0
Get the data layout of the tensor.