blob: 9c9fb909150e965bd7ecda2e14c80dc08b83718e [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Michele Di Giorgiod9eaf612020-07-08 11:12:57 +01002 * Copyright (c) 2017-2019 Arm Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +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 */
Michalis Spyrouf4643372019-11-29 16:17:13 +000024#ifndef ARM_COMPUTE_IACCESS_WINDOW_H
25#define ARM_COMPUTE_IACCESS_WINDOW_H
Anthony Barbier6ff3b192017-09-04 18:44:23 +010026
27#include "arm_compute/core/Coordinates.h"
28#include "arm_compute/core/TensorShape.h"
29#include "arm_compute/core/Types.h"
30
31#include <array>
32
33namespace arm_compute
34{
35class Window;
36class ITensorInfo;
37
38/** Decrease @p required in steps of @p step until it's less than @p available.
39 *
40 * @param[in] required Number of required bytes.
41 * @param[in] available Number of available bytes.
42 * @param[in] step Step size used to decrease required bytes.
43 *
44 * @return Largest value smaller than @p available that is a multiple of @p step
45 *
46 **/
47inline int adjust_down(int required, int available, int step)
48{
49 ARM_COMPUTE_ERROR_ON(step <= 0);
50
51 return required - step * ((required - available + step - 1) / step);
52}
53
54/** Increase @p required in steps of @p step until it's greater than @p available.
55 *
56 * @param[in] required Number of required bytes.
57 * @param[in] available Number of available bytes.
58 * @param[in] step Step size used to increase required bytes.
59 *
60 * @return Largest value smaller than @p available that is a multiple of @p step
61 *
62 **/
63inline int adjust_up(int required, int available, int step)
64{
65 ARM_COMPUTE_ERROR_ON(step <= 0);
66
67 return required + step * ((available - required + step - 1) / step);
68}
69
70/** Interface describing methods to update access window and padding based on kernel parameters. */
71class IAccessWindow
72{
73public:
Alex Gildayc357c472018-03-21 13:54:09 +000074 /** Default virtual destructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010075 virtual ~IAccessWindow() = default;
76 /** Shrink the window if padding is not large enough.
77 *
78 * @param[in] window Window used by the kernel.
79 *
80 * @return True if the window has been changed.
Alex Gildayc357c472018-03-21 13:54:09 +000081 *
Anthony Barbier6ff3b192017-09-04 18:44:23 +010082 */
83 virtual bool update_window_if_needed(Window &window) const = 0;
84 /** Increase the padding to be large enough for the window.
85 *
86 * @param[in] window Window used by the kernel.
87 *
88 * @return True if the padding has been changed.
89 */
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +000090 virtual bool update_padding_if_needed(const Window &window) = 0;
Anthony Barbier6ff3b192017-09-04 18:44:23 +010091 /** Compute the valid region based on access pattern and valid region of the inputs.
92 *
93 * @note This method assumes that there is no border.
94 *
95 * @param[in] window Execution window of the kernel.
96 * @param[in] input_valid_region Combined valid region of all inputs.
97 * @param[in] border_undefined Undefined borders are excluded from the valid region.
98 * @param[in] border_size Size of the border around the XY-plane of the tensor.
Alex Gildayc357c472018-03-21 13:54:09 +000099 *
100 * @return a valid region.
101 *
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100102 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100103 virtual ValidRegion compute_valid_region(const Window &window,
104 ValidRegion input_valid_region,
105 bool border_undefined,
106 BorderSize border_size) const = 0;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100107};
108
109/** Implementation of a rectangular access pattern. */
110class AccessWindowRectangle : public IAccessWindow
111{
112public:
113 /** Constructor for a rectangular access pattern.
114 *
115 * @note Width and height have to be non-negative.
116 *
117 * @param[in,out] info Tensor info of the accessed kernel.
118 * @param[in] x Offset of the access in X direction.
119 * @param[in] y Offset of the access in Y direction.
120 * @param[in] width Number of elements that are accessed in X direction.
121 * @param[in] height Number of elements that are accessed in Y direction.
122 */
123 AccessWindowRectangle(ITensorInfo *info, int x, int y, int width, int height)
124 : AccessWindowRectangle(info, x, y, width, height, 1.f, 1.f)
125 {
126 }
127
128 /** Constructor for a rectangular access pattern.
129 *
130 * @note Width, height and scale have to be non-negative.
131 *
132 * @param[in,out] info Tensor info of the accessed kernel.
133 * @param[in] x Offset of the access in X direction.
134 * @param[in] y Offset of the access in Y direction.
135 * @param[in] width Number of elements that are accessed in X direction.
136 * @param[in] height Number of elements that are accessed in Y direction.
137 * @param[in] scale_x Ratio along the X direction between the window used by the execute_window_loop and the rectangular access pattern defined
138 * @param[in] scale_y Ratio along the Y direction between the window used by the execute_window_loop and the rectangular access pattern defined
139 */
140 AccessWindowRectangle(ITensorInfo *info, int x, int y, int width, int height, float scale_x, float scale_y)
141 : _info(info), _x(x), _y(y), _width(width), _height(height), _scale_x(scale_x), _scale_y(scale_y)
142 {
143 ARM_COMPUTE_ERROR_ON(width < 0);
144 ARM_COMPUTE_ERROR_ON(height < 0);
145 ARM_COMPUTE_ERROR_ON(scale_x < 0);
146 ARM_COMPUTE_ERROR_ON(scale_y < 0);
147 }
148
Alex Gildayc357c472018-03-21 13:54:09 +0000149 /** Prevent instances of this class from being copied (As this class contains pointers) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100150 AccessWindowRectangle(const AccessWindowRectangle &) = delete;
Alex Gildayc357c472018-03-21 13:54:09 +0000151 /** Allow instances of this class to be move constructed */
152 AccessWindowRectangle(AccessWindowRectangle &&) = default;
153 /** Prevent instances of this class from being copied (As this class contains pointers) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100154 AccessWindowRectangle &operator=(const AccessWindowRectangle &) = delete;
Alex Gildayc357c472018-03-21 13:54:09 +0000155 /** Allow instances of this class to be moved */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100156 AccessWindowRectangle &operator=(AccessWindowRectangle &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000157 /** Default destructor */
158 ~AccessWindowRectangle() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100159
160 /** Set the valid region based on access pattern, valid region of the inputs and border mode.
161 *
162 * @param[in] window Execution window of the kernel.
163 * @param[in] input_valid_region Combined valid region of all inputs.
164 * @param[in] border_undefined (Optional) Undefined borders are excluded from the valid region.
165 * @param[in] border_size (Optional) Size of the border around the XY-plane of the tensor.
166 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100167 void set_valid_region(const Window &window,
168 const ValidRegion &input_valid_region,
169 bool border_undefined = false,
170 const BorderSize &border_size = BorderSize(0));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100171
172 /** Compute the valid region based on access pattern, valid region of the inputs and border mode.
173 *
174 * @note This method assumes that there is no border.
175 *
176 * @param[in] window Execution window of the kernel.
177 * @param[in] input_valid_region Combined valid region of all inputs.
Alex Gildayc357c472018-03-21 13:54:09 +0000178 *
179 * @return a valid region.
180 *
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100181 */
182 ValidRegion compute_valid_region(const Window &window, const ValidRegion &input_valid_region) const;
183
184 // Inherited methods overridden:
185
Alex Gildayc357c472018-03-21 13:54:09 +0000186 /** Compute the valid region based on access pattern and valid region of the inputs.
187 *
188 * @note This method assumes that all elements written by the kernel are valid.
189 *
190 * @param[in] window Execution window of the kernel.
191 * @param[in] input_valid_region Combined valid region of all inputs.
192 * @param[in] border_undefined Undefined borders are excluded from the valid region.
193 * @param[in] border_size Size of the border around the XY-plane of the tensor.
194 *
195 * @return a valid region.
196 *
197 */
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100198 ValidRegion compute_valid_region(const Window &window,
199 ValidRegion input_valid_region,
200 bool border_undefined,
201 BorderSize border_size) const override;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100202
203 bool update_window_if_needed(Window &window) const override;
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000204 bool update_padding_if_needed(const Window &window) override;
Michalis Spyrouf4643372019-11-29 16:17:13 +0000205
Anthony Barbieree50f512018-11-15 09:58:00 +0000206protected:
Michalis Spyrouf4643372019-11-29 16:17:13 +0000207 PaddingSize get_needed_padding(const Window &window) const;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100208
209protected:
210 ITensorInfo *_info;
211 int _x;
212 int _y;
213 int _width;
214 int _height;
215 float _scale_x;
216 float _scale_y;
217};
218
219/** Implementation of a column access pattern. */
220class AccessWindowVertical : public AccessWindowRectangle
221{
222public:
223 /** Constructor for a column access pattern.
224 *
225 * @note Height has to be non-negative.
226 *
227 * @param[in,out] info Tensor info of the accessed kernel.
228 * @param[in] y Offset of the access in Y direction.
229 * @param[in] height Number of elements that are accessed in Y direction.
230 * @param[in] scale_y Ratio along the Y direction between the window used by the execute_window_loop and the rectangular access pattern defined
231 */
232 AccessWindowVertical(ITensorInfo *info, int y, int height, float scale_y = 1.f)
233 : AccessWindowRectangle(info, 0, y, 1, height, 1.f, scale_y)
234 {
235 ARM_COMPUTE_ERROR_ON(height < 0);
236 ARM_COMPUTE_ERROR_ON(scale_y < 0);
237 }
238};
239
240/** Implementation of a row access pattern. */
241class AccessWindowHorizontal : public AccessWindowRectangle
242{
243public:
244 /** Constructor for a row access pattern.
245 *
246 * @note Width has to be non-negative.
247 *
248 * @param[in,out] info Tensor info of the accessed kernel.
249 * @param[in] x Offset of the access in X direction.
250 * @param[in] width Number of elements that are accessed in X direction.
251 * @param[in] scale_x Ratio along the X direction between the window used by the execute_window_loop and the rectangular access pattern defined
252 */
253 AccessWindowHorizontal(ITensorInfo *info, int x, int width, float scale_x = 1.f)
254 : AccessWindowRectangle(info, x, 0, width, 1, scale_x, 1.f)
255 {
256 ARM_COMPUTE_ERROR_ON(width < 0);
257 ARM_COMPUTE_ERROR_ON(scale_x < 0);
258 }
259};
260} // namespace arm_compute
Michalis Spyrouf4643372019-11-29 16:17:13 +0000261#endif /*ARM_COMPUTE_IACCESS_WINDOW_H*/