15#ifndef dealii_parallel_h
16#define dealii_parallel_h
32#ifdef DEAL_II_WITH_TASKFLOW
35# include <taskflow/algorithm/for_each.hpp>
36# include <taskflow/taskflow.hpp>
39#ifdef DEAL_II_WITH_TBB
40# include <tbb/blocked_range.h>
41# include <tbb/parallel_for.h>
42# include <tbb/parallel_reduce.h>
43# include <tbb/partitioner.h>
45# include <boost/range/iterator_range.hpp>
48#ifdef DEAL_II_HAVE_CXX20
66 template <
typename Number>
72#ifdef __INTEL_COMPILER
80 static const bool value =
false;
84#ifdef DEAL_II_WITH_TASKFLOW
88 template <
typename Iterator,
typename Functor>
92 const Functor &functor,
93 const unsigned int grainsize)
96 tf::Taskflow taskflow;
110 [&](
const auto &item) { functor(item); },
111 tf::StaticPartitioner(grainsize));
112 executor.run(taskflow).wait();
116#ifdef DEAL_II_WITH_TBB
120 template <
typename Iterator,
typename Functor>
124 const Functor &functor,
125 const unsigned int grainsize)
127 tbb::parallel_for(tbb::blocked_range<Iterator>(x_begin, x_end, grainsize),
129 tbb::auto_partitioner());
137 template <
typename Iterator,
typename Functor>
141 const Functor &functor,
142 const unsigned int grainsize,
143 const std::shared_ptr<tbb::affinity_partitioner> &partitioner)
145 tbb::parallel_for(tbb::blocked_range<Iterator>(x_begin, x_end, grainsize),
155 template <
typename Iterator,
typename Functor>
159 const Functor &functor,
162 functor(boost::iterator_range<Iterator>(x_begin, x_end));
197 template <
typename InputIterator,
typename OutputIterator,
typename Function>
199 (std::invocable<
Function,
decltype(*std::declval<InputIterator>())> &&
200 std::assignable_from<
201 decltype(*std::declval<OutputIterator>()),
203 decltype(*std::declval<InputIterator>())>>))
204 DEAL_II_DEPRECATED_EARLY
void transform(const InputIterator &begin_in,
205 const InputIterator &end_in,
208 const
unsigned int grainsize)
210#ifdef DEAL_II_WITH_TASKFLOW
211 using Iterators = std::tuple<InputIterator, OutputIterator>;
213 Iterators x_begin(begin_in, out);
214 Iterators x_end(end_in, OutputIterator());
217 SyncIterators(x_begin),
218 SyncIterators(x_end),
219 [function](
const auto &it) {
220 *std::get<1>(it) = function(*std::get<0>(it));
224#elif defined(DEAL_II_WITH_TBB)
225 using Iterators = std::tuple<InputIterator, OutputIterator>;
227 Iterators x_begin(begin_in, out);
228 Iterators x_end(end_in, OutputIterator());
230 SyncIterators(x_begin),
231 SyncIterators(x_end),
232 [function](
const auto &range) {
233 for (
const auto &p : range)
234 *std::get<1>(p) = function(*std::get<0>(p));
242 for (InputIterator in = begin_in; in != end_in;)
243 *out++ = function(*in++);
280 template <
typename InputIterator1,
281 typename InputIterator2,
282 typename OutputIterator,
286 decltype(*std::declval<InputIterator1>()),
287 decltype(*std::declval<InputIterator2>())> &&
288 std::assignable_from<
289 decltype(*std::declval<OutputIterator>()),
291 decltype(*std::declval<InputIterator1>()),
292 decltype(*std::declval<InputIterator2>())>>))
293 DEAL_II_DEPRECATED_EARLY
void transform(const InputIterator1 &begin_in1,
294 const InputIterator1 &end_in1,
298 const
unsigned int grainsize)
300#ifdef DEAL_II_WITH_TASKFLOW
302 std::tuple<InputIterator1, InputIterator2, OutputIterator>;
304 Iterators x_begin(begin_in1, in2, out);
305 Iterators x_end(end_in1, InputIterator2(), OutputIterator());
308 SyncIterators(x_begin),
309 SyncIterators(x_end),
310 [function](
const auto &it) {
311 *std::get<2>(it) = function(*std::get<0>(it), *std::get<1>(it));
315#elif defined(DEAL_II_WITH_TBB)
317 std::tuple<InputIterator1, InputIterator2, OutputIterator>;
319 Iterators x_begin(begin_in1, in2, out);
320 Iterators x_end(end_in1, InputIterator2(), OutputIterator());
322 SyncIterators(x_begin),
323 SyncIterators(x_end),
324 [function](
const auto &range) {
325 for (
const auto &p : range)
326 *std::get<2>(p) = function(*std::get<0>(p), *std::get<1>(p));
335 for (InputIterator1 in1 = begin_in1; in1 != end_in1;)
336 *out++ = function(*in1++, *in2++);
375 template <
typename InputIterator1,
376 typename InputIterator2,
377 typename InputIterator3,
378 typename OutputIterator,
382 decltype(*std::declval<InputIterator1>()),
383 decltype(*std::declval<InputIterator2>()),
384 decltype(*std::declval<InputIterator3>())> &&
385 std::assignable_from<
386 decltype(*std::declval<OutputIterator>()),
388 decltype(*std::declval<InputIterator1>()),
389 decltype(*std::declval<InputIterator2>()),
390 decltype(*std::declval<InputIterator3>())>>))
391 DEAL_II_DEPRECATED_EARLY
void transform(const InputIterator1 &begin_in1,
392 const InputIterator1 &end_in1,
397 const
unsigned int grainsize)
399#ifdef DEAL_II_WITH_TASKFLOW
400 using Iterators = std::
401 tuple<InputIterator1, InputIterator2, InputIterator3, OutputIterator>;
403 Iterators x_begin(begin_in1, in2, in3, out);
404 Iterators x_end(end_in1,
410 SyncIterators(x_begin),
411 SyncIterators(x_end),
412 [function](
const auto &it) {
414 function(*std::get<0>(it), *std::get<1>(it), *std::get<2>(it));
418#elif defined(DEAL_II_WITH_TBB)
419 using Iterators = std::
420 tuple<InputIterator1, InputIterator2, InputIterator3, OutputIterator>;
422 Iterators x_begin(begin_in1, in2, in3, out);
423 Iterators x_end(end_in1,
428 SyncIterators(x_begin),
429 SyncIterators(x_end),
430 [function](
const auto &range) {
431 for (
const auto &p : range)
433 function(*std::get<0>(p), *std::get<1>(p), *std::get<2>(p));
441 for (OutputIterator in1 = begin_in1; in1 != end_in1;)
442 *out++ = function(*in1++, *in2++, *in3++);
449#ifdef DEAL_II_WITH_TBB
456 template <
typename Iterator,
typename Function>
461 f(range.begin(), range.end());
538 template <
typename Iterator,
typename Function>
541 const
std_cxx20::type_identity_t<Iterator> &end,
543 const
unsigned int grainsize)
545#ifndef DEAL_II_WITH_TBB
555 [&f](
const tbb::blocked_range<Iterator> &range) {
556 internal::apply_to_subranges<Iterator, Function>(range, f);
609 const std::size_t end,
610 const std::size_t minimum_parallel_grain_size)
const;
690 template <
typename ResultType,
typename Iterator,
typename Function>
692 (std::invocable<Function, Iterator, Iterator> &&
693 std::convertible_to<std::invoke_result_t<Function, Iterator, Iterator>,
697 const Iterator &begin,
698 const
std_cxx20::type_identity_t<Iterator> &end,
699 const
unsigned int grainsize)
701#ifndef DEAL_II_WITH_TBB
706 return f(begin, end);
708 return tbb::parallel_reduce(
709 tbb::blocked_range<Iterator>(begin, end, grainsize),
711 [f](
const auto &range,
const ResultType &starting_value) {
712 ResultType value = starting_value;
713 value += f(range.begin(), range.end());
716 std::plus<ResultType>(),
717 tbb::auto_partitioner());
743#ifdef DEAL_II_WITH_TBB
756 std::shared_ptr<tbb::affinity_partitioner>
766 const std::shared_ptr<tbb::affinity_partitioner> &p);
793 namespace VectorImplementation
813 namespace SparseMatrixImplementation
832 const std::size_t begin,
833 const std::size_t end,
834 const std::size_t minimum_parallel_grain_size)
const
836#ifndef DEAL_II_WITH_TBB
839 (void)minimum_parallel_grain_size;
846 [
this](
const tbb::blocked_range<std::size_t> &range) {
849 minimum_parallel_grain_size);
static tf::Executor & get_taskflow_executor()
std::shared_ptr< tbb::affinity_partitioner > acquire_one_partitioner()
void release_one_partitioner(const std::shared_ptr< tbb::affinity_partitioner > &p)
std::shared_ptr< tbb::affinity_partitioner > my_partitioner
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_CXX20_REQUIRES(condition)
#define DEAL_II_NAMESPACE_CLOSE
unsigned int minimum_parallel_grain_size
unsigned int minimum_parallel_grain_size
void parallel_for(Iterator x_begin, Iterator x_end, const Functor &functor, const unsigned int grainsize)
void taskflow_parallel_for(Iterator x_begin, Iterator x_end, const Functor &functor, const unsigned int grainsize)
void apply_to_subranges(const tbb::blocked_range< Iterator > &range, const Function &f)
void apply_to_subranges(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, const Function &f, const unsigned int grainsize)
void transform(const InputIterator &begin_in, const InputIterator &end_in, OutputIterator out, const Function &function, const unsigned int grainsize)
ResultType accumulate_from_subranges(const Function &f, const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, const unsigned int grainsize)
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