41#if defined(__CUDACC__)
60#include <domain_decomposition/BlockDataID.h>
70namespace ReactionKernelBulkSelector {
72template <
typename FloatType =
double, std::
size_t N = 1>
struct KernelTrait {
73 using ReactionKernelBulk = pystencils::ReactionKernelBulk_1_double_precision;
76template <>
struct KernelTrait<double, 2> {
77 using ReactionKernelBulk = pystencils::ReactionKernelBulk_2_double_precision;
80template <>
struct KernelTrait<double, 3> {
81 using ReactionKernelBulk = pystencils::ReactionKernelBulk_3_double_precision;
84template <>
struct KernelTrait<double, 4> {
85 using ReactionKernelBulk = pystencils::ReactionKernelBulk_4_double_precision;
88template <>
struct KernelTrait<double, 5> {
89 using ReactionKernelBulk = pystencils::ReactionKernelBulk_5_double_precision;
92template <>
struct KernelTrait<float, 1> {
93 using ReactionKernelBulk = pystencils::ReactionKernelBulk_1_single_precision;
96template <>
struct KernelTrait<float, 2> {
97 using ReactionKernelBulk = pystencils::ReactionKernelBulk_2_single_precision;
100template <>
struct KernelTrait<float, 3> {
101 using ReactionKernelBulk = pystencils::ReactionKernelBulk_3_single_precision;
104template <>
struct KernelTrait<float, 4> {
105 using ReactionKernelBulk = pystencils::ReactionKernelBulk_4_single_precision;
108template <>
struct KernelTrait<float, 5> {
109 using ReactionKernelBulk = pystencils::ReactionKernelBulk_5_single_precision;
112template <
typename FloatType,
class Reactant, std::size_t... ints>
113auto get_kernel_impl(
const std::vector<std::shared_ptr<Reactant>> &reactants,
114 const double coefficient,
115 std::index_sequence<ints...> int_seq) {
116 auto kernel = std::make_shared<
117 typename KernelTrait<FloatType, int_seq.size()>::ReactionKernelBulk>(
118 walberla::BlockDataID(
119 reactants[ints]->get_species()->get_density_id())...,
120 numeric_cast<FloatType>(reactants[ints]->get_order())...,
121 numeric_cast<FloatType>(coefficient),
122 numeric_cast<FloatType>(reactants[ints]->get_stoech_coeff())...);
124 std::function<void(IBlock *)> sweep = [kernel](IBlock *b) { kernel->run(b); };
128template <
typename FloatType,
class Reactant,
class... Args>
129auto get_kernel_impl(
const std::vector<std::shared_ptr<Reactant>> &reactants,
131 switch (reactants.size()) {
134 return get_kernel_impl<FloatType>(reactants, args...,
135 std::make_index_sequence<1>{});
138 return get_kernel_impl<FloatType>(reactants, args...,
139 std::make_index_sequence<2>{});
142 return get_kernel_impl<FloatType>(reactants, args...,
143 std::make_index_sequence<3>{});
146 return get_kernel_impl<FloatType>(reactants, args...,
147 std::make_index_sequence<4>{});
150 return get_kernel_impl<FloatType>(reactants, args...,
151 std::make_index_sequence<5>{});
154 throw std::runtime_error(
"reactions of this size are not implemented!");
158template <
class Reactant,
class... Args>
159auto get_kernel(
const std::vector<std::shared_ptr<Reactant>> &reactants,
162 const auto is_double_precision =
163 reactants[0]->get_species()->is_double_precision();
165 if (is_double_precision) {
166 return get_kernel_impl<double>(reactants, args...);
169 return get_kernel_impl<float>(reactants, args...);
172#if defined(__CUDACC__)
174template <
typename FloatType =
double, std::
size_t N = 1>
175struct KernelTraitGPU {
176 using ReactionKernelBulkGPU =
177 pystencils::ReactionKernelBulk_1_double_precision_CUDA;
180template <>
struct KernelTraitGPU<double, 2> {
181 using ReactionKernelBulkGPU =
182 pystencils::ReactionKernelBulk_2_double_precision_CUDA;
185template <>
struct KernelTraitGPU<double, 3> {
186 using ReactionKernelBulkGPU =
187 pystencils::ReactionKernelBulk_3_double_precision_CUDA;
190template <>
struct KernelTraitGPU<double, 4> {
191 using ReactionKernelBulkGPU =
192 pystencils::ReactionKernelBulk_4_double_precision_CUDA;
195template <>
struct KernelTraitGPU<double, 5> {
196 using ReactionKernelBulkGPU =
197 pystencils::ReactionKernelBulk_5_double_precision_CUDA;
200template <>
struct KernelTraitGPU<float, 1> {
201 using ReactionKernelBulkGPU =
202 pystencils::ReactionKernelBulk_1_single_precision_CUDA;
205template <>
struct KernelTraitGPU<float, 2> {
206 using ReactionKernelBulkGPU =
207 pystencils::ReactionKernelBulk_2_single_precision_CUDA;
210template <>
struct KernelTraitGPU<float, 3> {
211 using ReactionKernelBulkGPU =
212 pystencils::ReactionKernelBulk_3_single_precision_CUDA;
215template <>
struct KernelTraitGPU<float, 4> {
216 using ReactionKernelBulkGPU =
217 pystencils::ReactionKernelBulk_4_single_precision_CUDA;
220template <>
struct KernelTraitGPU<float, 5> {
221 using ReactionKernelBulkGPU =
222 pystencils::ReactionKernelBulk_5_single_precision_CUDA;
225template <
typename FloatType,
class Reactant, std::size_t... ints>
226auto get_kernel_impl_gpu(
227 const std::vector<std::shared_ptr<Reactant>> &reactants,
228 const double coefficient, std::index_sequence<ints...> int_seq) {
229 auto kernel = std::make_shared<
typename KernelTraitGPU<
230 FloatType, int_seq.size()>::ReactionKernelBulkGPU>(
231 walberla::BlockDataID(
232 reactants[ints]->get_species()->get_density_id())...,
233 numeric_cast<FloatType>(reactants[ints]->get_order())...,
234 numeric_cast<FloatType>(coefficient),
235 numeric_cast<FloatType>(reactants[ints]->get_stoech_coeff())...);
237 std::function<void(IBlock *)> sweep = [kernel](IBlock *b) { kernel->run(b); };
241template <
typename FloatType,
class Reactant,
class... Args>
242auto get_kernel_impl_gpu(
243 const std::vector<std::shared_ptr<Reactant>> &reactants, Args... args) {
244 switch (reactants.size()) {
247 return get_kernel_impl_gpu<FloatType>(reactants, args...,
248 std::make_index_sequence<1>{});
251 return get_kernel_impl_gpu<FloatType>(reactants, args...,
252 std::make_index_sequence<2>{});
255 return get_kernel_impl_gpu<FloatType>(reactants, args...,
256 std::make_index_sequence<3>{});
259 return get_kernel_impl_gpu<FloatType>(reactants, args...,
260 std::make_index_sequence<4>{});
263 return get_kernel_impl_gpu<FloatType>(reactants, args...,
264 std::make_index_sequence<5>{});
267 throw std::runtime_error(
"reactions of this size are not implemented!");
271template <
class Reactant,
class... Args>
272auto get_kernel_gpu(
const std::vector<std::shared_ptr<Reactant>> &reactants,
275 const auto is_double_precision =
276 reactants[0]->get_species()->is_double_precision();
278 if (is_double_precision) {
279 return get_kernel_impl_gpu<double>(reactants, args...);
282 return get_kernel_impl_gpu<float>(reactants, args...);
\file PackInfoPdfDoublePrecision.cpp \author pystencils