blob: f7f208529a543ff48b8e75872280c09d8f4b86a8 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Usama Arife2428a02019-05-09 11:03:17 +01002 * Copyright (c) 2016-2019 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
Usama Arife2428a02019-05-09 11:03:17 +010043#define GPU_ARCH_MIDGARD 0x100
44#define GPU_ARCH_BIFROST 0x200
45
Gian Marco Iodice43a129e2019-05-14 10:14:08 +010046#define CONCAT(a, b) a##b
47
Georgios Pinitase5f8fd62017-06-23 18:03:44 +010048#define EXPAND(x) x
49
Anthony Barbier6ff3b192017-09-04 18:44:23 +010050#define CLAMP(x, min_val, max_val) min(max(x, min_val), max_val)
51
Giorgio Arena5c4a8e92019-08-28 17:55:07 +010052#define REV1(x) ((x))
53#define REV2(x) ((x).s10)
54#define REV3(x) ((x).s210)
55#define REV4(x) ((x).s3210)
56#define REV8(x) ((x).s76543210)
57#define REV16(x) ((x).sFEDCBA9876543210)
58
59#define REVERSE_STR(x, s) REV##s((x))
60#define REVERSE(x, s) REVERSE_STR(x, s)
61
62#define ROT1_0(x) ((x))
63
64#define ROT2_0(x) ((x))
65#define ROT2_1(x) ((x).s10)
66
67#define ROT3_0(x) ((x))
68#define ROT3_1(x) ((x).s201)
69#define ROT3_2(x) ((x).s120)
70
71#define ROT4_0(x) ((x))
72#define ROT4_1(x) ((x).s3012)
73#define ROT4_2(x) ((x).s2301)
74#define ROT4_3(x) ((x).s1230)
75
76#define ROT8_0(x) ((x))
77#define ROT8_1(x) ((x).s70123456)
78#define ROT8_2(x) ((x).s67012345)
79#define ROT8_3(x) ((x).s56701234)
80#define ROT8_4(x) ((x).s45670123)
81#define ROT8_5(x) ((x).s34567012)
82#define ROT8_6(x) ((x).s23456701)
83#define ROT8_7(x) ((x).s12345670)
84
85#define ROT16_0(x) ((x))
86#define ROT16_1(x) ((x).sF0123456789ABCDE)
87#define ROT16_2(x) ((x).sEF0123456789ABCD)
88#define ROT16_3(x) ((x).sDEF0123456789ABC)
89#define ROT16_4(x) ((x).sCDEF0123456789AB)
90#define ROT16_5(x) ((x).sBCDEF0123456789A)
91#define ROT16_6(x) ((x).sABCDEF0123456789)
92#define ROT16_7(x) ((x).s9ABCDEF012345678)
93#define ROT16_8(x) ((x).s89ABCDEF01234567)
94#define ROT16_9(x) ((x).s789ABCDEF0123456)
95#define ROT16_10(x) ((x).s6789ABCDEF012345)
96#define ROT16_11(x) ((x).s56789ABCDEF01234)
97#define ROT16_12(x) ((x).s456789ABCDEF0123)
98#define ROT16_13(x) ((x).s3456789ABCDEF012)
99#define ROT16_14(x) ((x).s23456789ABCDEF01)
100#define ROT16_15(x) ((x).s123456789ABCDEF0)
101
102#define ROTATE_STR(x, s, n) ROT##s##_##n(x)
103#define ROTATE(x, s, n) ROTATE_STR(x, s, n)
104
105#define V_OFFS1(dt) (dt)(0)
106#define V_OFFS2(dt) (dt)(0, 1)
107#define V_OFFS3(dt) (dt)(0, 1, 3)
108#define V_OFFS4(dt) (dt)(0, 1, 2, 3)
109#define V_OFFS8(dt) (dt)(0, 1, 2, 3, 4, 5, 6, 7)
110#define V_OFFS16(dt) (dt)(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
111
112#define VEC_OFFS_STR(dt, s) V_OFFS##s(dt)
113#define VEC_OFFS(dt, s) VEC_OFFS_STR(dt, s)
114
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100115#define VLOAD_STR(size) vload##size
116#define VLOAD(size) VLOAD_STR(size)
117
118#define VSTORE_STR(size) vstore##size
119#define VSTORE(size) VSTORE_STR(size)
120
Manuel Bottini0d0028c2018-10-02 16:41:52 +0100121#define float1 float
122#define half1 half
Usama Arif0681e3b2019-04-25 14:28:07 +0100123#define char1 char
124#define uchar1 uchar
125#define short1 short
126#define ushort1 ushort
127#define int1 int
128#define uint1 uint
129#define long1 long
130#define ulong1 ulong
131#define double1 double
132
133#define vload1(OFFSET, PTR) *(OFFSET + PTR)
Gian Marco Iodice9285adb2019-09-05 16:10:27 +0100134#define vstore1(DATA, OFFSET, PTR) *(OFFSET + PTR) = DATA
Manuel Bottini0d0028c2018-10-02 16:41:52 +0100135
Gian Marco Iodice0c17aa22019-09-27 09:23:15 +0100136// Convert built-in functions with _sat modifier are not supported in floating point so we create defines
137// without _sat to overcome this issue
138#define convert_float_sat convert_float
139#define convert_float1_sat convert_float
140#define convert_float2_sat convert_float2
141#define convert_float3_sat convert_float3
142#define convert_float4_sat convert_float4
143#define convert_float8_sat convert_float8
144#define convert_float16_sat convert_float16
145#define convert_half_sat convert_float
146#define convert_half1_sat convert_half
147#define convert_half2_sat convert_half2
148#define convert_half3_sat convert_half3
149#define convert_half4_sat convert_half4
150#define convert_half8_sat convert_half8
151#define convert_half16_sat convert_half16
152
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100153#define VEC_DATA_TYPE_STR(type, size) type##size
154#define VEC_DATA_TYPE(type, size) VEC_DATA_TYPE_STR(type, size)
155
Chunosovd6afedc2017-11-06 22:09:45 +0700156#define CL_VEC_DATA_TYPE_STR(type, size) type##size
157#define CL_VEC_DATA_TYPE(type, size) CL_VEC_DATA_TYPE_STR(type, size)
158
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100159#define CONVERT_STR(x, type) (convert_##type((x)))
160#define CONVERT(x, type) CONVERT_STR(x, type)
161
162#define CONVERT_SAT_STR(x, type) (convert_##type##_sat((x)))
163#define CONVERT_SAT(x, type) CONVERT_SAT_STR(x, type)
164
165#define CONVERT_SAT_ROUND_STR(x, type, round) (convert_##type##_sat_##round((x)))
166#define CONVERT_SAT_ROUND(x, type, round) CONVERT_SAT_ROUND_STR(x, type, round)
167
168#define VECTOR_DECLARATION(name) \
169 __global uchar *name##_ptr, \
170 uint name##_stride_x, \
171 uint name##_step_x, \
172 uint name##_offset_first_element_in_bytes
173
174#define IMAGE_DECLARATION(name) \
175 __global uchar *name##_ptr, \
176 uint name##_stride_x, \
177 uint name##_step_x, \
178 uint name##_stride_y, \
179 uint name##_step_y, \
180 uint name##_offset_first_element_in_bytes
181
182#define TENSOR3D_DECLARATION(name) \
183 __global uchar *name##_ptr, \
184 uint name##_stride_x, \
185 uint name##_step_x, \
186 uint name##_stride_y, \
187 uint name##_step_y, \
188 uint name##_stride_z, \
189 uint name##_step_z, \
190 uint name##_offset_first_element_in_bytes
191
steniu01868e5412017-07-17 23:16:00 +0100192#define TENSOR4D_DECLARATION(name) \
193 __global uchar *name##_ptr, \
194 uint name##_stride_x, \
195 uint name##_step_x, \
196 uint name##_stride_y, \
197 uint name##_step_y, \
198 uint name##_stride_z, \
199 uint name##_step_z, \
200 uint name##_stride_w, \
201 uint name##_step_w, \
202 uint name##_offset_first_element_in_bytes
203
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100204#define CONVERT_TO_VECTOR_STRUCT(name) \
205 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x)
206
207#define CONVERT_TO_VECTOR_STRUCT_NO_STEP(name) \
208 update_vector_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0)
209
210#define CONVERT_TO_IMAGE_STRUCT(name) \
211 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y)
212
213#define CONVERT_TO_IMAGE_STRUCT_NO_STEP(name) \
214 update_image_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0)
215
steniu01868e5412017-07-17 23:16:00 +0100216#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
217 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)
218
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100219#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT_NO_STEP(name) \
220 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)
221
steniu010d523cc2017-07-13 14:24:23 +0100222#define CONVERT_TENSOR3D_TO_IMAGE_STRUCT(name) \
223 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)
224
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100225#define CONVERT_TO_TENSOR3D_STRUCT(name) \
226 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, name##_step_x, name##_stride_y, name##_step_y, \
227 name##_stride_z, name##_step_z)
228
229#define CONVERT_TO_TENSOR3D_STRUCT_NO_STEP(name) \
230 update_tensor3D_workitem_ptr(name##_ptr, name##_offset_first_element_in_bytes, name##_stride_x, 0, name##_stride_y, 0, name##_stride_z, 0)
231
steniu01868e5412017-07-17 23:16:00 +0100232#define CONVERT_TO_TENSOR4D_STRUCT(name, mod_size) \
233 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 +0000234 name##_stride_z, name##_step_z, name##_stride_w, name##_step_w, mod_size)
steniu01868e5412017-07-17 23:16:00 +0100235
236#define CONVERT_TO_TENSOR4D_STRUCT_NO_STEP(name, mod_size) \
237 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)
238
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100239/** Structure to hold Vector information */
240typedef struct Vector
241{
242 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
243 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
244 int stride_x; /**< Stride of the image in X dimension (in bytes) */
245} Vector;
246
247/** Structure to hold Image information */
248typedef struct Image
249{
250 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
251 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
252 int stride_x; /**< Stride of the image in X dimension (in bytes) */
253 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
254} Image;
255
256/** Structure to hold 3D tensor information */
257typedef struct Tensor3D
258{
259 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
260 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
261 int stride_x; /**< Stride of the image in X dimension (in bytes) */
262 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
263 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
264} Tensor3D;
265
steniu01868e5412017-07-17 23:16:00 +0100266/** Structure to hold 4D tensor information */
267typedef struct Tensor4D
268{
269 __global uchar *ptr; /**< Pointer to the starting postion of the buffer */
270 int offset_first_element_in_bytes; /**< The offset of the first element in the source image */
271 int stride_x; /**< Stride of the image in X dimension (in bytes) */
272 int stride_y; /**< Stride of the image in Y dimension (in bytes) */
273 int stride_z; /**< Stride of the image in Z dimension (in bytes) */
274 int stride_w; /**< Stride of the image in W dimension (in bytes) */
275} Tensor4D;
276
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100277/** Wrap vector information into an Vector structure, and make the pointer point at this workitem's data.
278 *
279 * @param[in] ptr Pointer to the starting postion of the buffer
280 * @param[in] offset_first_element_in_bytes The offset of the first element in the source vector
281 * @param[in] stride_x Stride of the vector in X dimension (in bytes)
282 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
283 *
284 * @return An image object
285 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100286inline 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 +0100287{
288 Vector vector =
289 {
290 .ptr = ptr,
291 .offset_first_element_in_bytes = offset_first_element_in_bytes,
292 .stride_x = stride_x,
293 };
294 vector.ptr += vector.offset_first_element_in_bytes + get_global_id(0) * step_x;
295 return vector;
296}
297
298/** Wrap image information into an Image structure, and make the pointer point at this workitem's data.
299 *
300 * @param[in] ptr Pointer to the starting postion of the buffer
301 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
302 * @param[in] stride_x Stride of the image in X dimension (in bytes)
303 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
304 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
305 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
306 *
307 * @return An image object
308 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100309inline 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 +0100310{
311 Image img =
312 {
313 .ptr = ptr,
314 .offset_first_element_in_bytes = offset_first_element_in_bytes,
315 .stride_x = stride_x,
316 .stride_y = stride_y
317 };
318 img.ptr += img.offset_first_element_in_bytes + get_global_id(0) * step_x + get_global_id(1) * step_y;
319 return img;
320}
321
Anthony Barbier7ff47a32017-07-11 16:54:04 +0100322/** Wrap 3D tensor information into an image structure, and make the pointer point at this workitem's data.
323 *
324 * @param[in] ptr Pointer to the starting postion of the buffer
325 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
326 * @param[in] stride_x Stride of the image in X dimension (in bytes)
327 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
328 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
329 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
330 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
331 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
332 *
333 * @return A 3D tensor object
334 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100335inline 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 +0100336{
337 Image img =
338 {
339 .ptr = ptr,
340 .offset_first_element_in_bytes = offset_first_element_in_bytes,
341 .stride_x = stride_x,
342 .stride_y = stride_y
343 };
344 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;
345 return img;
346}
347
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100348/** Wrap 3D tensor information into an tensor structure, and make the pointer point at this workitem's data.
349 *
350 * @param[in] ptr Pointer to the starting postion of the buffer
351 * @param[in] offset_first_element_in_bytes The offset of the first element in the source image
352 * @param[in] stride_x Stride of the image in X dimension (in bytes)
353 * @param[in] step_x stride_x * number of elements along X processed per workitem(in bytes)
354 * @param[in] stride_y Stride of the image in Y dimension (in bytes)
355 * @param[in] step_y stride_y * number of elements along Y processed per workitem(in bytes)
356 * @param[in] stride_z Stride of the image in Z dimension (in bytes)
357 * @param[in] step_z stride_z * number of elements along Z processed per workitem(in bytes)
358 *
359 * @return A 3D tensor object
360 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100361inline 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 +0100362{
363 Tensor3D tensor =
364 {
365 .ptr = ptr,
366 .offset_first_element_in_bytes = offset_first_element_in_bytes,
367 .stride_x = stride_x,
368 .stride_y = stride_y,
369 .stride_z = stride_z
370 };
371 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;
372 return tensor;
373}
374
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100375inline 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 +0100376 uint step_w,
377 uint mod_size)
378{
379 Tensor4D tensor =
380 {
381 .ptr = ptr,
382 .offset_first_element_in_bytes = offset_first_element_in_bytes,
383 .stride_x = stride_x,
384 .stride_y = stride_y,
385 .stride_z = stride_z,
386 .stride_w = stride_w
387 };
388
389 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;
390 return tensor;
391}
392
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100393/** Get the pointer position of a Vector
394 *
395 * @param[in] vec Pointer to the starting position of the buffer
396 * @param[in] x Relative X position
397 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100398inline __global const uchar *vector_offset(const Vector *vec, int x)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100399{
400 return vec->ptr + x * vec->stride_x;
401}
402
403/** Get the pointer position of a Image
404 *
405 * @param[in] img Pointer to the starting position of the buffer
406 * @param[in] x Relative X position
407 * @param[in] y Relative Y position
408 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100409inline __global uchar *offset(const Image *img, int x, int y)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100410{
411 return img->ptr + x * img->stride_x + y * img->stride_y;
412}
413
414/** Get the pointer position of a Tensor3D
415 *
Gian Marco Iodice3a623242017-07-25 10:25:53 +0100416 * @param[in] tensor Pointer to the starting position of the buffer
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100417 * @param[in] x Relative X position
418 * @param[in] y Relative Y position
419 * @param[in] z Relative Z position
420 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100421inline __global const uchar *tensor3D_offset(const Tensor3D *tensor, int x, int y, int z)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100422{
423 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z;
424}
425
steniu01868e5412017-07-17 23:16:00 +0100426/** Get the pointer position of a Tensor4D
427 *
428 * @param[in] tensor Pointer to the starting position of the buffer
429 * @param[in] x Relative X position
430 * @param[in] y Relative Y position
431 * @param[in] z Relative Z position
432 * @param[in] w Relative W position
433 */
Georgios Pinitasaf7f7402018-10-25 16:04:40 +0100434inline __global const uchar *tensor4D_offset(const Tensor4D *tensor, int x, int y, int z, int w)
steniu01868e5412017-07-17 23:16:00 +0100435{
436 return tensor->ptr + x * tensor->stride_x + y * tensor->stride_y + z * tensor->stride_z + w * tensor->stride_w;
437}
438
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100439#endif // _HELPER_H