blob: 3f7a2a504bcdceb82be71dbcad19320429b78b36 [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
Michalis Spyroue03342e2018-01-15 14:39:13 +000031#if defined(ARM_COMPUTE_OPENCL_DOT8_ENABLED)
32#pragma OPENCL EXTENSION cl_arm_integer_dot_product_int8 : enable
33#endif // defined(ARM_COMPUTE_OPENCL_DOT8_ENABLED)
34
Giorgio Arenaeff8d952018-07-02 15:29:57 +010035#if defined(ARM_COMPUTE_OPENCL_DOT8_ACC_ENABLED)
36#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int8 : enable
37#endif // defined(ARM_COMPUTE_OPENCL_DOT8_ACC_ENABLED)
38
steniu01f01f9de2017-09-27 17:00:11 +010039#if defined(ARM_COMPUTE_DEBUG_ENABLED)
Vidhya Sudhan Loganathaneb8a3992018-04-10 12:23:22 +010040#if defined(cl_arm_printf)
steniu01f01f9de2017-09-27 17:00:11 +010041#pragma OPENCL EXTENSION cl_arm_printf : enable
Vidhya Sudhan Loganathaneb8a3992018-04-10 12:23:22 +010042#endif // defined(cl_arm_printf)
steniu01f01f9de2017-09-27 17:00:11 +010043#endif // defined(ARM_COMPUTE_DEBUG_ENABLED)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010044
Georgios Pinitase5f8fd62017-06-23 18:03:44 +010045#define EXPAND(x) x
46
Anthony Barbier6ff3b192017-09-04 18:44:23 +010047#define CLAMP(x, min_val, max_val) min(max(x, min_val), max_val)
48
Georgios Pinitasac4e8732017-07-05 17:02:25 +010049#define VLOAD_STR(size) vload##size
50#define VLOAD(size) VLOAD_STR(size)
51
52#define VSTORE_STR(size) vstore##size
53#define VSTORE(size) VSTORE_STR(size)
54
Anthony Barbier6ff3b192017-09-04 18:44:23 +010055#define VEC_DATA_TYPE_STR(type, size) type##size
56#define VEC_DATA_TYPE(type, size) VEC_DATA_TYPE_STR(type, size)
57
Chunosovd6afedc2017-11-06 22:09:45 +070058#define CL_VEC_DATA_TYPE_STR(type, size) type##size
59#define CL_VEC_DATA_TYPE(type, size) CL_VEC_DATA_TYPE_STR(type, size)
60
Anthony Barbier6ff3b192017-09-04 18:44:23 +010061#define CONVERT_STR(x, type) (convert_##type((x)))
62#define CONVERT(x, type) CONVERT_STR(x, type)
63
64#define CONVERT_SAT_STR(x, type) (convert_##type##_sat((x)))
65#define CONVERT_SAT(x, type) CONVERT_SAT_STR(x, type)
66
67#define CONVERT_SAT_ROUND_STR(x, type, round) (convert_##type##_sat_##round((x)))
68#define CONVERT_SAT_ROUND(x, type, round) CONVERT_SAT_ROUND_STR(x, type, round)
69
70#define VECTOR_DECLARATION(name) \
71 __global uchar *name##_ptr, \
72 uint name##_stride_x, \
73 uint name##_step_x, \
74 uint name##_offset_first_element_in_bytes
75
76#define IMAGE_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##_offset_first_element_in_bytes
83
84#define TENSOR3D_DECLARATION(name) \
85 __global uchar *name##_ptr, \
86 uint name##_stride_x, \
87 uint name##_step_x, \
88 uint name##_stride_y, \
89 uint name##_step_y, \
90 uint name##_stride_z, \
91 uint name##_step_z, \
92 uint name##_offset_first_element_in_bytes
93
steniu01868e5412017-07-17 23:16:00 +010094#define TENSOR4D_DECLARATION(name) \
95 __global uchar *name##_ptr, \
96 uint name##_stride_x, \
97 uint name##_step_x, \
98 uint name##_stride_y, \
99 uint name##_step_y, \
100 uint name##_stride_z, \
101 uint name##_step_z, \
102 uint name##_stride_w, \
103 uint name##_step_w, \
104 uint name##_offset_first_element_in_bytes
105
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100106#define CONVERT_TO_VECTOR_STRUCT(name) \
107 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x)
108
109#define CONVERT_TO_VECTOR_STRUCT_NO_STEP(name) \
110 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0)
111
112#define CONVERT_TO_IMAGE_STRUCT(name) \
113 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y)
114
115#define CONVERT_TO_IMAGE_STRUCT_NO_STEP(name) \
116 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0)
117
steniu01868e5412017-07-17 23:16:00 +0100118#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
119 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)
120
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100121#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT_NO_STEP(name) \
122 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)
123
steniu010d523cc2017-07-13 14:24:23 +0100124#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
125 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)
126
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100127#define CONVERT_TO_TENSOR3D_STRUCT(name) \
128 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, \
129 name##_stride_z, name##_step_z)
130
131#define CONVERT_TO_TENSOR3D_STRUCT_NO_STEP(name) \
132 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0, name##_stride_z, 0)
133
steniu01868e5412017-07-17 23:16:00 +0100134#define CONVERT_TO_TENSOR4D_STRUCT(name, mod_size) \
135 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 +0000136 name##_stride_z, name##_step_z, name##_stride_w, name##_step_w, mod_size)
steniu01868e5412017-07-17 23:16:00 +0100137
138#define CONVERT_TO_TENSOR4D_STRUCT_NO_STEP(name, mod_size) \
139 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)
140
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100141/** Structure to hold Vector information */
142typedef struct Vector
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} Vector;
148
149/** Structure to hold Image information */
150typedef struct Image
151{
152 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
153 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
154 int stride_x; /**< Stride of the image in X dimension (in bytes) */
155 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
156} Image;
157
158/** Structure to hold 3D tensor information */
159typedef struct Tensor3D
160{
161 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
162 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
163 int stride_x; /**< Stride of the image in X dimension (in bytes) */
164 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
165 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
166} Tensor3D;
167
steniu01868e5412017-07-17 23:16:00 +0100168/** Structure to hold 4D tensor information */
169typedef struct Tensor4D
170{
171 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
172 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
173 int stride_x; /**< Stride of the image in X dimension (in bytes) */
174 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
175 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
176 int stride_w; /**< Stride of the image in W dimension (in bytes) */
177} Tensor4D;
178
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100179/** Wrap vector information into an Vector structure, and make the pointer point at this workitem's data.
180 *
181 * @param[in] ptr Pointer to the starting postion of the buffer
182 * @param[in] offset_first_element_in_bytes The offset of the first element in the source vector
183 * @param[in] stride_x Stride of the vector in X dimension (in bytes)
184 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
185 *
186 * @return An image object
187 */
188Vector inline update_vector_workitem_ptr(__global uchar *ptr, uint offset_first_element_in_bytes, uint stride_x, uint step_x)
189{
190 Vector vector =
191 {
192 .ptr = ptr,
193 .offset_first_element_in_bytes = offset_first_element_in_bytes,
194 .stride_x = stride_x,
195 };
196 vector.ptr += vector.offset_first_element_in_bytes + get_global_id(0) * step_x;
197 return vector;
198}
199
200/** Wrap image information into an Image structure, and make the pointer point at this workitem's data.
201 *
202 * @param[in] ptr Pointer to the starting postion of the buffer
203 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
204 * @param[in] stride_x Stride of the image in X dimension (in bytes)
205 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
206 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
207 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
208 *
209 * @return An image object
210 */
211Image 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)
212{
213 Image img =
214 {
215 .ptr = ptr,
216 .offset_first_element_in_bytes = offset_first_element_in_bytes,
217 .stride_x = stride_x,
218 .stride_y = stride_y
219 };
220 img.ptr += img.offset_first_element_in_bytes + get_global_id(0) * step_x + get_global_id(1) * step_y;
221 return img;
222}
223
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100224/** Wrap 3D tensor information into an image structure, and make the pointer point at this workitem's data.
225 *
226 * @param[in] ptr Pointer to the starting postion of the buffer
227 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
228 * @param[in] stride_x Stride of the image in X dimension (in bytes)
229 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
230 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
231 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
232 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
233 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
234 *
235 * @return A 3D tensor object
236 */
237Image 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)
238{
239 Image img =
240 {
241 .ptr = ptr,
242 .offset_first_element_in_bytes = offset_first_element_in_bytes,
243 .stride_x = stride_x,
244 .stride_y = stride_y
245 };
246 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;
247 return img;
248}
249
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100250/** Wrap 3D tensor information into an tensor structure, and make the pointer point at this workitem's data.
251 *
252 * @param[in] ptr Pointer to the starting postion of the buffer
253 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
254 * @param[in] stride_x Stride of the image in X dimension (in bytes)
255 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
256 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
257 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
258 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
259 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
260 *
261 * @return A 3D tensor object
262 */
263Tensor3D 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)
264{
265 Tensor3D tensor =
266 {
267 .ptr = ptr,
268 .offset_first_element_in_bytes = offset_first_element_in_bytes,
269 .stride_x = stride_x,
270 .stride_y = stride_y,
271 .stride_z = stride_z
272 };
273 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;
274 return tensor;
275}
276
steniu01868e5412017-07-17 23:16:00 +0100277Tensor4D 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,
278 uint step_w,
279 uint mod_size)
280{
281 Tensor4D tensor =
282 {
283 .ptr = ptr,
284 .offset_first_element_in_bytes = offset_first_element_in_bytes,
285 .stride_x = stride_x,
286 .stride_y = stride_y,
287 .stride_z = stride_z,
288 .stride_w = stride_w
289 };
290
291 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;
292 return tensor;
293}
294
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100295/** Get the pointer position of a Vector
296 *
297 * @param[in] vec Pointer to the starting position of the buffer
298 * @param[in] x Relative X position
299 */
300__global inline const uchar *vector_offset(const Vector *vec, int x)
301{
302 return vec->ptr + x * vec->stride_x;
303}
304
305/** Get the pointer position of a Image
306 *
307 * @param[in] img Pointer to the starting position of the buffer
308 * @param[in] x Relative X position
309 * @param[in] y Relative Y position
310 */
311__global inline uchar *offset(const Image *img, int x, int y)
312{
313 return img->ptr + x * img->stride_x + y * img->stride_y;
314}
315
316/** Get the pointer position of a Tensor3D
317 *
Gian Marco Iodice3a623242017-07-25 10:25:53 +0100318 * @param[in] tensor Pointer to the starting position of the buffer
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100319 * @param[in] x Relative X position
320 * @param[in] y Relative Y position
321 * @param[in] z Relative Z position
322 */
323__global inline const uchar *tensor3D_offset(const Tensor3D *tensor, int x, int y, int z)
324{
325 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z;
326}
327
steniu01868e5412017-07-17 23:16:00 +0100328/** Get the pointer position of a Tensor4D
329 *
330 * @param[in] tensor Pointer to the starting position of the buffer
331 * @param[in] x Relative X position
332 * @param[in] y Relative Y position
333 * @param[in] z Relative Z position
334 * @param[in] w Relative W position
335 */
336__global inline const uchar *tensor4D_offset(const Tensor4D *tensor, int x, int y, int z, int w)
337{
338 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z + w * tensor->stride_w;
339}
340
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100341#endif // _HELPER_H