GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/parallel/parallel_for.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 7 7 100.0%
Functions: 605 837 72.3%
Branches: 0 0 -%

Line Branch Exec Source
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 //
4 // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7
8 /*!
9 * \file
10 * \ingroup Parallel
11 * \brief Parallel for loop (multithreading)
12 */
13
14 #ifndef DUMUX_PARALLEL_PARALLEL_FOR_HH
15 #define DUMUX_PARALLEL_PARALLEL_FOR_HH
16
17 #include <dumux/parallel/multithreading.hh>
18
19 #if DUMUX_HAVE_CPP_PARALLEL_ALGORITHMS
20 #include <algorithm>
21 #include <execution>
22 #include <dune/common/rangeutilities.hh>
23 #endif
24
25 #if HAVE_TBB
26 #include <tbb/parallel_for.h>
27 #endif
28
29 #if DUMUX_HAVE_KOKKOS
30 #include <Kokkos_Core.hpp>
31 #endif
32
33 // contents of the detail namespace might change
34 // any time without prior notice (do not use directly)
35 #ifndef DOXYGEN // hide from doxygen
36 namespace Dumux::Detail {
37
38 // This should be specialized for different ExecutionBackends
39 template<class FunctorType, class ExecutionBackend>
40 class ParallelFor;
41
42
43 // Serial backend implementation
44 template<class FunctorType>
45 class ParallelFor<FunctorType, Multithreading::ExecutionBackends::Serial>
46 {
47 public:
48 ParallelFor(const std::size_t count, const FunctorType& functor)
49 : functor_(functor), count_(count) {}
50
51 void execute() const
52 {
53 for (std::size_t i = 0; i < count_; ++i)
54 functor_(i);
55 }
56
57 private:
58 FunctorType functor_;
59 std::size_t count_;
60 };
61
62 #if DUMUX_HAVE_CPP_PARALLEL_ALGORITHMS
63 // C++ parallel algorithms backend implementation
64 template<class FunctorType>
65 class ParallelFor<FunctorType, Multithreading::ExecutionBackends::Cpp>
66 {
67 public:
68 ParallelFor(const std::size_t count, const FunctorType& functor)
69 : functor_(functor), range_(count) {}
70
71 void execute() const
72 {
73 std::for_each(std::execution::par_unseq, range_.begin(), range_.end(), functor_);
74 }
75
76 private:
77 FunctorType functor_;
78 Dune::IntegralRange<std::size_t> range_;
79 };
80 #endif
81
82
83 #if HAVE_TBB
84 // TBB backend implementation
85 template<class FunctorType>
86 class ParallelFor<FunctorType, Multithreading::ExecutionBackends::TBB>
87 {
88 public:
89 ParallelFor(const std::size_t count, const FunctorType& functor)
90 : functor_(functor), count_(count) {}
91
92 void execute() const
93 {
94 tbb::parallel_for(std::size_t{0}, count_, [&](const std::size_t i){ functor_(i); });
95 }
96
97 private:
98 FunctorType functor_;
99 std::size_t count_;
100 };
101 #endif // HAVE_TBB
102
103 #if DUMUX_HAVE_KOKKOS
104 // Kokkos backend implementation
105 template<class FunctorType>
106 class ParallelFor<FunctorType, Multithreading::ExecutionBackends::Kokkos>
107 {
108 public:
109 ParallelFor(const std::size_t count, const FunctorType& functor)
110 : functor_(functor), count_(count) {}
111
112 void execute() const
113 {
114 Kokkos::parallel_for(count_, [&](const std::size_t i){ functor_(i); });
115 }
116
117 private:
118 FunctorType functor_;
119 std::size_t count_;
120 };
121 #endif // DUMUX_HAVE_KOKKOS
122
123
124 #if DUMUX_HAVE_OPENMP
125 // OpenMP backend implementation
126 template<class FunctorType>
127 class ParallelFor<FunctorType, Multithreading::ExecutionBackends::OpenMP>
128 {
129 public:
130 1126608 ParallelFor(const std::size_t count, const FunctorType& functor)
131 1126608 : functor_(functor), count_(count) {}
132
133 void execute() const
134 {
135 1126608 #pragma omp parallel for
136 for (std::size_t i = 0; i < count_; ++i)
137 functor_(i);
138 }
139
140 private:
141 FunctorType functor_;
142 std::size_t count_;
143 };
144 #endif // DUMUX_HAVE_OPENMP
145
146
147 } // end namespace Detail
148 #endif // DOXYGEN
149
150
151 namespace Dumux {
152
153 /*!
154 * \ingroup Parallel
155 * \brief A parallel for loop (multithreading)
156 * \param count the number of work tasks to perform
157 * \param functor functor executed for each task (get task number as argument)
158 */
159 template<class FunctorType>
160 2252787 inline void parallelFor(const std::size_t count, const FunctorType& functor)
161 {
162 using ExecutionBackend = Detail::Multithreading::ExecutionBackend;
163 4505936 Detail::ParallelFor<FunctorType, ExecutionBackend> action(count, functor);
164 4505755 action.execute();
165 2252787 }
166
167 } // end namespace Dumux
168
169 #endif
170