blob: 68af64e3443695441cab3bfdf83487d436bfb22b [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
27#pragma OPENCL EXTENSION cl_khr_fp16 : enable
28
Georgios Pinitase5f8fd62017-06-23 18:03:44 +010029#define EXPAND(x) x
30
Anthony Barbier6ff3b192017-09-04 18:44:23 +010031#define CLAMP(x, min_val, max_val) min(max(x, min_val), max_val)
32
Georgios Pinitasac4e8732017-07-05 17:02:25 +010033#define VLOAD_STR(size) vload##size
34#define VLOAD(size) VLOAD_STR(size)
35
36#define VSTORE_STR(size) vstore##size
37#define VSTORE(size) VSTORE_STR(size)
38
Anthony Barbier6ff3b192017-09-04 18:44:23 +010039#define VEC_DATA_TYPE_STR(type, size) type##size
40#define VEC_DATA_TYPE(type, size) VEC_DATA_TYPE_STR(type, size)
41
42#define CONVERT_STR(x, type) (convert_##type((x)))
43#define CONVERT(x, type) CONVERT_STR(x, type)
44
45#define CONVERT_SAT_STR(x, type) (convert_##type##_sat((x)))
46#define CONVERT_SAT(x, type) CONVERT_SAT_STR(x, type)
47
48#define CONVERT_SAT_ROUND_STR(x, type, round) (convert_##type##_sat_##round((x)))
49#define CONVERT_SAT_ROUND(x, type, round) CONVERT_SAT_ROUND_STR(x, type, round)
50
51#define VECTOR_DECLARATION(name) \
52 __global uchar *name##_ptr, \
53 uint name##_stride_x, \
54 uint name##_step_x, \
55 uint name##_offset_first_element_in_bytes
56
57#define IMAGE_DECLARATION(name) \
58 __global uchar *name##_ptr, \
59 uint name##_stride_x, \
60 uint name##_step_x, \
61 uint name##_stride_y, \
62 uint name##_step_y, \
63 uint name##_offset_first_element_in_bytes
64
65#define TENSOR3D_DECLARATION(name) \
66 __global uchar *name##_ptr, \
67 uint name##_stride_x, \
68 uint name##_step_x, \
69 uint name##_stride_y, \
70 uint name##_step_y, \
71 uint name##_stride_z, \
72 uint name##_step_z, \
73 uint name##_offset_first_element_in_bytes
74
steniu01868e5412017-07-17 23:16:00 +010075#define TENSOR4D_DECLARATION(name) \
76 __global uchar *name##_ptr, \
77 uint name##_stride_x, \
78 uint name##_step_x, \
79 uint name##_stride_y, \
80 uint name##_step_y, \
81 uint name##_stride_z, \
82 uint name##_step_z, \
83 uint name##_stride_w, \
84 uint name##_step_w, \
85 uint name##_offset_first_element_in_bytes
86
Anthony Barbier6ff3b192017-09-04 18:44:23 +010087#define CONVERT_TO_VECTOR_STRUCT(name) \
88 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x)
89
90#define CONVERT_TO_VECTOR_STRUCT_NO_STEP(name) \
91 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0)
92
93#define CONVERT_TO_IMAGE_STRUCT(name) \
94 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y)
95
96#define CONVERT_TO_IMAGE_STRUCT_NO_STEP(name) \
97 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0)
98
steniu01868e5412017-07-17 23:16:00 +010099#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
100 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)
101
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100102#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT_NO_STEP(name) \
103 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)
104
steniu010d523cc2017-07-13 14:24:23 +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 Barbier6ff3b192017-09-04 18:44:23 +0100108#define CONVERT_TO_TENSOR3D_STRUCT(name) \
109 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, \
110 name##_stride_z, name##_step_z)
111
112#define CONVERT_TO_TENSOR3D_STRUCT_NO_STEP(name) \
113 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0, name##_stride_z, 0)
114
steniu01868e5412017-07-17 23:16:00 +0100115#define CONVERT_TO_TENSOR4D_STRUCT(name, mod_size) \
116 update_tensor4D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, \
117 name##_stride_z, name##_step_z, name##_stride_w, name##_step_z, mod_size)
118
119#define CONVERT_TO_TENSOR4D_STRUCT_NO_STEP(name, mod_size) \
120 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)
121
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100122/** Structure to hold Vector information */
123typedef struct Vector
124{
125 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
126 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
127 int stride_x; /**< Stride of the image in X dimension (in bytes) */
128} Vector;
129
130/** Structure to hold Image information */
131typedef struct Image
132{
133 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
134 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
135 int stride_x; /**< Stride of the image in X dimension (in bytes) */
136 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
137} Image;
138
139/** Structure to hold 3D tensor information */
140typedef struct Tensor3D
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 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
146 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
147} Tensor3D;
148
steniu01868e5412017-07-17 23:16:00 +0100149/** Structure to hold 4D tensor information */
150typedef struct Tensor4D
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 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
157 int stride_w; /**< Stride of the image in W dimension (in bytes) */
158} Tensor4D;
159
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100160/** Wrap vector information into an Vector structure, and make the pointer point at this workitem's data.
161 *
162 * @param[in] ptr Pointer to the starting postion of the buffer
163 * @param[in] offset_first_element_in_bytes The offset of the first element in the source vector
164 * @param[in] stride_x Stride of the vector in X dimension (in bytes)
165 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
166 *
167 * @return An image object
168 */
169Vector inline update_vector_workitem_ptr(__global uchar *ptr, uint offset_first_element_in_bytes, uint stride_x, uint step_x)
170{
171 Vector vector =
172 {
173 .ptr = ptr,
174 .offset_first_element_in_bytes = offset_first_element_in_bytes,
175 .stride_x = stride_x,
176 };
177 vector.ptr += vector.offset_first_element_in_bytes + get_global_id(0) * step_x;
178 return vector;
179}
180
181/** Wrap image information into an Image structure, and make the pointer point at this workitem's data.
182 *
183 * @param[in] ptr Pointer to the starting postion of the buffer
184 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
185 * @param[in] stride_x Stride of the image in X dimension (in bytes)
186 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
187 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
188 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
189 *
190 * @return An image object
191 */
192Image 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)
193{
194 Image img =
195 {
196 .ptr = ptr,
197 .offset_first_element_in_bytes = offset_first_element_in_bytes,
198 .stride_x = stride_x,
199 .stride_y = stride_y
200 };
201 img.ptr += img.offset_first_element_in_bytes + get_global_id(0) * step_x + get_global_id(1) * step_y;
202 return img;
203}
204
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100205/** Wrap 3D tensor information into an image structure, and make the pointer point at this workitem's data.
206 *
207 * @param[in] ptr Pointer to the starting postion of the buffer
208 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
209 * @param[in] stride_x Stride of the image in X dimension (in bytes)
210 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
211 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
212 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
213 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
214 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
215 *
216 * @return A 3D tensor object
217 */
218Image 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)
219{
220 Image img =
221 {
222 .ptr = ptr,
223 .offset_first_element_in_bytes = offset_first_element_in_bytes,
224 .stride_x = stride_x,
225 .stride_y = stride_y
226 };
227 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;
228 return img;
229}
230
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100231/** Wrap 3D tensor information into an tensor structure, and make the pointer point at this workitem's data.
232 *
233 * @param[in] ptr Pointer to the starting postion of the buffer
234 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
235 * @param[in] stride_x Stride of the image in X dimension (in bytes)
236 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
237 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
238 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
239 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
240 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
241 *
242 * @return A 3D tensor object
243 */
244Tensor3D 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)
245{
246 Tensor3D tensor =
247 {
248 .ptr = ptr,
249 .offset_first_element_in_bytes = offset_first_element_in_bytes,
250 .stride_x = stride_x,
251 .stride_y = stride_y,
252 .stride_z = stride_z
253 };
254 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;
255 return tensor;
256}
257
steniu01868e5412017-07-17 23:16:00 +0100258Tensor4D 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,
259 uint step_w,
260 uint mod_size)
261{
262 Tensor4D tensor =
263 {
264 .ptr = ptr,
265 .offset_first_element_in_bytes = offset_first_element_in_bytes,
266 .stride_x = stride_x,
267 .stride_y = stride_y,
268 .stride_z = stride_z,
269 .stride_w = stride_w
270 };
271
272 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;
273 return tensor;
274}
275
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100276/** Get the pointer position of a Vector
277 *
278 * @param[in] vec Pointer to the starting position of the buffer
279 * @param[in] x Relative X position
280 */
281__global inline const uchar *vector_offset(const Vector *vec, int x)
282{
283 return vec->ptr + x * vec->stride_x;
284}
285
286/** Get the pointer position of a Image
287 *
288 * @param[in] img Pointer to the starting position of the buffer
289 * @param[in] x Relative X position
290 * @param[in] y Relative Y position
291 */
292__global inline uchar *offset(const Image *img, int x, int y)
293{
294 return img->ptr + x * img->stride_x + y * img->stride_y;
295}
296
297/** Get the pointer position of a Tensor3D
298 *
Gian Marco Iodice3a623242017-07-25 10:25:53 +0100299 * @param[in] tensor Pointer to the starting position of the buffer
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100300 * @param[in] x Relative X position
301 * @param[in] y Relative Y position
302 * @param[in] z Relative Z position
303 */
304__global inline const uchar *tensor3D_offset(const Tensor3D *tensor, int x, int y, int z)
305{
306 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z;
307}
308
steniu01868e5412017-07-17 23:16:00 +0100309/** Get the pointer position of a Tensor4D
310 *
311 * @param[in] tensor Pointer to the starting position of the buffer
312 * @param[in] x Relative X position
313 * @param[in] y Relative Y position
314 * @param[in] z Relative Z position
315 * @param[in] w Relative W position
316 */
317__global inline const uchar *tensor4D_offset(const Tensor4D *tensor, int x, int y, int z, int w)
318{
319 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z + w * tensor->stride_w;
320}
321
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100322#endif // _HELPER_H