26#include <waLBerlaDefinitions.h>
43#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
62#include <domain_decomposition/BlockDataID.h>
72namespace ReactionKernelBulkSelector {
74template <
typename FloatType =
double, std::
size_t N = 1>
struct KernelTrait {
75 using ReactionKernelBulk = pystencils::ReactionKernelBulk_1_double_precision;
78template <>
struct KernelTrait<double, 2> {
79 using ReactionKernelBulk = pystencils::ReactionKernelBulk_2_double_precision;
82template <>
struct KernelTrait<double, 3> {
83 using ReactionKernelBulk = pystencils::ReactionKernelBulk_3_double_precision;
86template <>
struct KernelTrait<double, 4> {
87 using ReactionKernelBulk = pystencils::ReactionKernelBulk_4_double_precision;
90template <>
struct KernelTrait<double, 5> {
91 using ReactionKernelBulk = pystencils::ReactionKernelBulk_5_double_precision;
94template <>
struct KernelTrait<float, 1> {
95 using ReactionKernelBulk = pystencils::ReactionKernelBulk_1_single_precision;
98template <>
struct KernelTrait<float, 2> {
99 using ReactionKernelBulk = pystencils::ReactionKernelBulk_2_single_precision;
102template <>
struct KernelTrait<float, 3> {
103 using ReactionKernelBulk = pystencils::ReactionKernelBulk_3_single_precision;
106template <>
struct KernelTrait<float, 4> {
107 using ReactionKernelBulk = pystencils::ReactionKernelBulk_4_single_precision;
110template <>
struct KernelTrait<float, 5> {
111 using ReactionKernelBulk = pystencils::ReactionKernelBulk_5_single_precision;
114template <
typename FloatType,
class Reactant, std::size_t... ints>
115auto get_kernel_impl(
const std::vector<std::shared_ptr<Reactant>> &reactants,
116 const double coefficient,
117 std::index_sequence<ints...> int_seq) {
118 auto kernel = std::make_shared<
119 typename KernelTrait<FloatType, int_seq.size()>::ReactionKernelBulk>(
120 walberla::BlockDataID(
121 reactants[ints]->get_species()->get_density_id())...,
122 numeric_cast<FloatType>(reactants[ints]->get_order())...,
123 numeric_cast<FloatType>(coefficient),
124 numeric_cast<FloatType>(reactants[ints]->get_stoech_coeff())...);
126 std::function<void(IBlock *)> sweep = [kernel](IBlock *b) { kernel->run(b); };
130template <
typename FloatType,
class Reactant,
class... Args>
131auto get_kernel_impl(
const std::vector<std::shared_ptr<Reactant>> &reactants,
133 switch (reactants.size()) {
136 return get_kernel_impl<FloatType>(reactants, args...,
137 std::make_index_sequence<1>{});
140 return get_kernel_impl<FloatType>(reactants, args...,
141 std::make_index_sequence<2>{});
144 return get_kernel_impl<FloatType>(reactants, args...,
145 std::make_index_sequence<3>{});
148 return get_kernel_impl<FloatType>(reactants, args...,
149 std::make_index_sequence<4>{});
152 return get_kernel_impl<FloatType>(reactants, args...,
153 std::make_index_sequence<5>{});
156 throw std::runtime_error(
"reactions of this size are not implemented!");
160template <
class Reactant,
class... Args>
161auto get_kernel(
const std::vector<std::shared_ptr<Reactant>> &reactants,
164 const auto is_double_precision =
165 reactants[0]->get_species()->is_double_precision();
167 if (is_double_precision) {
168 return get_kernel_impl<double>(reactants, args...);
171 return get_kernel_impl<float>(reactants, args...);
174#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
176template <
typename FloatType =
double, std::
size_t N = 1>
177struct KernelTraitGPU {
178 using ReactionKernelBulkGPU =
179 pystencils::ReactionKernelBulk_1_double_precision_CUDA;
182template <>
struct KernelTraitGPU<double, 2> {
183 using ReactionKernelBulkGPU =
184 pystencils::ReactionKernelBulk_2_double_precision_CUDA;
187template <>
struct KernelTraitGPU<double, 3> {
188 using ReactionKernelBulkGPU =
189 pystencils::ReactionKernelBulk_3_double_precision_CUDA;
192template <>
struct KernelTraitGPU<double, 4> {
193 using ReactionKernelBulkGPU =
194 pystencils::ReactionKernelBulk_4_double_precision_CUDA;
197template <>
struct KernelTraitGPU<double, 5> {
198 using ReactionKernelBulkGPU =
199 pystencils::ReactionKernelBulk_5_double_precision_CUDA;
202template <>
struct KernelTraitGPU<float, 1> {
203 using ReactionKernelBulkGPU =
204 pystencils::ReactionKernelBulk_1_single_precision_CUDA;
207template <>
struct KernelTraitGPU<float, 2> {
208 using ReactionKernelBulkGPU =
209 pystencils::ReactionKernelBulk_2_single_precision_CUDA;
212template <>
struct KernelTraitGPU<float, 3> {
213 using ReactionKernelBulkGPU =
214 pystencils::ReactionKernelBulk_3_single_precision_CUDA;
217template <>
struct KernelTraitGPU<float, 4> {
218 using ReactionKernelBulkGPU =
219 pystencils::ReactionKernelBulk_4_single_precision_CUDA;
222template <>
struct KernelTraitGPU<float, 5> {
223 using ReactionKernelBulkGPU =
224 pystencils::ReactionKernelBulk_5_single_precision_CUDA;
227template <
typename FloatType,
class Reactant, std::size_t... ints>
228auto get_kernel_impl_gpu(
229 const std::vector<std::shared_ptr<Reactant>> &reactants,
230 const double coefficient, std::index_sequence<ints...> int_seq) {
231 auto kernel = std::make_shared<
typename KernelTraitGPU<
232 FloatType, int_seq.size()>::ReactionKernelBulkGPU>(
233 walberla::BlockDataID(
234 reactants[ints]->get_species()->get_density_id())...,
235 numeric_cast<FloatType>(reactants[ints]->get_order())...,
236 numeric_cast<FloatType>(coefficient),
237 numeric_cast<FloatType>(reactants[ints]->get_stoech_coeff())...);
239 std::function<void(IBlock *)> sweep = [kernel](IBlock *b) { kernel->run(b); };
243template <
typename FloatType,
class Reactant,
class... Args>
244auto get_kernel_impl_gpu(
245 const std::vector<std::shared_ptr<Reactant>> &reactants, Args... args) {
246 switch (reactants.size()) {
249 return get_kernel_impl_gpu<FloatType>(reactants, args...,
250 std::make_index_sequence<1>{});
253 return get_kernel_impl_gpu<FloatType>(reactants, args...,
254 std::make_index_sequence<2>{});
257 return get_kernel_impl_gpu<FloatType>(reactants, args...,
258 std::make_index_sequence<3>{});
261 return get_kernel_impl_gpu<FloatType>(reactants, args...,
262 std::make_index_sequence<4>{});
265 return get_kernel_impl_gpu<FloatType>(reactants, args...,
266 std::make_index_sequence<5>{});
269 throw std::runtime_error(
"reactions of this size are not implemented!");
273template <
class Reactant,
class... Args>
274auto get_kernel_gpu(
const std::vector<std::shared_ptr<Reactant>> &reactants,
277 const auto is_double_precision =
278 reactants[0]->get_species()->is_double_precision();
280 if (is_double_precision) {
281 return get_kernel_impl_gpu<double>(reactants, args...);
284 return get_kernel_impl_gpu<float>(reactants, args...);
\file PackInfoPdfDoublePrecision.cpp \author pystencils