blob: 9bc2135b6d2031635877e7c989d3d088b98adfab [file] [log] [blame]
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +01001/*
2* Copyright (c) 2020 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 */
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
56 bool padding_changed = false;
57
58 utility::for_each([&](IAccessWindow & w)
59 {
60 padding_changed |= w.update_padding_if_needed(win);
61 },
62 patterns...);
63
64 return window_changed;
65}
66
67/** Intersect multiple valid regions.
68 *
69 * @param[in] regions Valid regions.
70 *
71 * @return Intersection of all regions.
72 */
73template <typename... Ts>
74ValidRegion intersect_valid_regions(const Ts &... regions)
75{
76 auto intersect = [](const ValidRegion & r1, const ValidRegion & r2) -> ValidRegion
77 {
78 ValidRegion region;
79
80 for(size_t d = 0; d < std::min(r1.anchor.num_dimensions(), r2.anchor.num_dimensions()); ++d)
81 {
82 region.anchor.set(d, std::max(r1.anchor[d], r2.anchor[d]));
83 }
84
85 for(size_t d = 0; d < std::min(r1.shape.num_dimensions(), r2.shape.num_dimensions()); ++d)
86 {
87 region.shape.set(d, std::min(r1.shape[d], r2.shape[d]));
88 }
89
90 return region;
91 };
92
93 return utility::foldl(intersect, regions...);
94}
95
96#ifndef DOXYGEN_SKIP_THIS
97/** Calculate the maximum window for a given tensor shape and border setting
98 *
99 * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
100 * @param[in] steps (Optional) Number of elements processed for each step.
101 * @param[in] skip_border (Optional) If true exclude the border region from the window.
102 * @param[in] border_size (Optional) Border size.
103 *
104 * @return The maximum window the kernel can be executed on.
105 */
106Window calculate_max_window(const ValidRegion &valid_region, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize());
107
108/** Calculate the maximum window for a given tensor shape and border setting
109 *
110 * @param[in] info Tensor info object defining the shape of the object for which the window is created.
111 * @param[in] steps (Optional) Number of elements processed for each step.
112 * @param[in] skip_border (Optional) If true exclude the border region from the window.
113 * @param[in] border_size (Optional) Border size.
114 *
115 * @return The maximum window the kernel can be executed on.
116 */
117inline Window calculate_max_window(const ITensorInfo &info, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize())
118{
119 return calculate_max_window(info.valid_region(), steps, skip_border, border_size);
120}
121
122/** Calculate the maximum window used by a horizontal kernel for a given tensor shape and border setting
123 *
124 * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
125 * @param[in] steps (Optional) Number of elements processed for each step.
126 * @param[in] skip_border (Optional) If true exclude the border region from the window.
127 * @param[in] border_size (Optional) Border size. The border region will be excluded from the window.
128 *
129 * @return The maximum window the kernel can be executed on.
130 */
131Window calculate_max_window_horizontal(const ValidRegion &valid_region, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize());
132
133/** Calculate the maximum window used by a horizontal kernel for a given tensor shape and border setting
134 *
135 * @param[in] info Tensor info object defining the shape of the object for which the window is created.
136 * @param[in] steps (Optional) Number of elements processed for each step.
137 * @param[in] skip_border (Optional) If true exclude the border region from the window.
138 * @param[in] border_size (Optional) Border size.
139 *
140 * @return The maximum window the kernel can be executed on.
141 */
142inline Window calculate_max_window_horizontal(const ITensorInfo &info, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize())
143{
144 return calculate_max_window_horizontal(info.valid_region(), steps, skip_border, border_size);
145}
146
147/** Calculate the maximum window for a given tensor shape and border setting. The window will also includes the border.
148 *
149 * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
150 * @param[in] steps (Optional) Number of elements processed for each step.
151 * @param[in] border_size (Optional) Border size. The border region will be included in the window.
152 *
153 * @return The maximum window the kernel can be executed on.
154 */
155Window calculate_max_enlarged_window(const ValidRegion &valid_region, const Steps &steps = Steps(), BorderSize border_size = BorderSize());
156
157/** Calculate the maximum window for a given tensor shape and border setting. The window will also includes the border.
158 *
159 * @param[in] info Tensor info object defining the shape of the object for which the window is created.
160 * @param[in] steps (Optional) Number of elements processed for each step.
161 * @param[in] border_size (Optional) Border size. The border region will be included in the window.
162 *
163 * @return The maximum window the kernel can be executed on.
164 */
165inline Window calculate_max_enlarged_window(const ITensorInfo &info, const Steps &steps = Steps(), BorderSize border_size = BorderSize())
166{
167 return calculate_max_enlarged_window(info.valid_region(), steps, border_size);
168}
169#endif /* DOXYGEN_SKIP_THIS */
170} // namespace arm_compute
171
172#endif /* SRC_CORE_HELPERS_WINDOWHELPERS_H */