15#ifndef dealii_parallel_h
16#define dealii_parallel_h
31#ifdef DEAL_II_WITH_TASKFLOW
34# include <taskflow/algorithm/for_each.hpp>
35# include <taskflow/taskflow.hpp>
38#ifdef DEAL_II_WITH_TBB
39# include <tbb/blocked_range.h>
40# include <tbb/parallel_for.h>
41# include <tbb/parallel_reduce.h>
42# include <tbb/partitioner.h>
44# include <boost/range/iterator_range.hpp>
47#ifdef DEAL_II_HAVE_CXX20
65 template <
typename Number>
71#ifdef __INTEL_COMPILER
79 static const bool value =
false;
83#ifdef DEAL_II_WITH_TASKFLOW
87 template <
typename Iterator,
typename Functor>
91 const Functor &functor,
92 const unsigned int grainsize)
95 tf::Taskflow taskflow;
109 [&](
const auto &item) { functor(item); },
110 tf::StaticPartitioner(grainsize));
111 executor.run(taskflow).wait();
115#ifdef DEAL_II_WITH_TBB
119 template <
typename Iterator,
typename Functor>
123 const Functor &functor,
124 const unsigned int grainsize)
126 tbb::parallel_for(tbb::blocked_range<Iterator>(x_begin, x_end, grainsize),
128 tbb::auto_partitioner());
136 template <
typename Iterator,
typename Functor>
140 const Functor &functor,
141 const unsigned int grainsize,
142 const std::shared_ptr<tbb::affinity_partitioner> &partitioner)
144 tbb::parallel_for(tbb::blocked_range<Iterator>(x_begin, x_end, grainsize),
154 template <
typename Iterator,
typename Functor>
158 const Functor &functor,
161 functor(boost::iterator_range<Iterator>(x_begin, x_end));
196 template <
typename InputIterator,
typename OutputIterator,
typename Function>
198 (std::invocable<
Function,
decltype(*std::declval<InputIterator>())> &&
199 std::assignable_from<
200 decltype(*std::declval<OutputIterator>()),
202 decltype(*std::declval<InputIterator>())>>))
203 DEAL_II_DEPRECATED_EARLY
void transform(const InputIterator &begin_in,
204 const InputIterator &end_in,
207 const
unsigned int grainsize)
209#ifdef DEAL_II_WITH_TASKFLOW
210 using Iterators = std::tuple<InputIterator, OutputIterator>;
212 Iterators x_begin(begin_in, out);
213 Iterators x_end(end_in, OutputIterator());
216 SyncIterators(x_begin),
217 SyncIterators(x_end),
218 [function](
const auto &it) {
219 *std::get<1>(it) = function(*std::get<0>(it));
223#elif defined(DEAL_II_WITH_TBB)
224 using Iterators = std::tuple<InputIterator, OutputIterator>;
226 Iterators x_begin(begin_in, out);
227 Iterators x_end(end_in, OutputIterator());
229 SyncIterators(x_begin),
230 SyncIterators(x_end),
231 [function](
const auto &range) {
232 for (
const auto &p : range)
233 *std::get<1>(p) = function(*std::get<0>(p));
241 for (InputIterator in = begin_in; in != end_in;)
242 *out++ = function(*in++);
279 template <
typename InputIterator1,
280 typename InputIterator2,
281 typename OutputIterator,
285 decltype(*std::declval<InputIterator1>()),
286 decltype(*std::declval<InputIterator2>())> &&
287 std::assignable_from<
288 decltype(*std::declval<OutputIterator>()),
290 decltype(*std::declval<InputIterator1>()),
291 decltype(*std::declval<InputIterator2>())>>))
292 DEAL_II_DEPRECATED_EARLY
void transform(const InputIterator1 &begin_in1,
293 const InputIterator1 &end_in1,
297 const
unsigned int grainsize)
299#ifdef DEAL_II_WITH_TASKFLOW
301 std::tuple<InputIterator1, InputIterator2, OutputIterator>;
303 Iterators x_begin(begin_in1, in2, out);
304 Iterators x_end(end_in1, InputIterator2(), OutputIterator());
307 SyncIterators(x_begin),
308 SyncIterators(x_end),
309 [function](
const auto &it) {
310 *std::get<2>(it) = function(*std::get<0>(it), *std::get<1>(it));
314#elif defined(DEAL_II_WITH_TBB)
316 std::tuple<InputIterator1, InputIterator2, OutputIterator>;
318 Iterators x_begin(begin_in1, in2, out);
319 Iterators x_end(end_in1, InputIterator2(), OutputIterator());
321 SyncIterators(x_begin),
322 SyncIterators(x_end),
323 [function](
const auto &range) {
324 for (
const auto &p : range)
325 *std::get<2>(p) = function(*std::get<0>(p), *std::get<1>(p));
334 for (InputIterator1 in1 = begin_in1; in1 != end_in1;)
335 *out++ = function(*in1++, *in2++);
374 template <
typename InputIterator1,
375 typename InputIterator2,
376 typename InputIterator3,
377 typename OutputIterator,
381 decltype(*std::declval<InputIterator1>()),
382 decltype(*std::declval<InputIterator2>()),
383 decltype(*std::declval<InputIterator3>())> &&
384 std::assignable_from<
385 decltype(*std::declval<OutputIterator>()),
387 decltype(*std::declval<InputIterator1>()),
388 decltype(*std::declval<InputIterator2>()),
389 decltype(*std::declval<InputIterator3>())>>))
390 DEAL_II_DEPRECATED_EARLY
void transform(const InputIterator1 &begin_in1,
391 const InputIterator1 &end_in1,
396 const
unsigned int grainsize)
398#ifdef DEAL_II_WITH_TASKFLOW
399 using Iterators = std::
400 tuple<InputIterator1, InputIterator2, InputIterator3, OutputIterator>;
402 Iterators x_begin(begin_in1, in2, in3, out);
403 Iterators x_end(end_in1,
409 SyncIterators(x_begin),
410 SyncIterators(x_end),
411 [function](
const auto &it) {
413 function(*std::get<0>(it), *std::get<1>(it), *std::get<2>(it));
417#elif defined(DEAL_II_WITH_TBB)
418 using Iterators = std::
419 tuple<InputIterator1, InputIterator2, InputIterator3, OutputIterator>;
421 Iterators x_begin(begin_in1, in2, in3, out);
422 Iterators x_end(end_in1,
427 SyncIterators(x_begin),
428 SyncIterators(x_end),
429 [function](
const auto &range) {
430 for (
const auto &p : range)
432 function(*std::get<0>(p), *std::get<1>(p), *std::get<2>(p));
440 for (OutputIterator1 in1 = begin_in1; in1 != end_in1;)
441 *out++ = function(*in1++, *in2++, *in3++);
448#ifdef DEAL_II_WITH_TBB
455 template <
typename Iterator,
typename Function>
460 f(range.begin(), range.end());
537 template <
typename Iterator,
typename Function>
540 const
std_cxx20::type_identity_t<Iterator> &end,
542 const
unsigned int grainsize)
544#ifndef DEAL_II_WITH_TBB
554 [&f](
const tbb::blocked_range<Iterator> &range) {
555 internal::apply_to_subranges<Iterator, Function>(range, f);
608 const std::size_t end,
609 const std::size_t minimum_parallel_grain_size)
const;
689 template <
typename ResultType,
typename Iterator,
typename Function>
691 (std::invocable<Function, Iterator, Iterator> &&
692 std::convertible_to<std::invoke_result_t<Function, Iterator, Iterator>,
696 const Iterator &begin,
697 const
std_cxx20::type_identity_t<Iterator> &end,
698 const
unsigned int grainsize)
700#ifndef DEAL_II_WITH_TBB
705 return f(begin, end);
707 return tbb::parallel_reduce(
708 tbb::blocked_range<Iterator>(begin, end, grainsize),
710 [f](
const auto &range,
const ResultType &starting_value) {
711 ResultType value = starting_value;
712 value += f(range.begin(), range.end());
715 std::plus<ResultType>(),
716 tbb::auto_partitioner());
742#ifdef DEAL_II_WITH_TBB
755 std::shared_ptr<tbb::affinity_partitioner>
765 const std::shared_ptr<tbb::affinity_partitioner> &p);
792 namespace VectorImplementation
812 namespace SparseMatrixImplementation
831 const std::size_t begin,
832 const std::size_t end,
833 const std::size_t minimum_parallel_grain_size)
const
835#ifndef DEAL_II_WITH_TBB
838 (void)minimum_parallel_grain_size;
845 [
this](
const tbb::blocked_range<std::size_t> &range) {
848 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