blob: e404c18e8a8a8b613d04c8a44bbd10b900615e7f [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>
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010046bool update_window_and_padding(Window &win, Ts &&...patterns)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010047{
48 bool window_changed = false;
49
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010050 utility::for_each([&](const IAccessWindow &w) { window_changed |= w.update_window_if_needed(win); }, patterns...);
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010051
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010052 utility::for_each([&](IAccessWindow &w) { w.update_padding_if_needed(win); }, patterns...);
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010053
54 return window_changed;
55}
56
57/** Intersect multiple valid regions.
58 *
59 * @param[in] regions Valid regions.
60 *
61 * @return Intersection of all regions.
62 */
63template <typename... Ts>
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010064ValidRegion intersect_valid_regions(const Ts &...regions)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010065{
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010066 auto intersect = [](const ValidRegion &r1, const ValidRegion &r2) -> ValidRegion
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010067 {
68 ValidRegion region;
69
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010070 for (size_t d = 0; d < std::min(r1.anchor.num_dimensions(), r2.anchor.num_dimensions()); ++d)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010071 {
72 region.anchor.set(d, std::max(r1.anchor[d], r2.anchor[d]));
73 }
74
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010075 for (size_t d = 0; d < std::min(r1.shape.num_dimensions(), r2.shape.num_dimensions()); ++d)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010076 {
77 region.shape.set(d, std::min(r1.shape[d], r2.shape[d]));
78 }
79
80 return region;
81 };
82
83 return utility::foldl(intersect, regions...);
84}
85
86#ifndef DOXYGEN_SKIP_THIS
87/** Calculate the maximum window for a given tensor shape and border setting
88 *
89 * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
90 * @param[in] steps (Optional) Number of elements processed for each step.
91 * @param[in] skip_border (Optional) If true exclude the border region from the window.
92 * @param[in] border_size (Optional) Border size.
93 *
94 * @return The maximum window the kernel can be executed on.
95 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010096Window calculate_max_window(const ValidRegion &valid_region,
97 const Steps &steps = Steps(),
98 bool skip_border = false,
99 BorderSize border_size = BorderSize());
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100100
101/** Calculate the maximum window for a given tensor shape and border setting
102 *
SiCongLic7b1e842021-02-22 14:28:33 +0000103 * @param[in] shape Shape of the tensor space
104 * @param[in] steps (Optional) Number of elements processed for each step.
105 * @param[in] skip_border (Optional) If true exclude the border region from the window.
106 * @param[in] border_size (Optional) Border size.
107 *
108 * @return The maximum window the kernel can be executed on.
109 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100110Window calculate_max_window(const TensorShape &shape,
111 const Steps &steps = Steps(),
112 bool skip_border = false,
113 BorderSize border_size = BorderSize());
SiCongLic7b1e842021-02-22 14:28:33 +0000114
115/** Calculate the maximum window for a given tensor shape and border setting
116 *
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100117 * @param[in] info Tensor info object defining the shape of the object for which the window is created.
118 * @param[in] steps (Optional) Number of elements processed for each step.
119 * @param[in] skip_border (Optional) If true exclude the border region from the window.
120 * @param[in] border_size (Optional) Border size.
121 *
122 * @return The maximum window the kernel can be executed on.
123 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100124inline Window calculate_max_window(const ITensorInfo &info,
125 const Steps &steps = Steps(),
126 bool skip_border = false,
127 BorderSize border_size = BorderSize())
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100128{
SiCongLic7b1e842021-02-22 14:28:33 +0000129 return calculate_max_window(info.tensor_shape(), steps, skip_border, border_size);
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100130}
131
132/** Calculate the maximum window used by a horizontal kernel for a given tensor shape and border setting
133 *
134 * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
135 * @param[in] steps (Optional) Number of elements processed for each step.
136 * @param[in] skip_border (Optional) If true exclude the border region from the window.
137 * @param[in] border_size (Optional) Border size. The border region will be excluded from the window.
138 *
139 * @return The maximum window the kernel can be executed on.
140 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100141Window calculate_max_window_horizontal(const ValidRegion &valid_region,
142 const Steps &steps = Steps(),
143 bool skip_border = false,
144 BorderSize border_size = BorderSize());
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100145
146/** Calculate the maximum window used by a horizontal kernel for a given tensor shape and border setting
147 *
148 * @param[in] info Tensor info object defining the shape of the object for which the window is created.
149 * @param[in] steps (Optional) Number of elements processed for each step.
150 * @param[in] skip_border (Optional) If true exclude the border region from the window.
151 * @param[in] border_size (Optional) Border size.
152 *
153 * @return The maximum window the kernel can be executed on.
154 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100155inline Window calculate_max_window_horizontal(const ITensorInfo &info,
156 const Steps &steps = Steps(),
157 bool skip_border = false,
158 BorderSize border_size = BorderSize())
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100159{
160 return calculate_max_window_horizontal(info.valid_region(), steps, skip_border, border_size);
161}
162
163/** Calculate the maximum window for a given tensor shape and border setting. The window will also includes the border.
164 *
165 * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
166 * @param[in] steps (Optional) Number of elements processed for each step.
167 * @param[in] border_size (Optional) Border size. The border region will be included in the window.
168 *
169 * @return The maximum window the kernel can be executed on.
170 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100171Window calculate_max_enlarged_window(const ValidRegion &valid_region,
172 const Steps &steps = Steps(),
173 BorderSize border_size = BorderSize());
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100174
175/** Calculate the maximum window for a given tensor shape and border setting. The window will also includes the border.
176 *
177 * @param[in] info Tensor info object defining the shape of the object for which the window is created.
178 * @param[in] steps (Optional) Number of elements processed for each step.
179 * @param[in] border_size (Optional) Border size. The border region will be included in the window.
180 *
181 * @return The maximum window the kernel can be executed on.
182 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100183inline Window calculate_max_enlarged_window(const ITensorInfo &info,
184 const Steps &steps = Steps(),
185 BorderSize border_size = BorderSize())
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100186{
187 return calculate_max_enlarged_window(info.valid_region(), steps, border_size);
188}
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000189
Mohammed Suhail Munshifa79fda2022-09-20 11:49:23 +0100190/** Calculate the squashed or maximum window for the given tensor shape.
191 *
192 * If the tensor data resides continuously in the memory, the tensor can be interpreted
193 * as 1D array and all the dimensions can be squashed together into the x-dimension.
194 * Otherwise, generate the max window for the given tensor shape.
195 *
196 * @param[in] src Tensor info object defining the shape of the input tensor.
197 *
198 * @return The maximum window the kernel can be executed on and the preferred split dimension.
199 */
200std::pair<Window, size_t> calculate_squashed_or_max_window(const ITensorInfo &src);
201
Viet-Hoa Do0d05b662022-09-09 15:39:05 +0100202/** Calculate the squashed or maximum window for the given tensor shapes.
203 *
204 * If the tensor data resides continuously in the memory, the tensor can be interpreted
205 * as 1D array and all the dimensions can be squashed together into the x-dimension.
206 * Otherwise, generate the max window for the given tensor shapes.
207 *
208 * @param[in] src0 Tensor info object defining the shape of the first input tensor.
209 * @param[in] src1 Tensor info object defining the shape of the second input tensor.
210 *
211 * @return The squashed or maximum window the kernel can be executed on and the preferred split dimension.
212 */
213std::pair<Window, size_t> calculate_squashed_or_max_window(const ITensorInfo &src0, const ITensorInfo &src1);
214
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000215/** Function to compute the shape of output and window for the given inputs
216 *
217 * @param[in] infos Input tensor informations
218 *
219 * @return A pair of the shape and window
220 */
Sang-Hoon Parkd0b7b4b2021-03-09 10:47:30 +0000221template <typename... Shapes>
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100222std::pair<TensorShape, Window> compute_output_shape_and_window(const Shapes &...shapes)
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000223{
Sang-Hoon Parkd0b7b4b2021-03-09 10:47:30 +0000224 const TensorShape out_shape = TensorShape::broadcast_shape(shapes...);
225 return std::make_pair(out_shape, calculate_max_window(out_shape));
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000226}
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100227#endif /* DOXYGEN_SKIP_THIS */
228} // namespace arm_compute
229
230#endif /* SRC_CORE_HELPERS_WINDOWHELPERS_H */