37 template <
typename R,
typename... Args>
40 static constexpr std::size_t arity =
sizeof...(Args);
44 template <
typename R,
typename... Args>
52 template <auto Func, std::
size_t Index>
56 template <
typename T,
typename =
void>
64 T, std::void_t<typename T::element_type, typename T::kernel_buffer_direction>>
67 using direction_tag =
typename T::kernel_buffer_direction;
68 static constexpr
bool reads = direction_tag::reads_existing_data;
69 static constexpr
bool writes = direction_tag::writes_result;
72 static_assert(reads || writes,
"A directional kernel buffer needs read or write access");
81 template <
typename T,
typename =
void>
88 T, std::void_t<typename T::element_type, typename T::kernel_buffer_direction>>
100 static constexpr
bool valid =
false;
105 template <
typename T>
108 static constexpr
bool valid =
true;
113 template <
typename T>
121 template <
typename Param,
typename Actual,
bool = IsDirectionalKernelParamV<Param>>
126 template <
typename Param,
typename Actual>
130 using parameter_type = std::remove_cv_t<std::remove_reference_t<Param>>;
131 using parameter_element =
typename parameter_type::element_type;
132 using direction_tag =
typename parameter_type::kernel_buffer_direction;
135 static constexpr
bool writes = direction_tag::writes_result;
136 using wire_element = std::conditional_t<writes, parameter_element,
137 std::add_const_t<parameter_element>>;
140 static constexpr
bool value =
141 !std::is_reference_v<Param> &&
142 actual_buffer::valid &&
143 !std::is_void_v<std::remove_cv_t<parameter_element>> &&
144 !std::is_function_v<parameter_element> &&
145 (!writes || !std::is_const_v<parameter_element>) &&
146 std::is_same_v<std::remove_cv_t<actual_element>,
147 std::remove_cv_t<parameter_element>> &&
148 std::is_convertible_v<typename actual_buffer::pointer, wire_element*>;
151 template <
typename Param,
typename Actual>
155 template <
auto Func,
typename ActualTuple, std::size_t... Indices>
160 std::tuple_element_t<Indices, ActualTuple>> &&
164 template <
auto Func,
typename... Actual>
167 if constexpr (
sizeof...(Actual) != KernelArityV<Func>)
174 std::make_index_sequence<KernelArityV<Func>>{});
178 template <
auto Func,
typename... Actual>
182 template <
auto Func,
typename... Actual>
186 template <
auto Func, std::size_t... Indices>
194 directions.
args = {KernelParamDirectionV<KernelParamT<Func, Indices>>...};
201 return MakeKernelDirections<Func>(std::make_index_sequence<KernelArityV<Func>>{});
209 inline ArgDir directionAt(
const std::vector<ArgDir>& directions, std::size_t index) noexcept
211 return index < directions.size() ? directions[index] :
ArgDir::InOut;
NDArray is a class that can be used in both host and device code. NDArray is automatically divided in...
ArgDirections MakeKernelDirections(std::index_sequence< Indices... >)
constexpr bool KernelArgumentCompatibleV
constexpr ArgDir KernelParamDirectionV
constexpr std::size_t KernelArityV
constexpr bool IsDirectionalKernelParamV
constexpr bool KernelArgumentsCompatibleV
std::enable_if_t< KernelArgumentsCompatibleV< Func, Actual... >, int > EnableCompatibleKernelArguments
constexpr bool KernelArgumentsCompatible(std::index_sequence< Indices... >)
std::tuple_element_t< Index, typename KernelFunctionTraits< decltype(Func)>::parameters > KernelParamT
std::vector< ArgDir > args
static constexpr bool valid
std::tuple< Args... > parameters
static constexpr ArgDir value