41#if defined(__CUDACC__)
60#include <domain_decomposition/BlockDataID.h>
70namespace ReactionKernelIndexedSelector {
72template <
typename FloatType =
double, std::
size_t N = 1>
struct KernelTrait {
73 using ReactionKernelIndexed =
74 pystencils::ReactionKernelIndexed_1_double_precision;
77template <>
struct KernelTrait<double, 2> {
78 using ReactionKernelIndexed =
79 pystencils::ReactionKernelIndexed_2_double_precision;
82template <>
struct KernelTrait<double, 3> {
83 using ReactionKernelIndexed =
84 pystencils::ReactionKernelIndexed_3_double_precision;
87template <>
struct KernelTrait<double, 4> {
88 using ReactionKernelIndexed =
89 pystencils::ReactionKernelIndexed_4_double_precision;
92template <>
struct KernelTrait<double, 5> {
93 using ReactionKernelIndexed =
94 pystencils::ReactionKernelIndexed_5_double_precision;
97template <>
struct KernelTrait<float, 1> {
98 using ReactionKernelIndexed =
99 pystencils::ReactionKernelIndexed_1_single_precision;
102template <>
struct KernelTrait<float, 2> {
103 using ReactionKernelIndexed =
104 pystencils::ReactionKernelIndexed_2_single_precision;
107template <>
struct KernelTrait<float, 3> {
108 using ReactionKernelIndexed =
109 pystencils::ReactionKernelIndexed_3_single_precision;
112template <>
struct KernelTrait<float, 4> {
113 using ReactionKernelIndexed =
114 pystencils::ReactionKernelIndexed_4_single_precision;
117template <>
struct KernelTrait<float, 5> {
118 using ReactionKernelIndexed =
119 pystencils::ReactionKernelIndexed_5_single_precision;
122template <
typename FloatType,
class Reactant, std::size_t... ints>
123auto get_kernel_impl(
const std::vector<std::shared_ptr<Reactant>> &reactants,
124 const double coefficient,
const BlockDataID &indexFieldID,
125 std::index_sequence<ints...> int_seq) {
126 auto kernel = std::make_shared<
127 typename KernelTrait<FloatType, int_seq.size()>::ReactionKernelIndexed>(
129 walberla::BlockDataID(
130 reactants[ints]->get_species()->get_density_id())...,
131 numeric_cast<FloatType>(reactants[ints]->get_order())...,
132 numeric_cast<FloatType>(coefficient),
133 numeric_cast<FloatType>(reactants[ints]->get_stoech_coeff())...);
135 std::function<void(IBlock *)> sweep = [kernel](IBlock *b) { kernel->run(b); };
139template <
typename FloatType,
class Reactant,
class... Args>
140auto get_kernel_impl(
const std::vector<std::shared_ptr<Reactant>> &reactants,
142 switch (reactants.size()) {
145 return get_kernel_impl<FloatType>(reactants, args...,
146 std::make_index_sequence<1>{});
149 return get_kernel_impl<FloatType>(reactants, args...,
150 std::make_index_sequence<2>{});
153 return get_kernel_impl<FloatType>(reactants, args...,
154 std::make_index_sequence<3>{});
157 return get_kernel_impl<FloatType>(reactants, args...,
158 std::make_index_sequence<4>{});
161 return get_kernel_impl<FloatType>(reactants, args...,
162 std::make_index_sequence<5>{});
165 throw std::runtime_error(
"reactions of this size are not implemented!");
169template <
class Reactant,
class... Args>
170auto get_kernel(
const std::vector<std::shared_ptr<Reactant>> &reactants,
173 const auto is_double_precision =
174 reactants[0]->get_species()->is_double_precision();
176 if (is_double_precision) {
177 return get_kernel_impl<double>(reactants, args...);
180 return get_kernel_impl<float>(reactants, args...);
183#if defined(__CUDACC__)
185template <
typename FloatType =
double, std::
size_t N = 1>
186struct KernelTraitGPU {
187 using ReactionKernelIndexedGPU =
188 pystencils::ReactionKernelIndexed_1_double_precision_CUDA;
191template <>
struct KernelTraitGPU<double, 2> {
192 using ReactionKernelIndexedGPU =
193 pystencils::ReactionKernelIndexed_2_double_precision_CUDA;
196template <>
struct KernelTraitGPU<double, 3> {
197 using ReactionKernelIndexedGPU =
198 pystencils::ReactionKernelIndexed_3_double_precision_CUDA;
201template <>
struct KernelTraitGPU<double, 4> {
202 using ReactionKernelIndexedGPU =
203 pystencils::ReactionKernelIndexed_4_double_precision_CUDA;
206template <>
struct KernelTraitGPU<double, 5> {
207 using ReactionKernelIndexedGPU =
208 pystencils::ReactionKernelIndexed_5_double_precision_CUDA;
211template <>
struct KernelTraitGPU<float, 1> {
212 using ReactionKernelIndexedGPU =
213 pystencils::ReactionKernelIndexed_1_single_precision_CUDA;
216template <>
struct KernelTraitGPU<float, 2> {
217 using ReactionKernelIndexedGPU =
218 pystencils::ReactionKernelIndexed_2_single_precision_CUDA;
221template <>
struct KernelTraitGPU<float, 3> {
222 using ReactionKernelIndexedGPU =
223 pystencils::ReactionKernelIndexed_3_single_precision_CUDA;
226template <>
struct KernelTraitGPU<float, 4> {
227 using ReactionKernelIndexedGPU =
228 pystencils::ReactionKernelIndexed_4_single_precision_CUDA;
231template <>
struct KernelTraitGPU<float, 5> {
232 using ReactionKernelIndexedGPU =
233 pystencils::ReactionKernelIndexed_5_single_precision_CUDA;
236template <
typename FloatType,
class Reactant, std::size_t... ints>
237auto get_kernel_impl_gpu(
238 const std::vector<std::shared_ptr<Reactant>> &reactants,
239 const double coefficient,
const BlockDataID &indexFieldID,
240 std::index_sequence<ints...> int_seq) {
241 auto kernel = std::make_shared<
typename KernelTraitGPU<
242 FloatType, int_seq.size()>::ReactionKernelIndexedGPU>(
244 walberla::BlockDataID(
245 reactants[ints]->get_species()->get_density_id())...,
246 numeric_cast<FloatType>(reactants[ints]->get_order())...,
247 numeric_cast<FloatType>(coefficient),
248 numeric_cast<FloatType>(reactants[ints]->get_stoech_coeff())...);
250 std::function<void(IBlock *)> sweep = [kernel](IBlock *b) { kernel->run(b); };
254template <
typename FloatType,
class Reactant,
class... Args>
255auto get_kernel_impl_gpu(
256 const std::vector<std::shared_ptr<Reactant>> &reactants, Args... args) {
257 switch (reactants.size()) {
260 return get_kernel_impl_gpu<FloatType>(reactants, args...,
261 std::make_index_sequence<1>{});
264 return get_kernel_impl_gpu<FloatType>(reactants, args...,
265 std::make_index_sequence<2>{});
268 return get_kernel_impl_gpu<FloatType>(reactants, args...,
269 std::make_index_sequence<3>{});
272 return get_kernel_impl_gpu<FloatType>(reactants, args...,
273 std::make_index_sequence<4>{});
276 return get_kernel_impl_gpu<FloatType>(reactants, args...,
277 std::make_index_sequence<5>{});
280 throw std::runtime_error(
"reactions of this size are not implemented!");
284template <
class Reactant,
class... Args>
285auto get_kernel_gpu(
const std::vector<std::shared_ptr<Reactant>> &reactants,
288 const auto is_double_precision =
289 reactants[0]->get_species()->is_double_precision();
291 if (is_double_precision) {
292 return get_kernel_impl_gpu<double>(reactants, args...);
295 return get_kernel_impl_gpu<float>(reactants, args...);
\file PackInfoPdfDoublePrecision.cpp \author pystencils