12#ifndef MFEM_KERNEL_DISPATCH_HPP
13#define MFEM_KERNEL_DISPATCH_HPP
18#include <unordered_map>
47#define MFEM_EXPAND(X) X
49#define MFEM_REGISTER_KERNELS(KernelName, KernelType, ...) \
50 MFEM_EXPAND(MFEM_EXPAND(MFEM_REGISTER_KERNELS_N(__VA_ARGS__,2,1,)) \
51 (KernelName,KernelType,__VA_ARGS__))
53#define MFEM_REGISTER_KERNELS_N(_1, _2, N, ...) MFEM_REGISTER_KERNELS_##N
57#define MFEM_PARAM_LIST(...) __VA_ARGS__
61#define MFEM_REGISTER_KERNELS_1(KernelName, KernelType, Params) \
62 MFEM_REGISTER_KERNELS_(KernelName, KernelType, Params, (), Params)
66#define MFEM_REGISTER_KERNELS_2(KernelName, KernelType, Params, OptParams) \
67 MFEM_REGISTER_KERNELS_(KernelName, KernelType, Params, OptParams, \
68 (MFEM_PARAM_LIST Params, MFEM_PARAM_LIST OptParams))
73#define MFEM_REGISTER_KERNELS_(KernelName, KernelType, P1, P2, P3) \
75 : public ::mfem::KernelDispatchTable< \
76 KernelName, KernelType, \
77 ::mfem::internal::KernelTypeList<MFEM_PARAM_LIST P1>, \
78 ::mfem::internal::KernelTypeList<MFEM_PARAM_LIST P2>> { \
80 const char *kernel_name = MFEM_KERNEL_NAME(KernelName); \
81 using KernelSignature = KernelType; \
82 template <MFEM_PARAM_LIST P3> static KernelSignature Kernel(); \
83 static MFEM_EXPORT KernelSignature Fallback(MFEM_PARAM_LIST P1); \
84 static MFEM_EXPORT KernelName &Get() { \
85 static KernelName table; \
90namespace internal {
template<
typename... Types>
struct KernelTypeList { }; }
97 typename... OptParams>
100 internal::KernelTypeList<Params...>,
101 internal::KernelTypeList<OptParams...>>
104 std::unordered_map<std::tuple<Params...>, Signature,
TupleHasher>;
110 template <
typename F,
typename... Args,
111 typename std::enable_if<std::is_pointer<F>::value,
bool>::type=
true>
112 static void Invoke(F
f, Args&&... args)
114 f(std::forward<Args>(args)...);
121 template <
typename F,
typename T,
typename... Args,
122 typename std::enable_if<
123 std::is_member_function_pointer<F>::value,
bool>::type=
true>
124 static void Invoke(F
f, T&& t, Args&&... args)
126 (t.*
f)(std::forward<Args>(args)...);
138 template<
typename... Args>
139 static void Run(Params... params, Args&&... args)
141 const auto &table = Kernels::Get().table;
142 const std::tuple<Params...> key = std::make_tuple(params...);
143 const auto it = table.find(key);
144 if (it != table.end())
146 Invoke(it->second, std::forward<Args>(args)...);
151 Invoke(Kernels::Fallback(params...), std::forward<Args>(args)...);
156 template <Params... PARAMS>
162 std::tuple<Params...> param_tuple(PARAMS...);
163 Kernels::Get().table[param_tuple] =
164 Kernels:: template Kernel<PARAMS..., OptParams{}...>();
167 template <OptParams... OPT_PARAMS>
172 std::tuple<Params...> param_tuple(PARAMS...);
173 Kernels::Get().table[param_tuple] =
174 Kernels:: template Kernel<PARAMS..., OPT_PARAMS...>();
182 return Kernels::Get().table;
static void Run(Params... params, Args &&... args)
Run the kernel with the given dispatch parameters and arguments.
static const TableType & GetDispatchTable()
Return the dispatch map table.
static void ReportFallback(const std::string &kernel_name, Params &&... params)
Report the fallback kernel with given parameters.
SchrodingerBaseKernels< ParMesh, ParFiniteElementSpace, ParComplexGridFunction, ParGridFunction, ParBilinearForm, ParMixedBilinearForm, ParLinearForm > Kernels
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Register a specialized kernel for dispatch.
Base class for Schrodinger solver kernels.
Helper class for hashing std::tuple of hashable types.