blob: 7ee97d9bbcb2dbb77eb6ebd819ce09032b8b5cb0 [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
Anthony Barbier6ff3b192017-09-04 18:44:23 +010053#define VEC_DATA_TYPE_STR(type, size) type##size
54#define VEC_DATA_TYPE(type, size) VEC_DATA_TYPE_STR(type, size)
55
Chunosovd6afedc2017-11-06 22:09:45 +070056#define CL_VEC_DATA_TYPE_STR(type, size) type##size
57#define CL_VEC_DATA_TYPE(type, size) CL_VEC_DATA_TYPE_STR(type, size)
58
Anthony Barbier6ff3b192017-09-04 18:44:23 +010059#define CONVERT_STR(x, type) (convert_##type((x)))
60#define CONVERT(x, type) CONVERT_STR(x, type)
61
62#define CONVERT_SAT_STR(x, type) (convert_##type##_sat((x)))
63#define CONVERT_SAT(x, type) CONVERT_SAT_STR(x, type)
64
65#define CONVERT_SAT_ROUND_STR(x, type, round) (convert_##type##_sat_##round((x)))
66#define CONVERT_SAT_ROUND(x, type, round) CONVERT_SAT_ROUND_STR(x, type, round)
67
68#define VECTOR_DECLARATION(name) \
69 __global uchar *name##_ptr, \
70 uint name##_stride_x, \
71 uint name##_step_x, \
72 uint name##_offset_first_element_in_bytes
73
74#define IMAGE_DECLARATION(name) \
75 __global uchar *name##_ptr, \
76 uint name##_stride_x, \
77 uint name##_step_x, \
78 uint name##_stride_y, \
79 uint name##_step_y, \
80 uint name##_offset_first_element_in_bytes
81
82#define TENSOR3D_DECLARATION(name) \
83 __global uchar *name##_ptr, \
84 uint name##_stride_x, \
85 uint name##_step_x, \
86 uint name##_stride_y, \
87 uint name##_step_y, \
88 uint name##_stride_z, \
89 uint name##_step_z, \
90 uint name##_offset_first_element_in_bytes
91
steniu01868e5412017-07-17 23:16:00 +010092#define TENSOR4D_DECLARATION(name) \
93 __global uchar *name##_ptr, \
94 uint name##_stride_x, \
95 uint name##_step_x, \
96 uint name##_stride_y, \
97 uint name##_step_y, \
98 uint name##_stride_z, \
99 uint name##_step_z, \
100 uint name##_stride_w, \
101 uint name##_step_w, \
102 uint name##_offset_first_element_in_bytes
103
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100104#define CONVERT_TO_VECTOR_STRUCT(name) \
105 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x)
106
107#define CONVERT_TO_VECTOR_STRUCT_NO_STEP(name) \
108 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0)
109
110#define CONVERT_TO_IMAGE_STRUCT(name) \
111 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y)
112
113#define CONVERT_TO_IMAGE_STRUCT_NO_STEP(name) \
114 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0)
115
steniu01868e5412017-07-17 23:16:00 +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 Barbier7ff47a32017-07-11 16:54:04 +0100119#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT_NO_STEP(name) \
120 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)
121
steniu010d523cc2017-07-13 14:24:23 +0100122#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
123 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)
124
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100125#define CONVERT_TO_TENSOR3D_STRUCT(name) \
126 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, \
127 name##_stride_z, name##_step_z)
128
129#define CONVERT_TO_TENSOR3D_STRUCT_NO_STEP(name) \
130 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0, name##_stride_z, 0)
131
steniu01868e5412017-07-17 23:16:00 +0100132#define CONVERT_TO_TENSOR4D_STRUCT(name, mod_size) \
133 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 +0000134 name##_stride_z, name##_step_z, name##_stride_w, name##_step_w, mod_size)
steniu01868e5412017-07-17 23:16:00 +0100135
136#define CONVERT_TO_TENSOR4D_STRUCT_NO_STEP(name, mod_size) \
137 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)
138
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100139/** Structure to hold Vector information */
140typedef struct Vector
141{
142 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
143 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
144 int stride_x; /**< Stride of the image in X dimension (in bytes) */
145} Vector;
146
147/** Structure to hold Image information */
148typedef struct Image
149{
150 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
151 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
152 int stride_x; /**< Stride of the image in X dimension (in bytes) */
153 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
154} Image;
155
156/** Structure to hold 3D tensor information */
157typedef struct Tensor3D
158{
159 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
160 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
161 int stride_x; /**< Stride of the image in X dimension (in bytes) */
162 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
163 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
164} Tensor3D;
165
steniu01868e5412017-07-17 23:16:00 +0100166/** Structure to hold 4D tensor information */
167typedef struct Tensor4D
168{
169 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
170 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
171 int stride_x; /**< Stride of the image in X dimension (in bytes) */
172 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
173 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
174 int stride_w; /**< Stride of the image in W dimension (in bytes) */
175} Tensor4D;
176
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100177/** Wrap vector information into an Vector structure, and make the pointer point at this workitem's data.
178 *
179 * @param[in] ptr Pointer to the starting postion of the buffer
180 * @param[in] offset_first_element_in_bytes The offset of the first element in the source vector
181 * @param[in] stride_x Stride of the vector in X dimension (in bytes)
182 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
183 *
184 * @return An image object
185 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100186inline 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 +0100187{
188 Vector vector =
189 {
190 .ptr = ptr,
191 .offset_first_element_in_bytes = offset_first_element_in_bytes,
192 .stride_x = stride_x,
193 };
194 vector.ptr += vector.offset_first_element_in_bytes + get_global_id(0) * step_x;
195 return vector;
196}
197
198/** Wrap image information into an Image structure, and make the pointer point at this workitem's data.
199 *
200 * @param[in] ptr Pointer to the starting postion of the buffer
201 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
202 * @param[in] stride_x Stride of the image in X dimension (in bytes)
203 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
204 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
205 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
206 *
207 * @return An image object
208 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100209inline 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 +0100210{
211 Image img =
212 {
213 .ptr = ptr,
214 .offset_first_element_in_bytes = offset_first_element_in_bytes,
215 .stride_x = stride_x,
216 .stride_y = stride_y
217 };
218 img.ptr += img.offset_first_element_in_bytes + get_global_id(0) * step_x + get_global_id(1) * step_y;
219 return img;
220}
221
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100222/** Wrap 3D tensor information into an image structure, and make the pointer point at this workitem's data.
223 *
224 * @param[in] ptr Pointer to the starting postion of the buffer
225 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
226 * @param[in] stride_x Stride of the image in X dimension (in bytes)
227 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
228 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
229 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
230 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
231 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
232 *
233 * @return A 3D tensor object
234 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100235inline 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 +0100236{
237 Image img =
238 {
239 .ptr = ptr,
240 .offset_first_element_in_bytes = offset_first_element_in_bytes,
241 .stride_x = stride_x,
242 .stride_y = stride_y
243 };
244 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;
245 return img;
246}
247
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100248/** Wrap 3D tensor information into an tensor structure, and make the pointer point at this workitem's data.
249 *
250 * @param[in] ptr Pointer to the starting postion of the buffer
251 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
252 * @param[in] stride_x Stride of the image in X dimension (in bytes)
253 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
254 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
255 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
256 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
257 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
258 *
259 * @return A 3D tensor object
260 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100261inline 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 +0100262{
263 Tensor3D tensor =
264 {
265 .ptr = ptr,
266 .offset_first_element_in_bytes = offset_first_element_in_bytes,
267 .stride_x = stride_x,
268 .stride_y = stride_y,
269 .stride_z = stride_z
270 };
271 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;
272 return tensor;
273}
274
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100275inline 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 +0100276 uint step_w,
277 uint mod_size)
278{
279 Tensor4D tensor =
280 {
281 .ptr = ptr,
282 .offset_first_element_in_bytes = offset_first_element_in_bytes,
283 .stride_x = stride_x,
284 .stride_y = stride_y,
285 .stride_z = stride_z,
286 .stride_w = stride_w
287 };
288
289 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;
290 return tensor;
291}
292
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100293/** Get the pointer position of a Vector
294 *
295 * @param[in] vec Pointer to the starting position of the buffer
296 * @param[in] x Relative X position
297 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100298inline __global const uchar *vector_offset(const Vector *vec, int x)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100299{
300 return vec->ptr + x * vec->stride_x;
301}
302
303/** Get the pointer position of a Image
304 *
305 * @param[in] img Pointer to the starting position of the buffer
306 * @param[in] x Relative X position
307 * @param[in] y Relative Y position
308 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100309inline __global uchar *offset(const Image *img, int x, int y)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100310{
311 return img->ptr + x * img->stride_x + y * img->stride_y;
312}
313
314/** Get the pointer position of a Tensor3D
315 *
Gian Marco Iodice3a623242017-07-25 10:25:53 +0100316 * @param[in] tensor Pointer to the starting position of the buffer
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100317 * @param[in] x Relative X position
318 * @param[in] y Relative Y position
319 * @param[in] z Relative Z position
320 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100321inline __global const uchar *tensor3D_offset(const Tensor3D *tensor, int x, int y, int z)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100322{
323 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z;
324}
325
steniu01868e5412017-07-17 23:16:00 +0100326/** Get the pointer position of a Tensor4D
327 *
328 * @param[in] tensor Pointer to the starting position of the buffer
329 * @param[in] x Relative X position
330 * @param[in] y Relative Y position
331 * @param[in] z Relative Z position
332 * @param[in] w Relative W position
333 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100334inline __global const uchar *tensor4D_offset(const Tensor4D *tensor, int x, int y, int z, int w)
steniu01868e5412017-07-17 23:16:00 +0100335{
336 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z + w * tensor->stride_w;
337}
338
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100339#endif // _HELPER_H