blob: 615c5188a1c24ff0970e0d551eeeed17128ba6c7 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Michalis Spyrou5237e012018-01-17 09:40:27 +00002 * Copyright (c) 2016-2018 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 */
24#ifndef ARM_COMPUTE_HELPER_H
25#define ARM_COMPUTE_HELPER_H
26
Matthew Bentham6f31f8c2017-10-27 11:50:06 +010027#if defined(ARM_COMPUTE_OPENCL_FP16_ENABLED)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010028#pragma OPENCL EXTENSION cl_khr_fp16 : enable
Matthew Bentham6f31f8c2017-10-27 11:50:06 +010029#endif // defined(ARM_COMPUTE_OPENCL_FP16_ENABLED)
30
steniu01f01f9de2017-09-27 17:00:11 +010031#if defined(ARM_COMPUTE_DEBUG_ENABLED)
Vidhya Sudhan Loganathaneb8a3992018-04-10 12:23:22 +010032#if defined(cl_arm_printf)
steniu01f01f9de2017-09-27 17:00:11 +010033#pragma OPENCL EXTENSION cl_arm_printf : enable
Vidhya Sudhan Loganathaneb8a3992018-04-10 12:23:22 +010034#endif // defined(cl_arm_printf)
steniu01f01f9de2017-09-27 17:00:11 +010035#endif // defined(ARM_COMPUTE_DEBUG_ENABLED)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010036
Georgios Pinitase5f8fd62017-06-23 18:03:44 +010037#define EXPAND(x) x
38
Anthony Barbier6ff3b192017-09-04 18:44:23 +010039#define CLAMP(x, min_val, max_val) min(max(x, min_val), max_val)
40
Georgios Pinitasac4e8732017-07-05 17:02:25 +010041#define VLOAD_STR(size) vload##size
42#define VLOAD(size) VLOAD_STR(size)
43
44#define VSTORE_STR(size) vstore##size
45#define VSTORE(size) VSTORE_STR(size)
46
Anthony Barbier6ff3b192017-09-04 18:44:23 +010047#define VEC_DATA_TYPE_STR(type, size) type##size
48#define VEC_DATA_TYPE(type, size) VEC_DATA_TYPE_STR(type, size)
49
Chunosovd6afedc2017-11-06 22:09:45 +070050#define CL_VEC_DATA_TYPE_STR(type, size) type##size
51#define CL_VEC_DATA_TYPE(type, size) CL_VEC_DATA_TYPE_STR(type, size)
52
Anthony Barbier6ff3b192017-09-04 18:44:23 +010053#define CONVERT_STR(x, type) (convert_##type((x)))
54#define CONVERT(x, type) CONVERT_STR(x, type)
55
56#define CONVERT_SAT_STR(x, type) (convert_##type##_sat((x)))
57#define CONVERT_SAT(x, type) CONVERT_SAT_STR(x, type)
58
59#define CONVERT_SAT_ROUND_STR(x, type, round) (convert_##type##_sat_##round((x)))
60#define CONVERT_SAT_ROUND(x, type, round) CONVERT_SAT_ROUND_STR(x, type, round)
61
62#define VECTOR_DECLARATION(name) \
63 __global uchar *name##_ptr, \
64 uint name##_stride_x, \
65 uint name##_step_x, \
66 uint name##_offset_first_element_in_bytes
67
68#define IMAGE_DECLARATION(name) \
69 __global uchar *name##_ptr, \
70 uint name##_stride_x, \
71 uint name##_step_x, \
72 uint name##_stride_y, \
73 uint name##_step_y, \
74 uint name##_offset_first_element_in_bytes
75
76#define TENSOR3D_DECLARATION(name) \
77 __global uchar *name##_ptr, \
78 uint name##_stride_x, \
79 uint name##_step_x, \
80 uint name##_stride_y, \
81 uint name##_step_y, \
82 uint name##_stride_z, \
83 uint name##_step_z, \
84 uint name##_offset_first_element_in_bytes
85
steniu01868e5412017-07-17 23:16:00 +010086#define TENSOR4D_DECLARATION(name) \
87 __global uchar *name##_ptr, \
88 uint name##_stride_x, \
89 uint name##_step_x, \
90 uint name##_stride_y, \
91 uint name##_step_y, \
92 uint name##_stride_z, \
93 uint name##_step_z, \
94 uint name##_stride_w, \
95 uint name##_step_w, \
96 uint name##_offset_first_element_in_bytes
97
Anthony Barbier6ff3b192017-09-04 18:44:23 +010098#define CONVERT_TO_VECTOR_STRUCT(name) \
99 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x)
100
101#define CONVERT_TO_VECTOR_STRUCT_NO_STEP(name) \
102 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0)
103
104#define CONVERT_TO_IMAGE_STRUCT(name) \
105 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y)
106
107#define CONVERT_TO_IMAGE_STRUCT_NO_STEP(name) \
108 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0)
109
steniu01868e5412017-07-17 23:16:00 +0100110#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
111 update_image_from_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, name##_stride_z, name##_step_z)
112
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100113#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT_NO_STEP(name) \
114 update_image_from_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0, name##_stride_z, name##_step_z)
115
steniu010d523cc2017-07-13 14:24:23 +0100116#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
117 update_image_from_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, name##_stride_z, name##_step_z)
118
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100119#define CONVERT_TO_TENSOR3D_STRUCT(name) \
120 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, \
121 name##_stride_z, name##_step_z)
122
123#define CONVERT_TO_TENSOR3D_STRUCT_NO_STEP(name) \
124 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0, name##_stride_z, 0)
125
steniu01868e5412017-07-17 23:16:00 +0100126#define CONVERT_TO_TENSOR4D_STRUCT(name, mod_size) \
127 update_tensor4D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, \
Michalis Spyrou5237e012018-01-17 09:40:27 +0000128 name##_stride_z, name##_step_z, name##_stride_w, name##_step_w, mod_size)
steniu01868e5412017-07-17 23:16:00 +0100129
130#define CONVERT_TO_TENSOR4D_STRUCT_NO_STEP(name, mod_size) \
131 update_tensor4D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0, name##_stride_z, 0, name##_stride_w, 0, mod_size)
132
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100133/** Structure to hold Vector information */
134typedef struct Vector
135{
136 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
137 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
138 int stride_x; /**< Stride of the image in X dimension (in bytes) */
139} Vector;
140
141/** Structure to hold Image information */
142typedef struct Image
143{
144 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
145 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
146 int stride_x; /**< Stride of the image in X dimension (in bytes) */
147 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
148} Image;
149
150/** Structure to hold 3D tensor information */
151typedef struct Tensor3D
152{
153 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
154 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
155 int stride_x; /**< Stride of the image in X dimension (in bytes) */
156 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
157 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
158} Tensor3D;
159
steniu01868e5412017-07-17 23:16:00 +0100160/** Structure to hold 4D tensor information */
161typedef struct Tensor4D
162{
163 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
164 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
165 int stride_x; /**< Stride of the image in X dimension (in bytes) */
166 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
167 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
168 int stride_w; /**< Stride of the image in W dimension (in bytes) */
169} Tensor4D;
170
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100171/** Wrap vector information into an Vector structure, and make the pointer point at this workitem's data.
172 *
173 * @param[in] ptr Pointer to the starting postion of the buffer
174 * @param[in] offset_first_element_in_bytes The offset of the first element in the source vector
175 * @param[in] stride_x Stride of the vector in X dimension (in bytes)
176 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
177 *
178 * @return An image object
179 */
180Vector inline update_vector_workitem_ptr(__global uchar *ptr, uint offset_first_element_in_bytes, uint stride_x, uint step_x)
181{
182 Vector vector =
183 {
184 .ptr = ptr,
185 .offset_first_element_in_bytes = offset_first_element_in_bytes,
186 .stride_x = stride_x,
187 };
188 vector.ptr += vector.offset_first_element_in_bytes + get_global_id(0) * step_x;
189 return vector;
190}
191
192/** Wrap image information into an Image structure, and make the pointer point at this workitem's data.
193 *
194 * @param[in] ptr Pointer to the starting postion of the buffer
195 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
196 * @param[in] stride_x Stride of the image in X dimension (in bytes)
197 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
198 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
199 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
200 *
201 * @return An image object
202 */
203Image inline update_image_workitem_ptr(__global uchar *ptr, uint offset_first_element_in_bytes, uint stride_x, uint step_x, uint stride_y, uint step_y)
204{
205 Image img =
206 {
207 .ptr = ptr,
208 .offset_first_element_in_bytes = offset_first_element_in_bytes,
209 .stride_x = stride_x,
210 .stride_y = stride_y
211 };
212 img.ptr += img.offset_first_element_in_bytes + get_global_id(0) * step_x + get_global_id(1) * step_y;
213 return img;
214}
215
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100216/** Wrap 3D tensor information into an image structure, and make the pointer point at this workitem's data.
217 *
218 * @param[in] ptr Pointer to the starting postion of the buffer
219 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
220 * @param[in] stride_x Stride of the image in X dimension (in bytes)
221 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
222 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
223 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
224 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
225 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
226 *
227 * @return A 3D tensor object
228 */
229Image inline update_image_from_tensor3D_workitem_ptr(__global uchar *ptr, uint offset_first_element_in_bytes, uint stride_x, uint step_x, uint stride_y, uint step_y, uint stride_z, uint step_z)
230{
231 Image img =
232 {
233 .ptr = ptr,
234 .offset_first_element_in_bytes = offset_first_element_in_bytes,
235 .stride_x = stride_x,
236 .stride_y = stride_y
237 };
238 img.ptr += img.offset_first_element_in_bytes + get_global_id(0) * step_x + get_global_id(1) * step_y + get_global_id(2) * step_z;
239 return img;
240}
241
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100242/** Wrap 3D tensor information into an tensor structure, and make the pointer point at this workitem's data.
243 *
244 * @param[in] ptr Pointer to the starting postion of the buffer
245 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
246 * @param[in] stride_x Stride of the image in X dimension (in bytes)
247 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
248 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
249 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
250 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
251 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
252 *
253 * @return A 3D tensor object
254 */
255Tensor3D inline update_tensor3D_workitem_ptr(__global uchar *ptr, uint offset_first_element_in_bytes, uint stride_x, uint step_x, uint stride_y, uint step_y, uint stride_z, uint step_z)
256{
257 Tensor3D tensor =
258 {
259 .ptr = ptr,
260 .offset_first_element_in_bytes = offset_first_element_in_bytes,
261 .stride_x = stride_x,
262 .stride_y = stride_y,
263 .stride_z = stride_z
264 };
265 tensor.ptr += tensor.offset_first_element_in_bytes + get_global_id(0) * step_x + get_global_id(1) * step_y + get_global_id(2) * step_z;
266 return tensor;
267}
268
steniu01868e5412017-07-17 23:16:00 +0100269Tensor4D inline update_tensor4D_workitem_ptr(__global uchar *ptr, uint offset_first_element_in_bytes, uint stride_x, uint step_x, uint stride_y, uint step_y, uint stride_z, uint step_z, uint stride_w,
270 uint step_w,
271 uint mod_size)
272{
273 Tensor4D tensor =
274 {
275 .ptr = ptr,
276 .offset_first_element_in_bytes = offset_first_element_in_bytes,
277 .stride_x = stride_x,
278 .stride_y = stride_y,
279 .stride_z = stride_z,
280 .stride_w = stride_w
281 };
282
283 tensor.ptr += tensor.offset_first_element_in_bytes + get_global_id(0) * step_x + get_global_id(1) * step_y + (get_global_id(2) % mod_size) * step_z + (get_global_id(2) / mod_size) * step_w;
284 return tensor;
285}
286
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100287/** Get the pointer position of a Vector
288 *
289 * @param[in] vec Pointer to the starting position of the buffer
290 * @param[in] x Relative X position
291 */
292__global inline const uchar *vector_offset(const Vector *vec, int x)
293{
294 return vec->ptr + x * vec->stride_x;
295}
296
297/** Get the pointer position of a Image
298 *
299 * @param[in] img Pointer to the starting position of the buffer
300 * @param[in] x Relative X position
301 * @param[in] y Relative Y position
302 */
303__global inline uchar *offset(const Image *img, int x, int y)
304{
305 return img->ptr + x * img->stride_x + y * img->stride_y;
306}
307
308/** Get the pointer position of a Tensor3D
309 *
Gian Marco Iodice3a623242017-07-25 10:25:53 +0100310 * @param[in] tensor Pointer to the starting position of the buffer
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100311 * @param[in] x Relative X position
312 * @param[in] y Relative Y position
313 * @param[in] z Relative Z position
314 */
315__global inline const uchar *tensor3D_offset(const Tensor3D *tensor, int x, int y, int z)
316{
317 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z;
318}
319
steniu01868e5412017-07-17 23:16:00 +0100320/** Get the pointer position of a Tensor4D
321 *
322 * @param[in] tensor Pointer to the starting position of the buffer
323 * @param[in] x Relative X position
324 * @param[in] y Relative Y position
325 * @param[in] z Relative Z position
326 * @param[in] w Relative W position
327 */
328__global inline const uchar *tensor4D_offset(const Tensor4D *tensor, int x, int y, int z, int w)
329{
330 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z + w * tensor->stride_w;
331}
332
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100333#endif // _HELPER_H