2 * Copyright (c) 2017 ARM Limited.
4 * SPDX-License-Identifier: MIT
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:
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
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
24 #ifndef __ARM_COMPUTE_IACCESS_WINDOW_H__
25 #define __ARM_COMPUTE_IACCESS_WINDOW_H__
27 #include "arm_compute/core/Coordinates.h"
28 #include "arm_compute/core/TensorShape.h"
29 #include "arm_compute/core/Types.h"
38 /** Decrease @p required in steps of @p step until it's less than @p available.
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.
44 * @return Largest value smaller than @p available that is a multiple of @p step
47 inline int adjust_down(int required, int available, int step)
49 ARM_COMPUTE_ERROR_ON(step <= 0);
51 return required - step * ((required - available + step - 1) / step);
54 /** Increase @p required in steps of @p step until it's greater than @p available.
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.
60 * @return Largest value smaller than @p available that is a multiple of @p step
63 inline int adjust_up(int required, int available, int step)
65 ARM_COMPUTE_ERROR_ON(step <= 0);
67 return required + step * ((available - required + step - 1) / step);
70 /** Interface describing methods to update access window and padding based on kernel parameters. */
74 virtual ~IAccessWindow() = default;
75 /** Shrink the window if padding is not large enough.
77 * @param[in] window Window used by the kernel.
79 * @return True if the window has been changed.
81 virtual bool update_window_if_needed(Window &window) const = 0;
82 /** Increase the padding to be large enough for the window.
84 * @param[in] window Window used by the kernel.
86 * @return True if the padding has been changed.
88 virtual bool update_padding_if_needed(const Window &window) const = 0;
89 /** Set the valid region based on access pattern, valid region of the inputs and border mode.
91 * @param[in] window Execution window of the kernel.
92 * @param[in] input_valid_region Combined valid region of all inputs.
93 * @param[in] border_undefined Undefined borders are excluded from the valid region.
94 * @param[in] border_size Size of the border around the XY-plane of the tensor.
96 virtual void set_valid_region(const Window &window, ValidRegion input_valid_region, bool border_undefined, BorderSize border_size) = 0;
99 /** Implementation of a rectangular access pattern. */
100 class AccessWindowRectangle : public IAccessWindow
103 /** Constructor for a rectangular access pattern.
105 * @note Width and height have to be non-negative.
107 * @param[in,out] info Tensor info of the accessed kernel.
108 * @param[in] x Offset of the access in X direction.
109 * @param[in] y Offset of the access in Y direction.
110 * @param[in] width Number of elements that are accessed in X direction.
111 * @param[in] height Number of elements that are accessed in Y direction.
113 AccessWindowRectangle(TensorInfo *info, int x, int y, int width, int height)
114 : AccessWindowRectangle(info, x, y, width, height, 1.f, 1.f)
118 /** Constructor for a rectangular access pattern.
120 * @note Width, height and scale have to be non-negative.
122 * @param[in,out] info Tensor info of the accessed kernel.
123 * @param[in] x Offset of the access in X direction.
124 * @param[in] y Offset of the access in Y direction.
125 * @param[in] width Number of elements that are accessed in X direction.
126 * @param[in] height Number of elements that are accessed in Y direction.
127 * @param[in] scale_x Ratio along the X direction between the window used by the execute_window_loop and the rectangular access pattern defined
128 * @param[in] scale_y Ratio along the Y direction between the window used by the execute_window_loop and the rectangular access pattern defined
130 AccessWindowRectangle(TensorInfo *info, int x, int y, int width, int height, float scale_x, float scale_y)
131 : _info(info), _x(x), _y(y), _width(width), _height(height), _scale_x(scale_x), _scale_y(scale_y)
133 ARM_COMPUTE_ERROR_ON(width < 0);
134 ARM_COMPUTE_ERROR_ON(height < 0);
135 ARM_COMPUTE_ERROR_ON(scale_x < 0);
136 ARM_COMPUTE_ERROR_ON(scale_y < 0);
139 AccessWindowRectangle(const AccessWindowRectangle &) = delete;
140 AccessWindowRectangle &operator=(const AccessWindowRectangle &) = delete;
141 AccessWindowRectangle(AccessWindowRectangle &&) = default;
142 AccessWindowRectangle &operator=(AccessWindowRectangle &&) = default;
143 ~AccessWindowRectangle() = default;
145 /** Set the valid region based on access pattern and valid region of the inputs.
147 * @note This method assumes that there is no border.
148 * @note This method assumes that all elements written by the kernel are valid.
150 * @param[in] window Execution window of the kernel.
151 * @param[in] input_valid_region Combined valid region of all inputs.
153 void set_valid_region(const Window &window, ValidRegion input_valid_region);
155 // Inherited methods overridden:
157 /** @note This method assumes that all elements written by the kernel are valid. */
158 void set_valid_region(const Window &window, ValidRegion input_valid_region, bool border_undefined, BorderSize border_size) override;
160 bool update_window_if_needed(Window &window) const override;
161 bool update_padding_if_needed(const Window &window) const override;
173 /** Implementation of a column access pattern. */
174 class AccessWindowVertical : public AccessWindowRectangle
177 /** Constructor for a column access pattern.
179 * @note Height has to be non-negative.
181 * @param[in,out] info Tensor info of the accessed kernel.
182 * @param[in] y Offset of the access in Y direction.
183 * @param[in] height Number of elements that are accessed in Y direction.
184 * @param[in] scale_y Ratio along the Y direction between the window used by the execute_window_loop and the rectangular access pattern defined
186 AccessWindowVertical(TensorInfo *info, int y, int height, float scale_y = 1.f)
187 : AccessWindowRectangle(info, 0, y, 1, height, 1.f, scale_y)
189 ARM_COMPUTE_ERROR_ON(height < 0);
190 ARM_COMPUTE_ERROR_ON(scale_y < 0);
194 /** Implementation of a row access pattern. */
195 class AccessWindowHorizontal : public AccessWindowRectangle
198 /** Constructor for a row access pattern.
200 * @note Width has to be non-negative.
202 * @param[in,out] info Tensor info of the accessed kernel.
203 * @param[in] x Offset of the access in X direction.
204 * @param[in] width Number of elements that are accessed in X direction.
205 * @param[in] scale_x Ratio along the X direction between the window used by the execute_window_loop and the rectangular access pattern defined
207 AccessWindowHorizontal(TensorInfo *info, int x, int width, float scale_x = 1.f)
208 : AccessWindowRectangle(info, x, 0, width, 1, scale_x, 1.f)
210 ARM_COMPUTE_ERROR_ON(width < 0);
211 ARM_COMPUTE_ERROR_ON(scale_x < 0);
214 } // namespace arm_compute
215 #endif /*__ARM_COMPUTE_IACCESS_WINDOW_H__*/