]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Apply invocable concepts in parallel.h.
authorWolfgang Bangerth <bangerth@colostate.edu>
Tue, 21 Mar 2023 17:13:18 +0000 (11:13 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Tue, 21 Mar 2023 17:13:18 +0000 (11:13 -0600)
include/deal.II/base/parallel.h

index 8225f689f68f8749a4c05f2bcf0f85b2269ca76a..b55a1b109a2f19c91177ac989bc56e6c43899950 100644 (file)
 #  include <tbb/partitioner.h>
 #endif
 
+#ifdef DEAL_II_HAVE_CXX20
+#  include <concepts>
+#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 <code>*out++ =
-   * predicate(*in++)</code> where the <code>in</code> iterator ranges over
+   * function(*in++)</code> where the <code>in</code> 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 <typename InputIterator, typename OutputIterator, typename Predicate>
-  void
-  transform(const InputIterator &begin_in,
-            const InputIterator &end_in,
-            OutputIterator       out,
-            const Predicate &    predicate,
-            const unsigned int   grainsize)
+  template <typename InputIterator, typename OutputIterator, typename Function>
+  DEAL_II_CXX20_REQUIRES((std::invocable<Function, InputIterator>))
+  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<InputIterator, OutputIterator>;
     using SyncIterators = SynchronousIterators<Iterators>;
@@ -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 <code>*out++ = predicate(*in1++,
+   * An algorithm that performs the action <code>*out++ = function(*in1++,
    * *in2++)</code> where the <code>in1</code> iterator ranges over the given
    * input range, using the parallel for operator of tbb.
    *
@@ -187,14 +191,15 @@ namespace parallel
   template <typename InputIterator1,
             typename InputIterator2,
             typename OutputIterator,
-            typename Predicate>
-  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<Function, InputIterator1, InputIterator2>))
+  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<InputIterator1, InputIterator2, OutputIterator>;
@@ -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 <code>*out++ = predicate(*in1++,
+   * An algorithm that performs the action <code>*out++ = function(*in1++,
    * *in2++, *in3++)</code> where the <code>in1</code> 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<Function, InputIterator1, InputIterator2, InputIterator3>))
+  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<InputIterator1, InputIterator2, InputIterator3, OutputIterator>;
@@ -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 <typename RangeType, typename Function>
-    void
-    apply_to_subranges(const tbb::blocked_range<RangeType> &range,
-                       const Function &                     f)
+    template <typename Iterator, typename Function>
+    DEAL_II_CXX20_REQUIRES((std::invocable<Function, Iterator, Iterator>))
+    void apply_to_subranges(const tbb::blocked_range<Iterator> &range,
+                            const Function &                    f)
     {
       f(range.begin(), range.end());
     }
@@ -375,12 +381,12 @@ namespace parallel
    * @ref threads "Parallel computing with multiple processors"
    * module.
    */
-  template <typename RangeType, typename Function>
-  void
-  apply_to_subranges(const RangeType &                         begin,
-                     const typename identity<RangeType>::type &end,
-                     const Function &                          f,
-                     const unsigned int                        grainsize)
+  template <typename Iterator, typename Function>
+  DEAL_II_CXX20_REQUIRES((std::invocable<Function, Iterator, Iterator>))
+  void apply_to_subranges(const Iterator &                         begin,
+                          const typename identity<Iterator>::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<RangeType> &range) {
-        internal::apply_to_subranges<RangeType, Function>(range, f);
+      [&f](const tbb::blocked_range<Iterator> &range) {
+        internal::apply_to_subranges<Iterator, Function>(range, f);
       },
       grainsize);
 #endif
@@ -521,12 +527,13 @@ namespace parallel
    * @ref threads "Parallel computing with multiple processors"
    * module.
    */
-  template <typename ResultType, typename RangeType, typename Function>
+  template <typename ResultType, typename Iterator, typename Function>
+  DEAL_II_CXX20_REQUIRES((std::invocable<Function, Iterator, Iterator>))
   ResultType
-  accumulate_from_subranges(const Function &                          f,
-                            const RangeType &                         begin,
-                            const typename identity<RangeType>::type &end,
-                            const unsigned int                        grainsize)
+    accumulate_from_subranges(const Function &                         f,
+                              const Iterator &                         begin,
+                              const typename identity<Iterator>::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<RangeType>(begin, end, grainsize),
+      tbb::blocked_range<Iterator>(begin, end, grainsize),
       ResultType(0),
       [f](const auto &range, const ResultType &starting_value) {
         ResultType value = starting_value;

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.