26#include <waLBerlaDefinitions.h>
43#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
62#include <domain_decomposition/BlockDataID.h>
72namespace ReactionKernelIndexedSelector {
74template <
typename FloatType =
double, std::
size_t N = 1>
struct KernelTrait {
75 using ReactionKernelIndexed =
76 pystencils::ReactionKernelIndexed_1_double_precision;
79template <>
struct KernelTrait<double, 2> {
80 using ReactionKernelIndexed =
81 pystencils::ReactionKernelIndexed_2_double_precision;
84template <>
struct KernelTrait<double, 3> {
85 using ReactionKernelIndexed =
86 pystencils::ReactionKernelIndexed_3_double_precision;
89template <>
struct KernelTrait<double, 4> {
90 using ReactionKernelIndexed =
91 pystencils::ReactionKernelIndexed_4_double_precision;
94template <>
struct KernelTrait<double, 5> {
95 using ReactionKernelIndexed =
96 pystencils::ReactionKernelIndexed_5_double_precision;
99template <>
struct KernelTrait<float, 1> {
100 using ReactionKernelIndexed =
101 pystencils::ReactionKernelIndexed_1_single_precision;
104template <>
struct KernelTrait<float, 2> {
105 using ReactionKernelIndexed =
106 pystencils::ReactionKernelIndexed_2_single_precision;
109template <>
struct KernelTrait<float, 3> {
110 using ReactionKernelIndexed =
111 pystencils::ReactionKernelIndexed_3_single_precision;
114template <>
struct KernelTrait<float, 4> {
115 using ReactionKernelIndexed =
116 pystencils::ReactionKernelIndexed_4_single_precision;
119template <>
struct KernelTrait<float, 5> {
120 using ReactionKernelIndexed =
121 pystencils::ReactionKernelIndexed_5_single_precision;
124template <
typename FloatType,
class Reactant, std::size_t... ints>
125auto get_kernel_impl(
const std::vector<std::shared_ptr<Reactant>> &reactants,
126 const double coefficient,
const BlockDataID &indexFieldID,
127 std::index_sequence<ints...> int_seq) {
128 auto kernel = std::make_shared<
129 typename KernelTrait<FloatType, int_seq.size()>::ReactionKernelIndexed>(
131 walberla::BlockDataID(
132 reactants[ints]->get_species()->get_density_id())...,
133 numeric_cast<FloatType>(reactants[ints]->get_order())...,
134 numeric_cast<FloatType>(coefficient),
135 numeric_cast<FloatType>(reactants[ints]->get_stoech_coeff())...);
137 std::function<void(IBlock *)> sweep = [kernel](IBlock *b) { kernel->run(b); };
141template <
typename FloatType,
class Reactant,
class... Args>
142auto get_kernel_impl(
const std::vector<std::shared_ptr<Reactant>> &reactants,
144 switch (reactants.size()) {
147 return get_kernel_impl<FloatType>(reactants, args...,
148 std::make_index_sequence<1>{});
151 return get_kernel_impl<FloatType>(reactants, args...,
152 std::make_index_sequence<2>{});
155 return get_kernel_impl<FloatType>(reactants, args...,
156 std::make_index_sequence<3>{});
159 return get_kernel_impl<FloatType>(reactants, args...,
160 std::make_index_sequence<4>{});
163 return get_kernel_impl<FloatType>(reactants, args...,
164 std::make_index_sequence<5>{});
167 throw std::runtime_error(
"reactions of this size are not implemented!");
171template <
class Reactant,
class... Args>
172auto get_kernel(
const std::vector<std::shared_ptr<Reactant>> &reactants,
175 const auto is_double_precision =
176 reactants[0]->get_species()->is_double_precision();
178 if (is_double_precision) {
179 return get_kernel_impl<double>(reactants, args...);
182 return get_kernel_impl<float>(reactants, args...);
185#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
187template <
typename FloatType =
double, std::
size_t N = 1>
188struct KernelTraitGPU {
189 using ReactionKernelIndexedGPU =
190 pystencils::ReactionKernelIndexed_1_double_precision_CUDA;
193template <>
struct KernelTraitGPU<double, 2> {
194 using ReactionKernelIndexedGPU =
195 pystencils::ReactionKernelIndexed_2_double_precision_CUDA;
198template <>
struct KernelTraitGPU<double, 3> {
199 using ReactionKernelIndexedGPU =
200 pystencils::ReactionKernelIndexed_3_double_precision_CUDA;
203template <>
struct KernelTraitGPU<double, 4> {
204 using ReactionKernelIndexedGPU =
205 pystencils::ReactionKernelIndexed_4_double_precision_CUDA;
208template <>
struct KernelTraitGPU<double, 5> {
209 using ReactionKernelIndexedGPU =
210 pystencils::ReactionKernelIndexed_5_double_precision_CUDA;
213template <>
struct KernelTraitGPU<float, 1> {
214 using ReactionKernelIndexedGPU =
215 pystencils::ReactionKernelIndexed_1_single_precision_CUDA;
218template <>
struct KernelTraitGPU<float, 2> {
219 using ReactionKernelIndexedGPU =
220 pystencils::ReactionKernelIndexed_2_single_precision_CUDA;
223template <>
struct KernelTraitGPU<float, 3> {
224 using ReactionKernelIndexedGPU =
225 pystencils::ReactionKernelIndexed_3_single_precision_CUDA;
228template <>
struct KernelTraitGPU<float, 4> {
229 using ReactionKernelIndexedGPU =
230 pystencils::ReactionKernelIndexed_4_single_precision_CUDA;
233template <>
struct KernelTraitGPU<float, 5> {
234 using ReactionKernelIndexedGPU =
235 pystencils::ReactionKernelIndexed_5_single_precision_CUDA;
238template <
typename FloatType,
class Reactant, std::size_t... ints>
239auto get_kernel_impl_gpu(
240 const std::vector<std::shared_ptr<Reactant>> &reactants,
241 const double coefficient,
const BlockDataID &indexFieldID,
242 std::index_sequence<ints...> int_seq) {
243 auto kernel = std::make_shared<
typename KernelTraitGPU<
244 FloatType, int_seq.size()>::ReactionKernelIndexedGPU>(
246 walberla::BlockDataID(
247 reactants[ints]->get_species()->get_density_id())...,
248 numeric_cast<FloatType>(reactants[ints]->get_order())...,
249 numeric_cast<FloatType>(coefficient),
250 numeric_cast<FloatType>(reactants[ints]->get_stoech_coeff())...);
252 std::function<void(IBlock *)> sweep = [kernel](IBlock *b) { kernel->run(b); };
256template <
typename FloatType,
class Reactant,
class... Args>
257auto get_kernel_impl_gpu(
258 const std::vector<std::shared_ptr<Reactant>> &reactants, Args... args) {
259 switch (reactants.size()) {
262 return get_kernel_impl_gpu<FloatType>(reactants, args...,
263 std::make_index_sequence<1>{});
266 return get_kernel_impl_gpu<FloatType>(reactants, args...,
267 std::make_index_sequence<2>{});
270 return get_kernel_impl_gpu<FloatType>(reactants, args...,
271 std::make_index_sequence<3>{});
274 return get_kernel_impl_gpu<FloatType>(reactants, args...,
275 std::make_index_sequence<4>{});
278 return get_kernel_impl_gpu<FloatType>(reactants, args...,
279 std::make_index_sequence<5>{});
282 throw std::runtime_error(
"reactions of this size are not implemented!");
286template <
class Reactant,
class... Args>
287auto get_kernel_gpu(
const std::vector<std::shared_ptr<Reactant>> &reactants,
290 const auto is_double_precision =
291 reactants[0]->get_species()->is_double_precision();
293 if (is_double_precision) {
294 return get_kernel_impl_gpu<double>(reactants, args...);
297 return get_kernel_impl_gpu<float>(reactants, args...);
\file PackInfoPdfDoublePrecision.cpp \author pystencils