blob: eccf7f2d18b81029f2c5fc942b71bd4c85cd9906 [file] [log] [blame]
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +01001/*
Pablo Marquez Telloa81fc842022-08-23 17:17:38 +01002* Copyright (c) 2020-2022 Arm Limited.
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +01003 *
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 */
24#ifndef SRC_CORE_HELPERS_WINDOWHELPERS_H
25#define SRC_CORE_HELPERS_WINDOWHELPERS_H
26
27#include "arm_compute/core/IAccessWindow.h"
28#include "arm_compute/core/Steps.h"
29#include "arm_compute/core/Window.h"
30
31namespace arm_compute
32{
33/** Update window and padding size for each of the access patterns.
34 *
35 * First the window size is reduced based on all access patterns that are not
36 * allowed to modify the padding of the underlying tensor. Then the padding of
37 * the remaining tensors is increased to match the window.
38 *
39 * @param[in] win Window that is used by the kernel.
40 * @param[in] patterns Access patterns used to calculate the final window and padding.
41 *
42 * @return True if the window has been changed. Changes to the padding do not
43 * influence the returned value.
44 */
45template <typename... Ts>
46bool update_window_and_padding(Window &win, Ts &&... patterns)
47{
48 bool window_changed = false;
49
50 utility::for_each([&](const IAccessWindow & w)
51 {
52 window_changed |= w.update_window_if_needed(win);
53 },
54 patterns...);
55
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010056 utility::for_each([&](IAccessWindow & w)
57 {
Pablo Marquez Telloa81fc842022-08-23 17:17:38 +010058 w.update_padding_if_needed(win);
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010059 },
60 patterns...);
61
62 return window_changed;
63}
64
65/** Intersect multiple valid regions.
66 *
67 * @param[in] regions Valid regions.
68 *
69 * @return Intersection of all regions.
70 */
71template <typename... Ts>
72ValidRegion intersect_valid_regions(const Ts &... regions)
73{
74 auto intersect = [](const ValidRegion & r1, const ValidRegion & r2) -> ValidRegion
75 {
76 ValidRegion region;
77
78 for(size_t d = 0; d < std::min(r1.anchor.num_dimensions(), r2.anchor.num_dimensions()); ++d)
79 {
80 region.anchor.set(d, std::max(r1.anchor[d], r2.anchor[d]));
81 }
82
83 for(size_t d = 0; d < std::min(r1.shape.num_dimensions(), r2.shape.num_dimensions()); ++d)
84 {
85 region.shape.set(d, std::min(r1.shape[d], r2.shape[d]));
86 }
87
88 return region;
89 };
90
91 return utility::foldl(intersect, regions...);
92}
93
94#ifndef DOXYGEN_SKIP_THIS
95/** Calculate the maximum window for a given tensor shape and border setting
96 *
97 * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
98 * @param[in] steps (Optional) Number of elements processed for each step.
99 * @param[in] skip_border (Optional) If true exclude the border region from the window.
100 * @param[in] border_size (Optional) Border size.
101 *
102 * @return The maximum window the kernel can be executed on.
103 */
104Window calculate_max_window(const ValidRegion &valid_region, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize());
105
106/** Calculate the maximum window for a given tensor shape and border setting
107 *
SiCongLic7b1e842021-02-22 14:28:33 +0000108 * @param[in] shape Shape of the tensor space
109 * @param[in] steps (Optional) Number of elements processed for each step.
110 * @param[in] skip_border (Optional) If true exclude the border region from the window.
111 * @param[in] border_size (Optional) Border size.
112 *
113 * @return The maximum window the kernel can be executed on.
114 */
115Window calculate_max_window(const TensorShape &shape, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize());
116
117/** Calculate the maximum window for a given tensor shape and border setting
118 *
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100119 * @param[in] info Tensor info object defining the shape of the object for which the window is created.
120 * @param[in] steps (Optional) Number of elements processed for each step.
121 * @param[in] skip_border (Optional) If true exclude the border region from the window.
122 * @param[in] border_size (Optional) Border size.
123 *
124 * @return The maximum window the kernel can be executed on.
125 */
126inline Window calculate_max_window(const ITensorInfo &info, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize())
127{
SiCongLic7b1e842021-02-22 14:28:33 +0000128 return calculate_max_window(info.tensor_shape(), steps, skip_border, border_size);
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100129}
130
131/** Calculate the maximum window used by a horizontal kernel for a given tensor shape and border setting
132 *
133 * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
134 * @param[in] steps (Optional) Number of elements processed for each step.
135 * @param[in] skip_border (Optional) If true exclude the border region from the window.
136 * @param[in] border_size (Optional) Border size. The border region will be excluded from the window.
137 *
138 * @return The maximum window the kernel can be executed on.
139 */
140Window calculate_max_window_horizontal(const ValidRegion &valid_region, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize());
141
142/** Calculate the maximum window used by a horizontal kernel for a given tensor shape and border setting
143 *
144 * @param[in] info Tensor info object defining the shape of the object for which the window is created.
145 * @param[in] steps (Optional) Number of elements processed for each step.
146 * @param[in] skip_border (Optional) If true exclude the border region from the window.
147 * @param[in] border_size (Optional) Border size.
148 *
149 * @return The maximum window the kernel can be executed on.
150 */
151inline Window calculate_max_window_horizontal(const ITensorInfo &info, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize())
152{
153 return calculate_max_window_horizontal(info.valid_region(), steps, skip_border, border_size);
154}
155
156/** Calculate the maximum window for a given tensor shape and border setting. The window will also includes the border.
157 *
158 * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
159 * @param[in] steps (Optional) Number of elements processed for each step.
160 * @param[in] border_size (Optional) Border size. The border region will be included in the window.
161 *
162 * @return The maximum window the kernel can be executed on.
163 */
164Window calculate_max_enlarged_window(const ValidRegion &valid_region, const Steps &steps = Steps(), BorderSize border_size = BorderSize());
165
166/** Calculate the maximum window for a given tensor shape and border setting. The window will also includes the border.
167 *
168 * @param[in] info Tensor info object defining the shape of the object for which the window is created.
169 * @param[in] steps (Optional) Number of elements processed for each step.
170 * @param[in] border_size (Optional) Border size. The border region will be included in the window.
171 *
172 * @return The maximum window the kernel can be executed on.
173 */
174inline Window calculate_max_enlarged_window(const ITensorInfo &info, const Steps &steps = Steps(), BorderSize border_size = BorderSize())
175{
176 return calculate_max_enlarged_window(info.valid_region(), steps, border_size);
177}
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000178
Mohammed Suhail Munshifa79fda2022-09-20 11:49:23 +0100179/** Calculate the squashed or maximum window for the given tensor shape.
180 *
181 * If the tensor data resides continuously in the memory, the tensor can be interpreted
182 * as 1D array and all the dimensions can be squashed together into the x-dimension.
183 * Otherwise, generate the max window for the given tensor shape.
184 *
185 * @param[in] src Tensor info object defining the shape of the input tensor.
186 *
187 * @return The maximum window the kernel can be executed on and the preferred split dimension.
188 */
189std::pair<Window, size_t> calculate_squashed_or_max_window(const ITensorInfo &src);
190
Viet-Hoa Do0d05b662022-09-09 15:39:05 +0100191/** Calculate the squashed or maximum window for the given tensor shapes.
192 *
193 * If the tensor data resides continuously in the memory, the tensor can be interpreted
194 * as 1D array and all the dimensions can be squashed together into the x-dimension.
195 * Otherwise, generate the max window for the given tensor shapes.
196 *
197 * @param[in] src0 Tensor info object defining the shape of the first input tensor.
198 * @param[in] src1 Tensor info object defining the shape of the second input tensor.
199 *
200 * @return The squashed or maximum window the kernel can be executed on and the preferred split dimension.
201 */
202std::pair<Window, size_t> calculate_squashed_or_max_window(const ITensorInfo &src0, const ITensorInfo &src1);
203
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000204/** Function to compute the shape of output and window for the given inputs
205 *
206 * @param[in] infos Input tensor informations
207 *
208 * @return A pair of the shape and window
209 */
Sang-Hoon Parkd0b7b4b2021-03-09 10:47:30 +0000210template <typename... Shapes>
211std::pair<TensorShape, Window> compute_output_shape_and_window(const Shapes &... shapes)
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000212{
Sang-Hoon Parkd0b7b4b2021-03-09 10:47:30 +0000213 const TensorShape out_shape = TensorShape::broadcast_shape(shapes...);
214 return std::make_pair(out_shape, calculate_max_window(out_shape));
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000215}
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100216#endif /* DOXYGEN_SKIP_THIS */
217} // namespace arm_compute
218
219#endif /* SRC_CORE_HELPERS_WINDOWHELPERS_H */