blob: 30a55fcbc632b53345a8276120f949ac1d7ae273 [file] [log] [blame]
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +01001/*
Viet-Hoa Do0d05b662022-09-09 15:39:05 +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#include "src/core/helpers/WindowHelpers.h"
25
26namespace arm_compute
27{
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010028Window
29calculate_max_window(const ValidRegion &valid_region, const Steps &steps, bool skip_border, BorderSize border_size)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010030{
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010031 if (!skip_border)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010032 {
33 border_size = BorderSize(0);
34 }
35
36 const Coordinates &anchor = valid_region.anchor;
37 const TensorShape &shape = valid_region.shape;
38
39 Window window;
40
41 window.set(0, Window::Dimension(
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010042 // Skip the border left of the image
43 anchor[0] + border_size.left,
44 // Skip the border right of the image
45 // Make sure the window width is a multiple of the step size
46 anchor[0] + border_size.left +
47 ceil_to_multiple(std::max(0, static_cast<int>(shape[0]) - static_cast<int>(border_size.left) -
48 static_cast<int>(border_size.right)),
49 steps[0]),
50 steps[0]));
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010051
52 size_t n = 1;
53
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010054 if (anchor.num_dimensions() > 1)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010055 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010056 window.set(1,
57 Window::Dimension(
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010058 // Skip the border above the image
59 anchor[1] + border_size.top,
60 // Skip the border below the image
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010061 anchor[1] + border_size.top +
62 ceil_to_multiple(std::max(0, static_cast<int>(shape[1]) - static_cast<int>(border_size.top) -
63 static_cast<int>(border_size.bottom)),
64 steps[1]),
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010065 steps[1]));
66
67 ++n;
68 }
69
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010070 if (anchor.num_dimensions() > 2)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010071 {
72 window.set(2, Window::Dimension(anchor[2], std::max<size_t>(1, shape[2]), steps[2]));
73
74 ++n;
75 }
76
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010077 for (; n < anchor.num_dimensions(); ++n)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010078 {
79 window.set(n, Window::Dimension(anchor[n], std::max<size_t>(1, shape[n])));
80 }
81
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010082 for (; n < Coordinates::num_max_dimensions; ++n)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010083 {
84 window.set(n, Window::Dimension(0, 1));
85 }
86
87 return window;
88}
89
SiCongLic7b1e842021-02-22 14:28:33 +000090Window calculate_max_window(const TensorShape &shape, const Steps &steps, bool skip_border, BorderSize border_size)
91{
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010092 if (!skip_border)
SiCongLic7b1e842021-02-22 14:28:33 +000093 {
94 border_size = BorderSize(0);
95 }
96
97 Window window;
98
99 window.set(0, Window::Dimension(
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100100 // Skip the border left of the image
101 border_size.left,
102 // Skip the border right of the image
103 // Make sure the window width is a multiple of the step size
104 border_size.left +
105 ceil_to_multiple(std::max(0, static_cast<int>(shape[0]) - static_cast<int>(border_size.left) -
106 static_cast<int>(border_size.right)),
107 steps[0]),
108 steps[0]));
SiCongLic7b1e842021-02-22 14:28:33 +0000109
110 size_t n = 1;
111
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100112 if (shape.num_dimensions() > 1)
SiCongLic7b1e842021-02-22 14:28:33 +0000113 {
114 window.set(1, Window::Dimension(
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100115 // Skip the border above the image
116 border_size.top,
117 // Skip the border below the image
118 border_size.top + ceil_to_multiple(std::max(0, static_cast<int>(shape[1]) -
119 static_cast<int>(border_size.top) -
120 static_cast<int>(border_size.bottom)),
121 steps[1]),
122 steps[1]));
SiCongLic7b1e842021-02-22 14:28:33 +0000123
124 ++n;
125 }
126
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100127 if (shape.num_dimensions() > 2)
SiCongLic7b1e842021-02-22 14:28:33 +0000128 {
129 window.set(2, Window::Dimension(0, std::max<size_t>(1, shape[2]), steps[2]));
130
131 ++n;
132 }
133
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100134 for (; n < shape.num_dimensions(); ++n)
SiCongLic7b1e842021-02-22 14:28:33 +0000135 {
136 window.set(n, Window::Dimension(0, std::max<size_t>(1, shape[n])));
137 }
138
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100139 for (; n < Coordinates::num_max_dimensions; ++n)
SiCongLic7b1e842021-02-22 14:28:33 +0000140 {
141 window.set(n, Window::Dimension(0, 1));
142 }
143
144 return window;
145}
146
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100147Window calculate_max_enlarged_window(const ValidRegion &valid_region, const Steps &steps, BorderSize border_size)
148{
149 const Coordinates &anchor = valid_region.anchor;
150 const TensorShape &shape = valid_region.shape;
151
152 Window window;
153
154 window.set(0, Window::Dimension(
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100155 // move the anchor to the start from the border
156 anchor[0] - border_size.left,
157 // move the anchor to include the right end border
158 // Make sure the window width is a multiple of the step size
159 anchor[0] - border_size.left +
160 ceil_to_multiple(shape[0] + border_size.left + border_size.right, steps[0]),
161 steps[0]));
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100162
163 size_t n = 1;
164
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100165 if (anchor.num_dimensions() > 1)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100166 {
167 window.set(1, Window::Dimension(
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100168 // Include the border above the image
169 anchor[1] - border_size.top,
170 // Include the border below the image
171 anchor[1] - border_size.top +
172 ceil_to_multiple(shape[1] + border_size.top + border_size.bottom, steps[1]),
173 steps[1]));
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100174
175 ++n;
176 }
177
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100178 if (anchor.num_dimensions() > 2)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100179 {
180 window.set(2, Window::Dimension(0, std::max<size_t>(1, shape[n]), steps[2]));
181
182 ++n;
183 }
184
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100185 for (; n < anchor.num_dimensions(); ++n)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100186 {
187 window.set(n, Window::Dimension(anchor[n], std::max<size_t>(1, shape[n])));
188 }
189
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100190 for (; n < Coordinates::num_max_dimensions; ++n)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100191 {
192 window.set(n, Window::Dimension(0, 1));
193 }
194
195 return window;
196}
197
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100198Window calculate_max_window_horizontal(const ValidRegion &valid_region,
199 const Steps &steps,
200 bool skip_border,
201 BorderSize border_size)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100202{
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100203 if (skip_border)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100204 {
205 border_size.top = 0;
206 border_size.bottom = 0;
207 }
208 else
209 {
210 border_size.left = 0;
211 border_size.right = 0;
212 }
213
214 const Coordinates &anchor = valid_region.anchor;
215 const TensorShape &shape = valid_region.shape;
216
217 Window window;
218
219 window.set(0, Window::Dimension(
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100220 // Skip the border left of the image
221 anchor[0] + border_size.left,
222 // Skip the border right of the image
223 // Make sure the window width is a multiple of the step size
224 anchor[0] + border_size.left +
225 ceil_to_multiple(std::max(0, static_cast<int>(shape[0]) - static_cast<int>(border_size.left) -
226 static_cast<int>(border_size.right)),
227 steps[0]),
228 steps[0]));
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100229
230 size_t n = 1;
231
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100232 if (anchor.num_dimensions() > 1)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100233 {
234 window.set(1, Window::Dimension(
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100235 // Skip the border above the image
236 anchor[1] - border_size.top,
237 // Skip the border below the image
238 anchor[1] + shape[1] + border_size.bottom, 1));
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100239
240 ++n;
241 }
242
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100243 for (; n < anchor.num_dimensions(); ++n)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100244 {
245 window.set(n, Window::Dimension(anchor[n], std::max<size_t>(1, shape[n])));
246 }
247
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100248 for (; n < Coordinates::num_max_dimensions; ++n)
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100249 {
250 window.set(n, Window::Dimension(0, 1));
251 }
252
253 return window;
254}
Viet-Hoa Do0d05b662022-09-09 15:39:05 +0100255
256std::pair<Window, size_t> calculate_squashed_or_max_window(const ITensorInfo &src0, const ITensorInfo &src1)
257{
Mohammed Suhail Munshifa79fda2022-09-20 11:49:23 +0100258 const auto &shape0 = src0.tensor_shape();
259 const auto &shape1 = src1.tensor_shape();
260 const auto &strides0 = src0.strides_in_bytes();
261 const auto &strides1 = src1.strides_in_bytes();
262 const auto num_dimensions = std::max(src0.num_dimensions(), src1.num_dimensions());
Viet-Hoa Do0d05b662022-09-09 15:39:05 +0100263
264 Window win;
265 size_t split_dimension = Window::DimY;
Mohammed Suhail Munshifa79fda2022-09-20 11:49:23 +0100266 size_t dim = 0;
Viet-Hoa Do0d05b662022-09-09 15:39:05 +0100267
268 size_t squashed_bytes = src0.element_size();
269
270 // Try to squash the low dimensions together.
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100271 for (; dim < num_dimensions; ++dim)
Viet-Hoa Do0d05b662022-09-09 15:39:05 +0100272 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100273 if (shape0[dim] != shape1[dim] || strides0[dim] != squashed_bytes || strides1[dim] != squashed_bytes)
Viet-Hoa Do0d05b662022-09-09 15:39:05 +0100274 {
275 break;
276 }
277
278 squashed_bytes *= shape0[dim];
279 }
280
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100281 if (dim == num_dimensions)
Viet-Hoa Do0d05b662022-09-09 15:39:05 +0100282 {
283 auto squashed_elements = squashed_bytes / src0.element_size();
284
285 split_dimension = Window::DimX;
286
287 // The input tensors can be interpreted as 1D array.
288 win.set(0, Window::Dimension(0, squashed_elements, 1));
289
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100290 for (dim = 1; dim < Coordinates::num_max_dimensions; ++dim)
Viet-Hoa Do0d05b662022-09-09 15:39:05 +0100291 {
292 win.set(dim, Window::Dimension(0, 1, 1));
293 }
294 }
295 else
296 {
297 // Generates the max window.
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100298 for (dim = 0; dim < Coordinates::num_max_dimensions; ++dim)
Viet-Hoa Do0d05b662022-09-09 15:39:05 +0100299 {
300 win.set(dim, Window::Dimension(0, std::max(shape0[dim], shape1[dim]), 1));
301 }
302 }
303
304 return std::make_pair(win, split_dimension);
305}
Mohammed Suhail Munshifa79fda2022-09-20 11:49:23 +0100306
307std::pair<Window, size_t> calculate_squashed_or_max_window(const ITensorInfo &src)
308{
309 const auto &shape = src.tensor_shape();
310 const auto &strides = src.strides_in_bytes();
311 const auto num_dimensions = src.num_dimensions();
312
313 Window win;
314 size_t split_dimension = Window::DimY;
315 size_t dim = 0;
316 size_t squashed_bytes = src.element_size();
317
318 // Try to squash the low dimensions together.
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100319 for (; dim < num_dimensions; ++dim)
Mohammed Suhail Munshifa79fda2022-09-20 11:49:23 +0100320 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100321 if (strides[dim] != squashed_bytes)
Mohammed Suhail Munshifa79fda2022-09-20 11:49:23 +0100322 {
323 break;
324 }
325 squashed_bytes *= shape[dim];
326 }
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100327 if (dim == num_dimensions)
Mohammed Suhail Munshifa79fda2022-09-20 11:49:23 +0100328 {
329 const auto squashed_elements = squashed_bytes / src.element_size();
330 split_dimension = Window::DimX;
331 // The input tensor can be interpreted as 1D array.
332 win.set(0, Window::Dimension(0, squashed_elements, 1));
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100333 for (dim = 1; dim < Coordinates::num_max_dimensions; ++dim)
Mohammed Suhail Munshifa79fda2022-09-20 11:49:23 +0100334 {
335 win.set(dim, Window::Dimension(0, 1, 1));
336 }
337 }
338 else
339 {
340 // Generate the max window.
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100341 for (dim = 0; dim < Coordinates::num_max_dimensions; ++dim)
Mohammed Suhail Munshifa79fda2022-09-20 11:49:23 +0100342 {
343 win.set(dim, Window::Dimension(0, shape[dim], 1));
344 }
345 }
346 return std::make_pair(win, split_dimension);
347}
348
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +0100349} // namespace arm_compute