16 template <
typename Function>
21 template <typename F, unsigned Arity = function_traits<F>::arity>
30 std::remove_cv_t<T> value;
31 std::memcpy(&value, address,
sizeof(value));
35 template <
typename Po
inter>
40 auto parameterSlot = loadArgumentSlot<const void*>(buffer);
43 auto ndarray = loadArgumentSlot<const mu::NDArray<char>*>(parameterSlot);
44 return reinterpret_cast<Pointer
>(
const_cast<char*
>(ndarray->data()));
46 return loadArgumentSlot<Pointer>(parameterSlot);
49 template <
typename Po
inter>
52 auto parameterSlot = loadArgumentSlot<void*>(buffer);
55 auto ndarray = loadArgumentSlot<mu::NDArray<char>*>(parameterSlot);
56 ndarray->setData(
reinterpret_cast<void*
>(
reinterpret_cast<uintptr_t
>(value)));
60 std::memcpy(parameterSlot, &value,
sizeof(value));
64 template <
typename Param>
70 using wire_type =
typename adapter::wire_type;
71 return adapter::fromWire(unpackKernelPointer<wire_type>(isNDArrayValue, buffer));
75 return unpackKernelPointer<Param>(isNDArrayValue, buffer);
79 Param* value = *
reinterpret_cast<Param**
>(buffer);
80 if constexpr (is_ndarray_v<Param>)
82 void* argumentAddress = *
reinterpret_cast<void**
>(buffer);
83 value = *
reinterpret_cast<Param**
>(argumentAddress);
87 void* argumentAddress = *
reinterpret_cast<void**
>(buffer);
91 void* dataPointer = ndarray->
data();
92 value = *
reinterpret_cast<Param**
>(dataPointer);
96 value = *
reinterpret_cast<Param**
>(argumentAddress);
99 return static_cast<Param&
>(*value);
105 #define GET_ARG(num) \
106 static_assert(detail::supported_directional_parameter_v<typename function_traits<F>::arg##num##_type>, \
107 "Directional kernel pointer parameters must be passed by value, not by reference"); \
108 using remove_reference##num##_t = typename remove_reference<typename function_traits<F>::arg##num##_type>::type; \
109 decltype(auto) a##num = detail::unpackKernelArgument<remove_reference##num##_t>( \
110 mode, (ndarrayValueBit & (1ull << (num - 1))) != 0, buffer); \
111 buffer += sizeof(void*);
113 #define PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
114 #define ARGS(x) PRIMITIVE_CAT(ARGS_, x)
116 #define ARGS_1 GET_ARG(1);
117 #define ARGS_2 ARGS_1 GET_ARG(2);
118 #define ARGS_3 ARGS_2 GET_ARG(3);
119 #define ARGS_4 ARGS_3 GET_ARG(4);
120 #define ARGS_5 ARGS_4 GET_ARG(5);
121 #define ARGS_6 ARGS_5 GET_ARG(6);
122 #define ARGS_7 ARGS_6 GET_ARG(7);
123 #define ARGS_8 ARGS_7 GET_ARG(8);
124 #define ARGS_9 ARGS_8 GET_ARG(9);
128 #define STORE_ARG(num) \
129 if constexpr (std::is_lvalue_reference_v<typename function_traits<F>::arg##num##_type> && \
130 is_pointer<remove_reference##num##_t>::value && !std::is_const_v<remove_reference##num##_t>) \
132 detail::storeKernelPointer((ndarrayValueBit & (1ull << (num - 1))) != 0, \
133 argumentStart + (num - 1) * sizeof(void*), a##num); \
135 #define STORES(x) PRIMITIVE_CAT(STORES_, x)
137 #define STORES_1 STORE_ARG(1);
138 #define STORES_2 STORES_1 STORE_ARG(2);
139 #define STORES_3 STORES_2 STORE_ARG(3);
140 #define STORES_4 STORES_3 STORE_ARG(4);
141 #define STORES_5 STORES_4 STORE_ARG(5);
142 #define STORES_6 STORES_5 STORE_ARG(6);
143 #define STORES_7 STORES_6 STORE_ARG(7);
144 #define STORES_8 STORES_7 STORE_ARG(8);
145 #define STORES_9 STORES_8 STORE_ARG(9);
147 #define CALL_PARAMS(x) PRIMITIVE_CAT(CALL_PARAMS_, x)
148 #define CALL_PARAMS_0
149 #define CALL_PARAMS_1 a1
150 #define CALL_PARAMS_2 CALL_PARAMS_1, a2
151 #define CALL_PARAMS_3 CALL_PARAMS_2, a3
152 #define CALL_PARAMS_4 CALL_PARAMS_3, a4
153 #define CALL_PARAMS_5 CALL_PARAMS_4, a5
154 #define CALL_PARAMS_6 CALL_PARAMS_5, a6
155 #define CALL_PARAMS_7 CALL_PARAMS_6, a7
156 #define CALL_PARAMS_8 CALL_PARAMS_7, a8
157 #define CALL_PARAMS_9 CALL_PARAMS_8, a9
158 #define CALL_FUNC(x) fp(CALL_PARAMS(x))
160 #define CALL_HELPER(_NUM) \
161 template <typename F> \
162 class CallHelper<F, _NUM> \
165 template <typename FP> \
166 static void invoke(FP fp, [[maybe_unused]] uint32_t mode, [[maybe_unused]] uint32_t ndarrayValueBit, \
167 [[maybe_unused]] char* buffer) \
169 [[maybe_unused]] char* argumentStart = buffer; \
226 template <
typename FP>
227 inline void callMain(FP func, uint32_t mode, uint32_t ndarrayValueBit,
char* buffer)
NDArray is a class that can be used in both host and device code. NDArray is automatically divided in...
Pointer unpackKernelPointer(bool isNDArrayValue, const char *buffer)
T loadArgumentSlot(const void *address)
void storeKernelPointer(bool isNDArrayValue, char *buffer, Pointer value)
decltype(auto) unpackKernelArgument(uint32_t mode, bool isNDArrayValue, char *buffer)
void callMain(FP func, uint32_t mode, uint32_t ndarrayValueBit, char *buffer)
bool isNormalMode(uint32_t mode)