From 6cfd96a6a76bb2bbc7a5c2dac4e312d6dc15396e Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Tue, 21 Mar 2023 11:13:18 -0600 Subject: [PATCH] Apply invocable concepts in parallel.h. --- include/deal.II/base/parallel.h | 115 +++++++++++++++++--------------- 1 file changed, 61 insertions(+), 54 deletions(-) diff --git a/include/deal.II/base/parallel.h b/include/deal.II/base/parallel.h index 8225f689f6..b55a1b109a 100644 --- a/include/deal.II/base/parallel.h +++ b/include/deal.II/base/parallel.h @@ -36,6 +36,10 @@ # include #endif +#ifdef DEAL_II_HAVE_CXX20 +# include +#endif + // TODO[WB]: allow calling functions to pass along a tbb::affinity_partitioner // object to ensure that subsequent calls use the same cache lines @@ -107,7 +111,7 @@ namespace parallel /** * An algorithm that performs the action *out++ = - * predicate(*in++) where the in iterator ranges over + * function(*in++) where the in iterator ranges over * the given input range. * * This algorithm does pretty much what std::transform does. The difference @@ -128,13 +132,13 @@ namespace parallel * @ref threads "Parallel computing with multiple processors" * module. */ - template - void - transform(const InputIterator &begin_in, - const InputIterator &end_in, - OutputIterator out, - const Predicate & predicate, - const unsigned int grainsize) + template + DEAL_II_CXX20_REQUIRES((std::invocable)) + void transform(const InputIterator &begin_in, + const InputIterator &end_in, + OutputIterator out, + const Function & function, + const unsigned int grainsize) { #ifndef DEAL_II_WITH_TBB // make sure we don't get compiler @@ -142,7 +146,7 @@ namespace parallel (void)grainsize; for (OutputIterator in = begin_in; in != end_in;) - *out++ = predicate(*in++); + *out++ = function(*in++); #else using Iterators = std::tuple; using SyncIterators = SynchronousIterators; @@ -151,9 +155,9 @@ namespace parallel internal::parallel_for( SyncIterators(x_begin), SyncIterators(x_end), - [predicate](const auto &range) { + [function](const auto &range) { for (const auto &p : range) - *std::get<1>(p) = predicate(*std::get<0>(p)); + *std::get<1>(p) = function(*std::get<0>(p)); }, grainsize); #endif @@ -162,7 +166,7 @@ namespace parallel /** - * An algorithm that performs the action *out++ = predicate(*in1++, + * An algorithm that performs the action *out++ = function(*in1++, * *in2++) where the in1 iterator ranges over the given * input range, using the parallel for operator of tbb. * @@ -187,14 +191,15 @@ namespace parallel template - void - transform(const InputIterator1 &begin_in1, - const InputIterator1 &end_in1, - InputIterator2 in2, - OutputIterator out, - const Predicate & predicate, - const unsigned int grainsize) + typename Function> + DEAL_II_CXX20_REQUIRES( + (std::invocable)) + void transform(const InputIterator1 &begin_in1, + const InputIterator1 &end_in1, + InputIterator2 in2, + OutputIterator out, + const Function & function, + const unsigned int grainsize) { #ifndef DEAL_II_WITH_TBB // make sure we don't get compiler @@ -202,7 +207,7 @@ namespace parallel (void)grainsize; for (OutputIterator in1 = begin_in1; in1 != end_in1;) - *out++ = predicate(*in1++, *in2++); + *out++ = function(*in1++, *in2++); #else using Iterators = std::tuple; @@ -212,9 +217,9 @@ namespace parallel internal::parallel_for( SyncIterators(x_begin), SyncIterators(x_end), - [predicate](const auto &range) { + [function](const auto &range) { for (const auto &p : range) - *std::get<2>(p) = predicate(*std::get<0>(p), *std::get<1>(p)); + *std::get<2>(p) = function(*std::get<0>(p), *std::get<1>(p)); }, grainsize); #endif @@ -223,7 +228,7 @@ namespace parallel /** - * An algorithm that performs the action *out++ = predicate(*in1++, + * An algorithm that performs the action *out++ = function(*in1++, * *in2++, *in3++) where the in1 iterator ranges over * the given input range. * @@ -249,15 +254,16 @@ namespace parallel typename InputIterator2, typename InputIterator3, typename OutputIterator, - typename Predicate> - void - transform(const InputIterator1 &begin_in1, - const InputIterator1 &end_in1, - InputIterator2 in2, - InputIterator3 in3, - OutputIterator out, - const Predicate & predicate, - const unsigned int grainsize) + typename Function> + DEAL_II_CXX20_REQUIRES( + (std::invocable)) + void transform(const InputIterator1 &begin_in1, + const InputIterator1 &end_in1, + InputIterator2 in2, + InputIterator3 in3, + OutputIterator out, + const Function & function, + const unsigned int grainsize) { #ifndef DEAL_II_WITH_TBB // make sure we don't get compiler @@ -265,7 +271,7 @@ namespace parallel (void)grainsize; for (OutputIterator in1 = begin_in1; in1 != end_in1;) - *out++ = predicate(*in1++, *in2++, *in3++); + *out++ = function(*in1++, *in2++, *in3++); #else using Iterators = std:: tuple; @@ -278,10 +284,10 @@ namespace parallel internal::parallel_for( SyncIterators(x_begin), SyncIterators(x_end), - [predicate](const auto &range) { + [function](const auto &range) { for (const auto &p : range) *std::get<3>(p) = - predicate(*std::get<0>(p), *std::get<1>(p), *std::get<2>(p)); + function(*std::get<0>(p), *std::get<1>(p), *std::get<2>(p)); }, grainsize); #endif @@ -295,10 +301,10 @@ namespace parallel * Take a range argument and call the given function with its begin and * end. */ - template - void - apply_to_subranges(const tbb::blocked_range &range, - const Function & f) + template + DEAL_II_CXX20_REQUIRES((std::invocable)) + void apply_to_subranges(const tbb::blocked_range &range, + const Function & f) { f(range.begin(), range.end()); } @@ -375,12 +381,12 @@ namespace parallel * @ref threads "Parallel computing with multiple processors" * module. */ - template - void - apply_to_subranges(const RangeType & begin, - const typename identity::type &end, - const Function & f, - const unsigned int grainsize) + template + DEAL_II_CXX20_REQUIRES((std::invocable)) + void apply_to_subranges(const Iterator & begin, + const typename identity::type &end, + const Function & f, + const unsigned int grainsize) { #ifndef DEAL_II_WITH_TBB // make sure we don't get compiler @@ -392,8 +398,8 @@ namespace parallel internal::parallel_for( begin, end, - [&f](const tbb::blocked_range &range) { - internal::apply_to_subranges(range, f); + [&f](const tbb::blocked_range &range) { + internal::apply_to_subranges(range, f); }, grainsize); #endif @@ -521,12 +527,13 @@ namespace parallel * @ref threads "Parallel computing with multiple processors" * module. */ - template + template + DEAL_II_CXX20_REQUIRES((std::invocable)) ResultType - accumulate_from_subranges(const Function & f, - const RangeType & begin, - const typename identity::type &end, - const unsigned int grainsize) + accumulate_from_subranges(const Function & f, + const Iterator & begin, + const typename identity::type &end, + const unsigned int grainsize) { #ifndef DEAL_II_WITH_TBB // make sure we don't get compiler @@ -536,7 +543,7 @@ namespace parallel return f(begin, end); #else return tbb::parallel_reduce( - tbb::blocked_range(begin, end, grainsize), + tbb::blocked_range(begin, end, grainsize), ResultType(0), [f](const auto &range, const ResultType &starting_value) { ResultType value = starting_value; -- 2.39.5