Blender V4.3
kernel_templates.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021-2022 Intel Corporation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7/* Some macro magic to generate templates for kernel arguments.
8 * The resulting oneapi_call() template allows to call a SYCL/C++ kernel
9 * with typed arguments by only giving it a void `**args` as given by Cycles.
10 * The template will automatically cast from void* to the expected type. */
11
12/* When expanded by the preprocessor, the generated templates will look like this example: */
13#if 0
14template<typename T0, typename T1, typename T2>
15void oneapi_call(
17 sycl::handler &cgh,
18 size_t global_size,
19 size_t local_size,
20 void **args,
21 void (*func)(const KernelGlobalsGPU *, size_t, size_t, sycl::handler &, T0, T1, T2))
22{
23 func(kg, global_size, local_size, cgh, *(T0 *)(args[0]), *(T1 *)(args[1]), *(T2 *)(args[2]));
24}
25#endif
26
27/* clang-format off */
28#define ONEAPI_TYP(x) typename T##x
29#define ONEAPI_CAST(x) *(T##x *)(args[x])
30#define ONEAPI_T(x) T##x
31
32#define ONEAPI_GET_NTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, N, ...) N
33#define ONEAPI_0(_call, ...)
34#define ONEAPI_1(_call, x) _call(x)
35#define ONEAPI_2(_call, x, ...) _call(x), ONEAPI_1(_call, __VA_ARGS__)
36#define ONEAPI_3(_call, x, ...) _call(x), ONEAPI_2(_call, __VA_ARGS__)
37#define ONEAPI_4(_call, x, ...) _call(x), ONEAPI_3(_call, __VA_ARGS__)
38#define ONEAPI_5(_call, x, ...) _call(x), ONEAPI_4(_call, __VA_ARGS__)
39#define ONEAPI_6(_call, x, ...) _call(x), ONEAPI_5(_call, __VA_ARGS__)
40#define ONEAPI_7(_call, x, ...) _call(x), ONEAPI_6(_call, __VA_ARGS__)
41#define ONEAPI_8(_call, x, ...) _call(x), ONEAPI_7(_call, __VA_ARGS__)
42#define ONEAPI_9(_call, x, ...) _call(x), ONEAPI_8(_call, __VA_ARGS__)
43#define ONEAPI_10(_call, x, ...) _call(x), ONEAPI_9(_call, __VA_ARGS__)
44#define ONEAPI_11(_call, x, ...) _call(x), ONEAPI_10(_call, __VA_ARGS__)
45#define ONEAPI_12(_call, x, ...) _call(x), ONEAPI_11(_call, __VA_ARGS__)
46#define ONEAPI_13(_call, x, ...) _call(x), ONEAPI_12(_call, __VA_ARGS__)
47#define ONEAPI_14(_call, x, ...) _call(x), ONEAPI_13(_call, __VA_ARGS__)
48#define ONEAPI_15(_call, x, ...) _call(x), ONEAPI_14(_call, __VA_ARGS__)
49#define ONEAPI_16(_call, x, ...) _call(x), ONEAPI_15(_call, __VA_ARGS__)
50#define ONEAPI_17(_call, x, ...) _call(x), ONEAPI_16(_call, __VA_ARGS__)
51#define ONEAPI_18(_call, x, ...) _call(x), ONEAPI_17(_call, __VA_ARGS__)
52#define ONEAPI_19(_call, x, ...) _call(x), ONEAPI_18(_call, __VA_ARGS__)
53#define ONEAPI_20(_call, x, ...) _call(x), ONEAPI_19(_call, __VA_ARGS__)
54#define ONEAPI_21(_call, x, ...) _call(x), ONEAPI_20(_call, __VA_ARGS__)
55
56#define ONEAPI_CALL_FOR(x, ...) \
57 ONEAPI_GET_NTH_ARG("ignored", \
58 ##__VA_ARGS__, \
59 ONEAPI_21, \
60 ONEAPI_20, \
61 ONEAPI_19, \
62 ONEAPI_18, \
63 ONEAPI_17, \
64 ONEAPI_16, \
65 ONEAPI_15, \
66 ONEAPI_14, \
67 ONEAPI_13, \
68 ONEAPI_12, \
69 ONEAPI_11, \
70 ONEAPI_10, \
71 ONEAPI_9, \
72 ONEAPI_8, \
73 ONEAPI_7, \
74 ONEAPI_6, \
75 ONEAPI_5, \
76 ONEAPI_4, \
77 ONEAPI_3, \
78 ONEAPI_2, \
79 ONEAPI_1, \
80 ONEAPI_0) \
81 (x, ##__VA_ARGS__)
82
83/* This template automatically casts entries in the void **args array to the types requested by the kernel func.
84 * Since kernel parameters are passed as void ** to the device, this is the closest that we have to type safety. */
85#define oneapi_template(...) \
86 template<ONEAPI_CALL_FOR(ONEAPI_TYP, __VA_ARGS__)> \
87 void oneapi_call( \
88 KernelGlobalsGPU *kg, \
89 sycl::handler &cgh, \
90 size_t global_size, \
91 size_t local_size, \
92 void **args, \
93 void (*func)(KernelGlobalsGPU*, size_t, size_t, sycl::handler &, ONEAPI_CALL_FOR(ONEAPI_T, __VA_ARGS__))) \
94 { \
95 func(kg, \
96 global_size, \
97 local_size, \
98 cgh, \
99 ONEAPI_CALL_FOR(ONEAPI_CAST, __VA_ARGS__)); \
100 }
101
103oneapi_template(0, 1)
105oneapi_template(0, 1, 2, 3)
106oneapi_template(0, 1, 2, 3, 4)
107oneapi_template(0, 1, 2, 3, 4, 5)
108oneapi_template(0, 1, 2, 3, 4, 5, 6)
109oneapi_template(0, 1, 2, 3, 4, 5, 6, 7)
110oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8)
111oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
112oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
113oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
114oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
115oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
116oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
117oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
118oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
119oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)
120oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)
121oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
122oneapi_template(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
123
124 /* clang-format on */
#define oneapi_template(...)
#define T2
Definition md5.cpp:19
#define T1
Definition md5.cpp:18