16 #ifndef dealii_parallel_h 17 #define dealii_parallel_h 20 #include <deal.II/base/config.h> 22 #include <deal.II/base/exceptions.h> 23 #include <deal.II/base/synchronous_iterator.h> 24 #include <deal.II/base/template_constraints.h> 25 #include <deal.II/base/thread_management.h> 32 #ifdef DEAL_II_WITH_THREADS 33 # include <tbb/blocked_range.h> 34 # include <tbb/parallel_for.h> 35 # include <tbb/parallel_reduce.h> 36 # include <tbb/partitioner.h> 43 DEAL_II_NAMESPACE_OPEN
53 template <
typename Number>
56 static const bool value =
true;
59 #ifdef __INTEL_COMPILER 67 static const bool value =
false;
87 template <
typename Range>
89 operator()(
const Range &range)
const 91 for (
typename Range::const_iterator p = range.begin(); p != range.end();
105 template <
typename I1,
typename I2>
107 apply(
const F &f,
const std::tuple<I1, I2> &p)
109 *std::get<1>(p) = f(*std::get<0>(p));
115 template <
typename I1,
typename I2,
typename I3>
117 apply(
const F &f,
const std::tuple<I1, I2, I3> &p)
119 *std::get<2>(p) = f(*std::get<0>(p), *std::get<1>(p));
125 template <
typename I1,
typename I2,
typename I3,
typename I4>
127 apply(
const F &f,
const std::tuple<I1, I2, I3, I4> &p)
129 *std::get<3>(p) = f(*std::get<0>(p), *std::get<1>(p), *std::get<2>(p));
140 template <
typename F>
171 template <
typename InputIterator,
typename OutputIterator,
typename Predicate>
174 const InputIterator &end_in,
176 Predicate & predicate,
177 const unsigned int grainsize)
179 #ifndef DEAL_II_WITH_THREADS 184 for (OutputIterator in = begin_in; in != end_in;)
185 *out++ = predicate(*in++);
187 using Iterators = std::tuple<InputIterator, OutputIterator>;
189 Iterators x_begin(begin_in, out);
190 Iterators x_end(end_in, OutputIterator());
191 tbb::parallel_for(tbb::blocked_range<SyncIterators>(x_begin,
195 tbb::auto_partitioner());
224 template <
typename InputIterator1,
225 typename InputIterator2,
226 typename OutputIterator,
230 const InputIterator1 &end_in1,
233 Predicate & predicate,
234 const unsigned int grainsize)
236 #ifndef DEAL_II_WITH_THREADS 241 for (OutputIterator in1 = begin_in1; in1 != end_in1;)
242 *out++ = predicate(*in1++, *in2++);
245 std::tuple<InputIterator1, InputIterator2, OutputIterator>;
247 Iterators x_begin(begin_in1, in2, out);
248 Iterators x_end(end_in1, InputIterator2(), OutputIterator());
249 tbb::parallel_for(tbb::blocked_range<SyncIterators>(x_begin,
253 tbb::auto_partitioner());
282 template <
typename InputIterator1,
283 typename InputIterator2,
284 typename InputIterator3,
285 typename OutputIterator,
289 const InputIterator1 &end_in1,
293 Predicate & predicate,
294 const unsigned int grainsize)
296 #ifndef DEAL_II_WITH_THREADS 301 for (OutputIterator in1 = begin_in1; in1 != end_in1;)
302 *out++ = predicate(*in1++, *in2++, *in3++);
304 using Iterators = std::
305 tuple<InputIterator1, InputIterator2, InputIterator3, OutputIterator>;
307 Iterators x_begin(begin_in1, in2, in3, out);
308 Iterators x_end(end_in1,
312 tbb::parallel_for(tbb::blocked_range<SyncIterators>(x_begin,
316 tbb::auto_partitioner());
323 #ifdef DEAL_II_WITH_THREADS 328 template <
typename RangeType,
typename Function>
333 f(range.begin(), range.end());
410 template <
typename RangeType,
typename Function>
413 const typename identity<RangeType>::type &end,
415 const unsigned int grainsize)
417 #ifndef DEAL_II_WITH_THREADS 422 # ifndef DEAL_II_BIND_NO_CONST_OP_PARENTHESES 432 tbb::blocked_range<RangeType>(begin, end, grainsize),
433 std::bind(&internal::apply_to_subranges<RangeType, Function>,
434 std::placeholders::_1,
436 tbb::auto_partitioner());
486 apply_parallel(
const std::size_t begin,
487 const std::size_t end,
488 const std::size_t minimum_parallel_grain_size)
const;
497 apply_to_subrange(
const std::size_t,
const std::size_t)
const = 0;
504 #ifdef DEAL_II_WITH_THREADS 511 template <
typename ResultType,
typename Function>
528 template <
typename Reductor>
530 const Reductor & reductor,
531 const ResultType neutral_element = ResultType())
532 : result(neutral_element)
534 , neutral_element(neutral_element)
542 : result(r.neutral_element)
544 , neutral_element(r.neutral_element)
545 , reductor(r.reductor)
555 result = reductor(result, r.
result);
561 template <
typename RangeType>
565 result = reductor(result, f(range.begin(), range.end()));
585 const std::function<ResultType(ResultType, ResultType)>
reductor;
650 template <
typename ResultType,
typename RangeType,
typename Function>
653 const RangeType & begin,
654 const typename identity<RangeType>::type &end,
655 const unsigned int grainsize)
657 #ifndef DEAL_II_WITH_THREADS 662 # ifndef DEAL_II_BIND_NO_CONST_OP_PARENTHESES 663 return f(begin, end);
668 return ff(begin, end);
672 f, std::plus<ResultType>(), 0);
673 tbb::parallel_reduce(tbb::blocked_range<RangeType>(begin, end, grainsize),
675 tbb::auto_partitioner());
702 #ifdef DEAL_II_WITH_THREADS 715 std::shared_ptr<tbb::affinity_partitioner>
716 acquire_one_partitioner();
724 release_one_partitioner(std::shared_ptr<tbb::affinity_partitioner> &p);
731 std::shared_ptr<tbb::affinity_partitioner> my_partitioner;
751 namespace VectorImplementation
767 extern unsigned int minimum_parallel_grain_size;
771 namespace SparseMatrixImplementation
778 extern unsigned int minimum_parallel_grain_size;
788 #ifdef DEAL_II_WITH_THREADS 803 operator()(
const tbb::blocked_range<std::size_t> &range)
const 805 worker_.apply_to_subrange(range.begin(), range.end());
817 const std::size_t begin,
818 const std::size_t end,
819 const std::size_t minimum_parallel_grain_size)
const 821 #ifndef DEAL_II_WITH_THREADS 824 (void)minimum_parallel_grain_size;
826 apply_to_subrange(begin, end);
830 tbb::blocked_range<std::size_t>(begin, end, minimum_parallel_grain_size),
832 tbb::auto_partitioner());
838 DEAL_II_NAMESPACE_CLOSE
Body< F > make_body(const F &f)
void apply_parallel(const std::size_t begin, const std::size_t end, const std::size_t minimum_parallel_grain_size) const
void join(const ReductionOnSubranges &r)
static void apply(const F &f, const std::tuple< I1, I2, I3 > &p)
void operator()(const tbb::blocked_range< RangeType > &range)
ReductionOnSubranges(const Function &f, const Reductor &reductor, const ResultType neutral_element=ResultType())
static void apply(const F &f, const std::tuple< I1, I2, I3, I4 > &p)
void apply_to_subranges(const tbb::blocked_range< RangeType > &range, const Function &f)
ReductionOnSubranges(const ReductionOnSubranges &r, tbb::split)
const std::function< ResultType(ResultType, ResultType)> reductor
static void apply(const F &f, const std::tuple< I1, I2 > &p)
ResultType accumulate_from_subranges(const Function &f, const RangeType &begin, const typename identity< RangeType >::type &end, const unsigned int grainsize)
const ResultType neutral_element
void transform(const InputIterator &begin_in, const InputIterator &end_in, OutputIterator out, Predicate &predicate, const unsigned int grainsize)