blob: 180bd50528c0f015b9fd436d50fba863c580626b [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
Georgios Pinitasdaa38552018-08-28 17:43:18 +010027#if defined(ARM_COMPUTE_OPENCL_FP16_ENABLED) && defined(cl_khr_fp16)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010028#pragma OPENCL EXTENSION cl_khr_fp16 : enable
Georgios Pinitasdaa38552018-08-28 17:43:18 +010029#endif // defined(ARM_COMPUTE_OPENCL_FP16_ENABLED) && defined(cl_khr_fp16)
Matthew Bentham6f31f8c2017-10-27 11:50:06 +010030
Georgios Pinitasdaa38552018-08-28 17:43:18 +010031#if defined(ARM_COMPUTE_OPENCL_DOT8_ENABLED) && defined(cl_arm_integer_dot_product_int8)
Michalis Spyroue03342e2018-01-15 14:39:13 +000032#pragma OPENCL EXTENSION cl_arm_integer_dot_product_int8 : enable
Georgios Pinitasdaa38552018-08-28 17:43:18 +010033#endif // defined(ARM_COMPUTE_OPENCL_DOT8_ENABLED) && defined(cl_arm_integer_dot_product_int8)
Michalis Spyroue03342e2018-01-15 14:39:13 +000034
Georgios Pinitasdaa38552018-08-28 17:43:18 +010035#if defined(ARM_COMPUTE_OPENCL_DOT8_ACC_ENABLED) && defined(cl_arm_integer_dot_product_accumulate_int8)
Giorgio Arenaeff8d952018-07-02 15:29:57 +010036#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int8 : enable
Georgios Pinitasdaa38552018-08-28 17:43:18 +010037#endif // defined(ARM_COMPUTE_OPENCL_DOT8_ACC_ENABLED) && defined(cl_arm_integer_dot_product_accumulate_int8)
Giorgio Arenaeff8d952018-07-02 15:29:57 +010038
Georgios Pinitasdaa38552018-08-28 17:43:18 +010039#if defined(ARM_COMPUTE_DEBUG_ENABLED) && defined(cl_arm_printf)
steniu01f01f9de2017-09-27 17:00:11 +010040#pragma OPENCL EXTENSION cl_arm_printf : enable
Georgios Pinitas238c97c2018-08-31 17:28:29 +010041#endif // defined(ARM_COMPUTE_DEBUG_ENABLED) && defined(cl_arm_printf)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010042
Georgios Pinitase5f8fd62017-06-23 18:03:44 +010043#define EXPAND(x) x
44
Anthony Barbier6ff3b192017-09-04 18:44:23 +010045#define CLAMP(x, min_val, max_val) min(max(x, min_val), max_val)
46
Georgios Pinitasac4e8732017-07-05 17:02:25 +010047#define VLOAD_STR(size) vload##size
48#define VLOAD(size) VLOAD_STR(size)
49
50#define VSTORE_STR(size) vstore##size
51#define VSTORE(size) VSTORE_STR(size)
52
Manuel Bottini0d0028c2018-10-02 16:41:52 +010053#define float1 float
54#define half1 half
55
Anthony Barbier6ff3b192017-09-04 18:44:23 +010056#define VEC_DATA_TYPE_STR(type, size) type##size
57#define VEC_DATA_TYPE(type, size) VEC_DATA_TYPE_STR(type, size)
58
Chunosovd6afedc2017-11-06 22:09:45 +070059#define CL_VEC_DATA_TYPE_STR(type, size) type##size
60#define CL_VEC_DATA_TYPE(type, size) CL_VEC_DATA_TYPE_STR(type, size)
61
Anthony Barbier6ff3b192017-09-04 18:44:23 +010062#define CONVERT_STR(x, type) (convert_##type((x)))
63#define CONVERT(x, type) CONVERT_STR(x, type)
64
65#define CONVERT_SAT_STR(x, type) (convert_##type##_sat((x)))
66#define CONVERT_SAT(x, type) CONVERT_SAT_STR(x, type)
67
68#define CONVERT_SAT_ROUND_STR(x, type, round) (convert_##type##_sat_##round((x)))
69#define CONVERT_SAT_ROUND(x, type, round) CONVERT_SAT_ROUND_STR(x, type, round)
70
71#define VECTOR_DECLARATION(name) \
72 __global uchar *name##_ptr, \
73 uint name##_stride_x, \
74 uint name##_step_x, \
75 uint name##_offset_first_element_in_bytes
76
77#define IMAGE_DECLARATION(name) \
78 __global uchar *name##_ptr, \
79 uint name##_stride_x, \
80 uint name##_step_x, \
81 uint name##_stride_y, \
82 uint name##_step_y, \
83 uint name##_offset_first_element_in_bytes
84
85#define TENSOR3D_DECLARATION(name) \
86 __global uchar *name##_ptr, \
87 uint name##_stride_x, \
88 uint name##_step_x, \
89 uint name##_stride_y, \
90 uint name##_step_y, \
91 uint name##_stride_z, \
92 uint name##_step_z, \
93 uint name##_offset_first_element_in_bytes
94
steniu01868e5412017-07-17 23:16:00 +010095#define TENSOR4D_DECLARATION(name) \
96 __global uchar *name##_ptr, \
97 uint name##_stride_x, \
98 uint name##_step_x, \
99 uint name##_stride_y, \
100 uint name##_step_y, \
101 uint name##_stride_z, \
102 uint name##_step_z, \
103 uint name##_stride_w, \
104 uint name##_step_w, \
105 uint name##_offset_first_element_in_bytes
106
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100107#define CONVERT_TO_VECTOR_STRUCT(name) \
108 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x)
109
110#define CONVERT_TO_VECTOR_STRUCT_NO_STEP(name) \
111 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0)
112
113#define CONVERT_TO_IMAGE_STRUCT(name) \
114 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y)
115
116#define CONVERT_TO_IMAGE_STRUCT_NO_STEP(name) \
117 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0)
118
steniu01868e5412017-07-17 23:16:00 +0100119#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
120 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)
121
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100122#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT_NO_STEP(name) \
123 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)
124
steniu010d523cc2017-07-13 14:24:23 +0100125#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
126 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)
127
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100128#define CONVERT_TO_TENSOR3D_STRUCT(name) \
129 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, \
130 name##_stride_z, name##_step_z)
131
132#define CONVERT_TO_TENSOR3D_STRUCT_NO_STEP(name) \
133 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0, name##_stride_z, 0)
134
steniu01868e5412017-07-17 23:16:00 +0100135#define CONVERT_TO_TENSOR4D_STRUCT(name, mod_size) \
136 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 +0000137 name##_stride_z, name##_step_z, name##_stride_w, name##_step_w, mod_size)
steniu01868e5412017-07-17 23:16:00 +0100138
139#define CONVERT_TO_TENSOR4D_STRUCT_NO_STEP(name, mod_size) \
140 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)
141
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100142/** Structure to hold Vector information */
143typedef struct Vector
144{
145 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
146 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
147 int stride_x; /**< Stride of the image in X dimension (in bytes) */
148} Vector;
149
150/** Structure to hold Image information */
151typedef struct Image
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} Image;
158
159/** Structure to hold 3D tensor information */
160typedef struct Tensor3D
161{
162 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
163 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
164 int stride_x; /**< Stride of the image in X dimension (in bytes) */
165 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
166 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
167} Tensor3D;
168
steniu01868e5412017-07-17 23:16:00 +0100169/** Structure to hold 4D tensor information */
170typedef struct Tensor4D
171{
172 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
173 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
174 int stride_x; /**< Stride of the image in X dimension (in bytes) */
175 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
176 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
177 int stride_w; /**< Stride of the image in W dimension (in bytes) */
178} Tensor4D;
179
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100180/** Wrap vector information into an Vector structure, and make the pointer point at this workitem's data.
181 *
182 * @param[in] ptr Pointer to the starting postion of the buffer
183 * @param[in] offset_first_element_in_bytes The offset of the first element in the source vector
184 * @param[in] stride_x Stride of the vector in X dimension (in bytes)
185 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
186 *
187 * @return An image object
188 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100189inline Vector update_vector_workitem_ptr(__global uchar *ptr, uint offset_first_element_in_bytes, uint stride_x, uint step_x)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100190{
191 Vector vector =
192 {
193 .ptr = ptr,
194 .offset_first_element_in_bytes = offset_first_element_in_bytes,
195 .stride_x = stride_x,
196 };
197 vector.ptr += vector.offset_first_element_in_bytes + get_global_id(0) * step_x;
198 return vector;
199}
200
201/** Wrap image information into an Image structure, and make the pointer point at this workitem's data.
202 *
203 * @param[in] ptr Pointer to the starting postion of the buffer
204 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
205 * @param[in] stride_x Stride of the image in X dimension (in bytes)
206 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
207 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
208 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
209 *
210 * @return An image object
211 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100212inline Image 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)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100213{
214 Image img =
215 {
216 .ptr = ptr,
217 .offset_first_element_in_bytes = offset_first_element_in_bytes,
218 .stride_x = stride_x,
219 .stride_y = stride_y
220 };
221 img.ptr += img.offset_first_element_in_bytes + get_global_id(0) * step_x + get_global_id(1) * step_y;
222 return img;
223}
224
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100225/** Wrap 3D tensor information into an image structure, and make the pointer point at this workitem's data.
226 *
227 * @param[in] ptr Pointer to the starting postion of the buffer
228 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
229 * @param[in] stride_x Stride of the image in X dimension (in bytes)
230 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
231 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
232 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
233 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
234 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
235 *
236 * @return A 3D tensor object
237 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100238inline Image 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)
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100239{
240 Image img =
241 {
242 .ptr = ptr,
243 .offset_first_element_in_bytes = offset_first_element_in_bytes,
244 .stride_x = stride_x,
245 .stride_y = stride_y
246 };
247 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;
248 return img;
249}
250
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100251/** Wrap 3D tensor information into an tensor structure, and make the pointer point at this workitem's data.
252 *
253 * @param[in] ptr Pointer to the starting postion of the buffer
254 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
255 * @param[in] stride_x Stride of the image in X dimension (in bytes)
256 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
257 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
258 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
259 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
260 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
261 *
262 * @return A 3D tensor object
263 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100264inline Tensor3D 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)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100265{
266 Tensor3D tensor =
267 {
268 .ptr = ptr,
269 .offset_first_element_in_bytes = offset_first_element_in_bytes,
270 .stride_x = stride_x,
271 .stride_y = stride_y,
272 .stride_z = stride_z
273 };
274 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;
275 return tensor;
276}
277
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100278inline Tensor4D 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,
steniu01868e5412017-07-17 23:16:00 +0100279 uint step_w,
280 uint mod_size)
281{
282 Tensor4D tensor =
283 {
284 .ptr = ptr,
285 .offset_first_element_in_bytes = offset_first_element_in_bytes,
286 .stride_x = stride_x,
287 .stride_y = stride_y,
288 .stride_z = stride_z,
289 .stride_w = stride_w
290 };
291
292 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;
293 return tensor;
294}
295
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100296/** Get the pointer position of a Vector
297 *
298 * @param[in] vec Pointer to the starting position of the buffer
299 * @param[in] x Relative X position
300 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100301inline __global const uchar *vector_offset(const Vector *vec, int x)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100302{
303 return vec->ptr + x * vec->stride_x;
304}
305
306/** Get the pointer position of a Image
307 *
308 * @param[in] img Pointer to the starting position of the buffer
309 * @param[in] x Relative X position
310 * @param[in] y Relative Y position
311 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100312inline __global uchar *offset(const Image *img, int x, int y)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100313{
314 return img->ptr + x * img->stride_x + y * img->stride_y;
315}
316
317/** Get the pointer position of a Tensor3D
318 *
Gian Marco Iodice3a623242017-07-25 10:25:53 +0100319 * @param[in] tensor Pointer to the starting position of the buffer
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100320 * @param[in] x Relative X position
321 * @param[in] y Relative Y position
322 * @param[in] z Relative Z position
323 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100324inline __global const uchar *tensor3D_offset(const Tensor3D *tensor, int x, int y, int z)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100325{
326 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z;
327}
328
steniu01868e5412017-07-17 23:16:00 +0100329/** Get the pointer position of a Tensor4D
330 *
331 * @param[in] tensor Pointer to the starting position of the buffer
332 * @param[in] x Relative X position
333 * @param[in] y Relative Y position
334 * @param[in] z Relative Z position
335 * @param[in] w Relative W position
336 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100337inline __global const uchar *tensor4D_offset(const Tensor4D *tensor, int x, int y, int z, int w)
steniu01868e5412017-07-17 23:16:00 +0100338{
339 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z + w * tensor->stride_w;
340}
341
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100342#endif // _HELPER_H