blob: 330d67daa5da6adc927ff2472a735554c462f6a9 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
2 * Copyright (c) 2016, 2017 ARM Limited.
3 *
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)
32#pragma OPENCL EXTENSION cl_arm_printf : enable
33#endif // defined(ARM_COMPUTE_DEBUG_ENABLED)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010034
Georgios Pinitase5f8fd62017-06-23 18:03:44 +010035#define EXPAND(x) x
36
Anthony Barbier6ff3b192017-09-04 18:44:23 +010037#define CLAMP(x, min_val, max_val) min(max(x, min_val), max_val)
38
Georgios Pinitasac4e8732017-07-05 17:02:25 +010039#define VLOAD_STR(size) vload##size
40#define VLOAD(size) VLOAD_STR(size)
41
42#define VSTORE_STR(size) vstore##size
43#define VSTORE(size) VSTORE_STR(size)
44
Anthony Barbier6ff3b192017-09-04 18:44:23 +010045#define VEC_DATA_TYPE_STR(type, size) type##size
46#define VEC_DATA_TYPE(type, size) VEC_DATA_TYPE_STR(type, size)
47
48#define CONVERT_STR(x, type) (convert_##type((x)))
49#define CONVERT(x, type) CONVERT_STR(x, type)
50
51#define CONVERT_SAT_STR(x, type) (convert_##type##_sat((x)))
52#define CONVERT_SAT(x, type) CONVERT_SAT_STR(x, type)
53
54#define CONVERT_SAT_ROUND_STR(x, type, round) (convert_##type##_sat_##round((x)))
55#define CONVERT_SAT_ROUND(x, type, round) CONVERT_SAT_ROUND_STR(x, type, round)
56
57#define VECTOR_DECLARATION(name) \
58 __global uchar *name##_ptr, \
59 uint name##_stride_x, \
60 uint name##_step_x, \
61 uint name##_offset_first_element_in_bytes
62
63#define IMAGE_DECLARATION(name) \
64 __global uchar *name##_ptr, \
65 uint name##_stride_x, \
66 uint name##_step_x, \
67 uint name##_stride_y, \
68 uint name##_step_y, \
69 uint name##_offset_first_element_in_bytes
70
71#define TENSOR3D_DECLARATION(name) \
72 __global uchar *name##_ptr, \
73 uint name##_stride_x, \
74 uint name##_step_x, \
75 uint name##_stride_y, \
76 uint name##_step_y, \
77 uint name##_stride_z, \
78 uint name##_step_z, \
79 uint name##_offset_first_element_in_bytes
80
steniu01868e5412017-07-17 23:16:00 +010081#define TENSOR4D_DECLARATION(name) \
82 __global uchar *name##_ptr, \
83 uint name##_stride_x, \
84 uint name##_step_x, \
85 uint name##_stride_y, \
86 uint name##_step_y, \
87 uint name##_stride_z, \
88 uint name##_step_z, \
89 uint name##_stride_w, \
90 uint name##_step_w, \
91 uint name##_offset_first_element_in_bytes
92
Anthony Barbier6ff3b192017-09-04 18:44:23 +010093#define CONVERT_TO_VECTOR_STRUCT(name) \
94 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x)
95
96#define CONVERT_TO_VECTOR_STRUCT_NO_STEP(name) \
97 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0)
98
99#define CONVERT_TO_IMAGE_STRUCT(name) \
100 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y)
101
102#define CONVERT_TO_IMAGE_STRUCT_NO_STEP(name) \
103 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0)
104
steniu01868e5412017-07-17 23:16:00 +0100105#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
106 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)
107
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100108#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT_NO_STEP(name) \
109 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)
110
steniu010d523cc2017-07-13 14:24:23 +0100111#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
112 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)
113
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100114#define CONVERT_TO_TENSOR3D_STRUCT(name) \
115 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, \
116 name##_stride_z, name##_step_z)
117
118#define CONVERT_TO_TENSOR3D_STRUCT_NO_STEP(name) \
119 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0, name##_stride_z, 0)
120
steniu01868e5412017-07-17 23:16:00 +0100121#define CONVERT_TO_TENSOR4D_STRUCT(name, mod_size) \
122 update_tensor4D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, \
123 name##_stride_z, name##_step_z, name##_stride_w, name##_step_z, mod_size)
124
125#define CONVERT_TO_TENSOR4D_STRUCT_NO_STEP(name, mod_size) \
126 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)
127
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100128/** Structure to hold Vector information */
129typedef struct Vector
130{
131 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
132 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
133 int stride_x; /**< Stride of the image in X dimension (in bytes) */
134} Vector;
135
136/** Structure to hold Image information */
137typedef struct Image
138{
139 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
140 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
141 int stride_x; /**< Stride of the image in X dimension (in bytes) */
142 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
143} Image;
144
145/** Structure to hold 3D tensor information */
146typedef struct Tensor3D
147{
148 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
149 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
150 int stride_x; /**< Stride of the image in X dimension (in bytes) */
151 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
152 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
153} Tensor3D;
154
steniu01868e5412017-07-17 23:16:00 +0100155/** Structure to hold 4D tensor information */
156typedef struct Tensor4D
157{
158 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
159 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
160 int stride_x; /**< Stride of the image in X dimension (in bytes) */
161 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
162 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
163 int stride_w; /**< Stride of the image in W dimension (in bytes) */
164} Tensor4D;
165
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100166/** Wrap vector information into an Vector structure, and make the pointer point at this workitem's data.
167 *
168 * @param[in] ptr Pointer to the starting postion of the buffer
169 * @param[in] offset_first_element_in_bytes The offset of the first element in the source vector
170 * @param[in] stride_x Stride of the vector in X dimension (in bytes)
171 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
172 *
173 * @return An image object
174 */
175Vector inline update_vector_workitem_ptr(__global uchar *ptr, uint offset_first_element_in_bytes, uint stride_x, uint step_x)
176{
177 Vector vector =
178 {
179 .ptr = ptr,
180 .offset_first_element_in_bytes = offset_first_element_in_bytes,
181 .stride_x = stride_x,
182 };
183 vector.ptr += vector.offset_first_element_in_bytes + get_global_id(0) * step_x;
184 return vector;
185}
186
187/** Wrap image information into an Image structure, and make the pointer point at this workitem's data.
188 *
189 * @param[in] ptr Pointer to the starting postion of the buffer
190 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
191 * @param[in] stride_x Stride of the image in X dimension (in bytes)
192 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
193 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
194 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
195 *
196 * @return An image object
197 */
198Image 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)
199{
200 Image img =
201 {
202 .ptr = ptr,
203 .offset_first_element_in_bytes = offset_first_element_in_bytes,
204 .stride_x = stride_x,
205 .stride_y = stride_y
206 };
207 img.ptr += img.offset_first_element_in_bytes + get_global_id(0) * step_x + get_global_id(1) * step_y;
208 return img;
209}
210
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100211/** Wrap 3D tensor information into an image structure, and make the pointer point at this workitem's data.
212 *
213 * @param[in] ptr Pointer to the starting postion of the buffer
214 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
215 * @param[in] stride_x Stride of the image in X dimension (in bytes)
216 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
217 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
218 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
219 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
220 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
221 *
222 * @return A 3D tensor object
223 */
224Image 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)
225{
226 Image img =
227 {
228 .ptr = ptr,
229 .offset_first_element_in_bytes = offset_first_element_in_bytes,
230 .stride_x = stride_x,
231 .stride_y = stride_y
232 };
233 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;
234 return img;
235}
236
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100237/** Wrap 3D tensor information into an tensor structure, and make the pointer point at this workitem's data.
238 *
239 * @param[in] ptr Pointer to the starting postion of the buffer
240 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
241 * @param[in] stride_x Stride of the image in X dimension (in bytes)
242 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
243 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
244 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
245 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
246 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
247 *
248 * @return A 3D tensor object
249 */
250Tensor3D 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)
251{
252 Tensor3D tensor =
253 {
254 .ptr = ptr,
255 .offset_first_element_in_bytes = offset_first_element_in_bytes,
256 .stride_x = stride_x,
257 .stride_y = stride_y,
258 .stride_z = stride_z
259 };
260 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;
261 return tensor;
262}
263
steniu01868e5412017-07-17 23:16:00 +0100264Tensor4D 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,
265 uint step_w,
266 uint mod_size)
267{
268 Tensor4D tensor =
269 {
270 .ptr = ptr,
271 .offset_first_element_in_bytes = offset_first_element_in_bytes,
272 .stride_x = stride_x,
273 .stride_y = stride_y,
274 .stride_z = stride_z,
275 .stride_w = stride_w
276 };
277
278 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;
279 return tensor;
280}
281
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100282/** Get the pointer position of a Vector
283 *
284 * @param[in] vec Pointer to the starting position of the buffer
285 * @param[in] x Relative X position
286 */
287__global inline const uchar *vector_offset(const Vector *vec, int x)
288{
289 return vec->ptr + x * vec->stride_x;
290}
291
292/** Get the pointer position of a Image
293 *
294 * @param[in] img Pointer to the starting position of the buffer
295 * @param[in] x Relative X position
296 * @param[in] y Relative Y position
297 */
298__global inline uchar *offset(const Image *img, int x, int y)
299{
300 return img->ptr + x * img->stride_x + y * img->stride_y;
301}
302
303/** Get the pointer position of a Tensor3D
304 *
Gian Marco Iodice3a623242017-07-25 10:25:53 +0100305 * @param[in] tensor Pointer to the starting position of the buffer
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100306 * @param[in] x Relative X position
307 * @param[in] y Relative Y position
308 * @param[in] z Relative Z position
309 */
310__global inline const uchar *tensor3D_offset(const Tensor3D *tensor, int x, int y, int z)
311{
312 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z;
313}
314
steniu01868e5412017-07-17 23:16:00 +0100315/** Get the pointer position of a Tensor4D
316 *
317 * @param[in] tensor Pointer to the starting position of the buffer
318 * @param[in] x Relative X position
319 * @param[in] y Relative Y position
320 * @param[in] z Relative Z position
321 * @param[in] w Relative W position
322 */
323__global inline const uchar *tensor4D_offset(const Tensor4D *tensor, int x, int y, int z, int w)
324{
325 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z + w * tensor->stride_w;
326}
327
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100328#endif // _HELPER_H