46 inline void cpu_simd_loop(
const std::string ®ion_name [[maybe_unused]],
48 const unsigned int left,
49 const unsigned int internal,
50 const unsigned int right,
53 Assert(left <= internal && internal <= right,
54 dealii::ExcMessage(
"Invalid index range: it must hold left <= "
55 "internal, internal <= right"));
57 if (!region_name.empty()) {
61 using VA = dealii::VectorizedArray<ScalarNumber>;
63 constexpr unsigned int stride_size = get_stride_size<VA>;
64 const unsigned int regular =
65 left + (internal - left) / stride_size * stride_size;
67#if defined(WITH_OPENMP)
74 for (
unsigned int i = left; i < regular; i += stride_size)
75 body(VA(), std::forward<Args>(args)..., i);
79 for (
unsigned int i = regular; i < right; i += 1)
80 body(ScalarNumber(), std::forward<Args>(args)..., i);
83#elif defined(WITH_DEAL_II_THREADS)
90 Assert((regular - left) % stride_size == 0, dealii::ExcInternalError());
91 dealii::parallel::apply_to_subranges(
93 (regular - left) / stride_size,
94 [&](
const unsigned int begin,
const unsigned int end) {
96 for (
unsigned int i = begin; i < end; ++i)
97 body(VA(), std::forward<Args>(args)..., left + stride_size * i);
101 dealii::parallel::apply_to_subranges(
104 [&](
const unsigned int begin,
const unsigned int end) {
106 for (
unsigned int i = begin; i < end; ++i)
107 body(ScalarNumber(), std::forward<Args>(args)..., i);
116 for (
unsigned int i = left; i < regular; i += stride_size)
117 body(VA(), std::forward<Args>(args)..., i);
120 for (
unsigned int i = regular; i < right; i += 1)
121 body(ScalarNumber(), std::forward<Args>(args)..., i);
125 if (!region_name.empty()) {
156 inline void gpu_loop(
const std::string ®ion_name,
158 const unsigned int left,
159 const unsigned int internal [[maybe_unused]],
160 const unsigned int right,
165 Assert(left <= internal && internal <= right,
166 dealii::ExcMessage(
"Invalid index range: it must hold left <= "
167 "internal, internal <= right"));
169 using MemorySpace = dealii::MemorySpace::Default;
170 using ExecutionSpace =
typename MemorySpace::kokkos_space::execution_space;
172 Kokkos::RangePolicy<ExecutionSpace, Kokkos::IndexType<unsigned int>>;
174 const auto exec = ExecutionSpace{};
181 const auto packed_args = std::make_tuple(std::forward<Args>(args)...);
183 if (!region_name.empty()) {
187 Kokkos::parallel_for(
189 Policy(exec, left, right),
190 KOKKOS_LAMBDA(
const unsigned int i) {
192 [&](
const auto &...unpacked) {
193 body(ScalarNumber(), unpacked..., i);
200 if (!region_name.empty()) {
221 inline void loop(
const std::string ®ion_name,
223 const unsigned int left,
224 const unsigned int internal,
225 const unsigned int right,
228 using HostSpace = dealii::MemorySpace::Host;
229 using DefaultSpace = dealii::MemorySpace::Default;
230 static_assert(std::is_same_v<MemorySpace, HostSpace> ||
231 std::is_same_v<MemorySpace, DefaultSpace>,
232 "Unexpected memory space");
234 if constexpr (std::is_same_v<MemorySpace, HostSpace>) {
235 cpu_simd_loop<ScalarNumber>(region_name,
240 std::forward<Args>(args)...);
242 gpu_loop<ScalarNumber>(region_name,
247 std::forward<Args>(args)...);
273 const typename Reducer::value_type initial_value,
274 const unsigned int left,
275 const unsigned int right,
280 dealii::ExcMessage(
"Invalid index range: it must hold left <= right"));
282 if (!region_name.empty()) {
286 using ValueType =
typename Reducer::value_type;
288 ValueType result = initial_value;
290#if defined(WITH_OPENMP)
295 ValueType local_result;
296 Reducer(local_result).init(local_result);
299 for (
unsigned int i = left; i < right; ++i)
300 body(ValueType(), std::forward<Args>(args)..., i, local_result);
303 Reducer(result).join(result, local_result);
306#elif defined(WITH_DEAL_II_THREADS)
311 dealii::parallel::apply_to_subranges(
314 [&](
const unsigned int begin,
const unsigned int end) {
315 ValueType local_result;
316 Reducer(local_result).init(local_result);
318 for (
unsigned int i = begin; i < end; ++i)
319 body(ValueType(), std::forward<Args>(args)..., i, local_result);
321 std::lock_guard<std::mutex> lock(mutex);
322 Reducer(result).join(result, local_result);
330 for (
unsigned int i = left; i < right; ++i)
331 body(ValueType(), std::forward<Args>(args)..., i, result);
335 if (!region_name.empty()) {
367 const typename Reducer::value_type initial_value,
368 const unsigned int left,
369 const unsigned int right,
376 dealii::ExcMessage(
"Invalid index range: it must hold left <= right"));
378 using ValueType =
typename Reducer::value_type;
379 using MemorySpace = dealii::MemorySpace::Default;
380 using ExecutionSpace =
typename MemorySpace::kokkos_space::execution_space;
382 Kokkos::RangePolicy<ExecutionSpace, Kokkos::IndexType<unsigned int>>;
384 const auto exec = ExecutionSpace{};
393 const auto packed_args = std::make_tuple(std::forward<Args>(args)...);
395 if (!region_name.empty()) {
399 Kokkos::parallel_reduce(
401 Policy(exec, left, right),
402 KOKKOS_LAMBDA(
const unsigned int i, ValueType &local_result) {
404 [&](
const auto &...unpacked) {
405 body(ValueType(), unpacked..., i, local_result);
411 if (!region_name.empty()) {
415 ValueType combined = initial_value;
416 Reducer(combined).join(combined, result);
452 const typename Reducer::value_type initial_value,
453 const unsigned int left,
454 const unsigned int right,
457 using HostSpace = dealii::MemorySpace::Host;
458 using DefaultSpace = dealii::MemorySpace::Default;
459 static_assert(std::is_same_v<MemorySpace, HostSpace> ||
460 std::is_same_v<MemorySpace, DefaultSpace>,
461 "Unexpected memory space");
463 if constexpr (std::is_same_v<MemorySpace, HostSpace>) {
464 return cpu_reduction_loop<Reducer>(region_name,
469 std::forward<Args>(args)...);
471 return gpu_reduction_loop<Reducer>(region_name,
476 std::forward<Args>(args)...);
Reducer::value_type reduction_loop(const std::string ®ion_name, const Functor &body, const typename Reducer::value_type initial_value, const unsigned int left, const unsigned int right, Args &&...args)
Reducer::value_type cpu_reduction_loop(const std::string ®ion_name, const Functor &body, const typename Reducer::value_type initial_value, const unsigned int left, const unsigned int right, Args &&...args)
void gpu_loop(const std::string ®ion_name, const Functor &body, const unsigned int left, const unsigned int internal, const unsigned int right, Args &&...args)
void loop(const std::string ®ion_name, const Functor &body, const unsigned int left, const unsigned int internal, const unsigned int right, Args &&...args)
Reducer::value_type gpu_reduction_loop(const std::string ®ion_name, const Functor &body, const typename Reducer::value_type initial_value, const unsigned int left, const unsigned int right, Args &&...args)
void cpu_simd_loop(const std::string ®ion_name, const Functor &body, const unsigned int left, const unsigned int internal, const unsigned int right, Args &&...args)