Reference documentation for deal.II version 9.4.1
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
parallel.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2008 - 2022 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
16#ifndef dealii_parallel_h
17#define dealii_parallel_h
18
19
20#include <deal.II/base/config.h>
21
26
27#include <cstddef>
28#include <functional>
29#include <memory>
30#include <tuple>
31
32#ifdef DEAL_II_WITH_TBB
34# include <tbb/blocked_range.h>
35# include <tbb/parallel_for.h>
36# include <tbb/parallel_reduce.h>
37# include <tbb/partitioner.h>
39#endif
40
41
42// TODO[WB]: allow calling functions to pass along a tbb::affinity_partitioner
43// object to ensure that subsequent calls use the same cache lines
44
46
47namespace parallel
48{
49 namespace internal
50 {
55 template <typename Number>
57 {
58 static const bool value = true;
59 };
60
61#ifdef __INTEL_COMPILER
62 // Disable long double SIMD instructions on ICC. This is to work around a
63 // bug that generates wrong code at least up to intel 15 (see
64 // tests/lac/vector-vector, tests/lac/intel-15-bug, and the discussion at
65 // https://github.com/dealii/dealii/issues/598).
66 template <>
67 struct EnableOpenMPSimdFor<long double>
68 {
69 static const bool value = false;
70 };
71#endif
72
73
74#ifdef DEAL_II_WITH_TBB
78 template <typename Iterator, typename Functor>
79 void
80 parallel_for(Iterator x_begin,
81 Iterator x_end,
82 const Functor & functor,
83 const unsigned int grainsize)
84 {
85 tbb::parallel_for(tbb::blocked_range<Iterator>(x_begin, x_end, grainsize),
86 functor,
87 tbb::auto_partitioner());
88 }
89
90
91
95 template <typename Iterator, typename Functor>
96 void
97 parallel_for(Iterator x_begin,
98 Iterator x_end,
99 const Functor & functor,
100 const unsigned int grainsize,
101 const std::shared_ptr<tbb::affinity_partitioner> &partitioner)
102 {
103 tbb::parallel_for(tbb::blocked_range<Iterator>(x_begin, x_end, grainsize),
104 functor,
105 *partitioner);
106 }
107#endif
108 } // namespace internal
109
133 template <typename InputIterator, typename OutputIterator, typename Predicate>
134 void
135 transform(const InputIterator &begin_in,
136 const InputIterator &end_in,
137 OutputIterator out,
138 const Predicate & predicate,
139 const unsigned int grainsize)
140 {
141#ifndef DEAL_II_WITH_TBB
142 // make sure we don't get compiler
143 // warnings about unused arguments
144 (void)grainsize;
145
146 for (OutputIterator in = begin_in; in != end_in;)
147 *out++ = predicate(*in++);
148#else
149 using Iterators = std::tuple<InputIterator, OutputIterator>;
150 using SyncIterators = SynchronousIterators<Iterators>;
151 Iterators x_begin(begin_in, out);
152 Iterators x_end(end_in, OutputIterator());
154 SyncIterators(x_begin),
155 SyncIterators(x_end),
156 [predicate](const auto &range) {
157 for (const auto &p : range)
158 *std::get<1>(p) = predicate(*std::get<0>(p));
159 },
160 grainsize);
161#endif
162 }
163
164
165
189 template <typename InputIterator1,
190 typename InputIterator2,
191 typename OutputIterator,
192 typename Predicate>
193 void
194 transform(const InputIterator1 &begin_in1,
195 const InputIterator1 &end_in1,
196 InputIterator2 in2,
197 OutputIterator out,
198 const Predicate & predicate,
199 const unsigned int grainsize)
200 {
201#ifndef DEAL_II_WITH_TBB
202 // make sure we don't get compiler
203 // warnings about unused arguments
204 (void)grainsize;
205
206 for (OutputIterator in1 = begin_in1; in1 != end_in1;)
207 *out++ = predicate(*in1++, *in2++);
208#else
209 using Iterators =
210 std::tuple<InputIterator1, InputIterator2, OutputIterator>;
211 using SyncIterators = SynchronousIterators<Iterators>;
212 Iterators x_begin(begin_in1, in2, out);
213 Iterators x_end(end_in1, InputIterator2(), OutputIterator());
215 SyncIterators(x_begin),
216 SyncIterators(x_end),
217 [predicate](const auto &range) {
218 for (const auto &p : range)
219 *std::get<2>(p) = predicate(*std::get<0>(p), *std::get<1>(p));
220 },
221 grainsize);
222#endif
223 }
224
225
226
250 template <typename InputIterator1,
251 typename InputIterator2,
252 typename InputIterator3,
253 typename OutputIterator,
254 typename Predicate>
255 void
256 transform(const InputIterator1 &begin_in1,
257 const InputIterator1 &end_in1,
258 InputIterator2 in2,
259 InputIterator3 in3,
260 OutputIterator out,
261 const Predicate & predicate,
262 const unsigned int grainsize)
263 {
264#ifndef DEAL_II_WITH_TBB
265 // make sure we don't get compiler
266 // warnings about unused arguments
267 (void)grainsize;
268
269 for (OutputIterator in1 = begin_in1; in1 != end_in1;)
270 *out++ = predicate(*in1++, *in2++, *in3++);
271#else
272 using Iterators = std::
273 tuple<InputIterator1, InputIterator2, InputIterator3, OutputIterator>;
274 using SyncIterators = SynchronousIterators<Iterators>;
275 Iterators x_begin(begin_in1, in2, in3, out);
276 Iterators x_end(end_in1,
277 InputIterator2(),
278 InputIterator3(),
279 OutputIterator());
281 SyncIterators(x_begin),
282 SyncIterators(x_end),
283 [predicate](const auto &range) {
284 for (const auto &p : range)
285 *std::get<3>(p) =
286 predicate(*std::get<0>(p), *std::get<1>(p), *std::get<2>(p));
287 },
288 grainsize);
289#endif
290 }
291
292
293 namespace internal
294 {
295#ifdef DEAL_II_WITH_TBB
300 template <typename RangeType, typename Function>
301 void
302 apply_to_subranges(const tbb::blocked_range<RangeType> &range,
303 const Function & f)
304 {
305 f(range.begin(), range.end());
306 }
307#endif
308 } // namespace internal
309
310
380 template <typename RangeType, typename Function>
381 void
382 apply_to_subranges(const RangeType & begin,
383 const typename identity<RangeType>::type &end,
384 const Function & f,
385 const unsigned int grainsize)
386 {
387#ifndef DEAL_II_WITH_TBB
388 // make sure we don't get compiler
389 // warnings about unused arguments
390 (void)grainsize;
391
392 f(begin, end);
393#else
395 begin,
396 end,
397 [&f](const tbb::blocked_range<RangeType> &range) {
398 internal::apply_to_subranges<RangeType, Function>(range, f);
399 },
400 grainsize);
401#endif
402 }
403
404
405
434 {
439 virtual ~ParallelForInteger() = default;
440
449 void
450 apply_parallel(const std::size_t begin,
451 const std::size_t end,
452 const std::size_t minimum_parallel_grain_size) const;
453
460 virtual void
461 apply_to_subrange(const std::size_t, const std::size_t) const = 0;
462 };
463
464
465
526 template <typename ResultType, typename RangeType, typename Function>
527 ResultType
529 const RangeType & begin,
530 const typename identity<RangeType>::type &end,
531 const unsigned int grainsize)
532 {
533#ifndef DEAL_II_WITH_TBB
534 // make sure we don't get compiler
535 // warnings about unused arguments
536 (void)grainsize;
537
538 return f(begin, end);
539#else
540 return tbb::parallel_reduce(
541 tbb::blocked_range<RangeType>(begin, end, grainsize),
542 ResultType(0),
543 [f](const auto &range, const ResultType &starting_value) {
544 ResultType value = starting_value;
545 value += f(range.begin(), range.end());
546 return value;
547 },
548 std::plus<ResultType>(),
549 tbb::auto_partitioner());
550#endif
551 }
552
553
554 // --------------------- for loop affinity partitioner -----------------------
555
565 namespace internal
566 {
568 {
569 public:
574
575#ifdef DEAL_II_WITH_TBB
581
588 std::shared_ptr<tbb::affinity_partitioner>
590
596 void
597 release_one_partitioner(std::shared_ptr<tbb::affinity_partitioner> &p);
598
599 private:
604 std::shared_ptr<tbb::affinity_partitioner> my_partitioner;
605
610 bool in_use;
611
615 std::mutex mutex;
616#endif
617 };
618 } // namespace internal
619} // namespace parallel
620
621
622namespace internal
623{
624 namespace VectorImplementation
625 {
640 extern unsigned int minimum_parallel_grain_size;
641 } // namespace VectorImplementation
642
643
644 namespace SparseMatrixImplementation
645 {
651 extern unsigned int minimum_parallel_grain_size;
652 } // namespace SparseMatrixImplementation
653
654} // end of namespace internal
655
656
657/* --------------------------- inline functions ------------------------- */
658
659namespace parallel
660{
661 inline void
663 const std::size_t begin,
664 const std::size_t end,
665 const std::size_t minimum_parallel_grain_size) const
666 {
667#ifndef DEAL_II_WITH_TBB
668 // make sure we don't get compiler
669 // warnings about unused arguments
670 (void)minimum_parallel_grain_size;
671
672 apply_to_subrange(begin, end);
673#else
675 begin,
676 end,
677 [this](const tbb::blocked_range<std::size_t> &range) {
678 apply_to_subrange(range.begin(), range.end());
679 },
680 minimum_parallel_grain_size);
681#endif
682 }
683
684} // end of namespace parallel
685
687
688#endif
std::shared_ptr< tbb::affinity_partitioner > acquire_one_partitioner()
Definition: parallel.cc:75
std::shared_ptr< tbb::affinity_partitioner > my_partitioner
Definition: parallel.h:604
void release_one_partitioner(std::shared_ptr< tbb::affinity_partitioner > &p)
Definition: parallel.cc:88
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:442
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition: config.h:456
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:443
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition: config.h:495
unsigned int minimum_parallel_grain_size
Definition: parallel.cc:34
void parallel_for(Iterator x_begin, Iterator x_end, const Functor &functor, const unsigned int grainsize)
Definition: parallel.h:80
void apply_to_subranges(const tbb::blocked_range< RangeType > &range, const Function &f)
Definition: parallel.h:302
ResultType accumulate_from_subranges(const Function &f, const RangeType &begin, const typename identity< RangeType >::type &end, const unsigned int grainsize)
Definition: parallel.h:528
void apply_to_subranges(const RangeType &begin, const typename identity< RangeType >::type &end, const Function &f, const unsigned int grainsize)
Definition: parallel.h:382
void transform(const InputIterator &begin_in, const InputIterator &end_in, OutputIterator out, const Predicate &predicate, const unsigned int grainsize)
Definition: parallel.h:135
virtual ~ParallelForInteger()=default
virtual void apply_to_subrange(const std::size_t, const std::size_t) const =0
void apply_parallel(const std::size_t begin, const std::size_t end, const std::size_t minimum_parallel_grain_size) const
Definition: parallel.h:662