]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Implement iterator range support in WorkStream::run()
authorJean-Paul Pelteret <jppelteret@gmail.com>
Thu, 2 May 2019 17:32:10 +0000 (19:32 +0200)
committerJean-Paul Pelteret <jppelteret@gmail.com>
Thu, 2 May 2019 17:32:10 +0000 (19:32 +0200)
doc/news/changes/minor/20190502Jean-PaulPelteret-1 [new file with mode: 0644]
include/deal.II/base/work_stream.h
tests/base/work_stream_01a.cc [new file with mode: 0644]
tests/base/work_stream_01a.output [new file with mode: 0644]
tests/base/work_stream_01b.cc [new file with mode: 0644]
tests/base/work_stream_01b.output [new file with mode: 0644]

diff --git a/doc/news/changes/minor/20190502Jean-PaulPelteret-1 b/doc/news/changes/minor/20190502Jean-PaulPelteret-1
new file mode 100644 (file)
index 0000000..8f41a0d
--- /dev/null
@@ -0,0 +1,5 @@
+Improved: The Workstream::run() function is now capable of working with iterator
+ranges, or any general iterable object that defines the `begin()` and `end()`
+of a range of elements to iterate over.
+<br>
+(Jean-Paul Pelteret, 2019/05/02)
index 555c35c98da7562d65960f9f3dd25287429dcb8d..c2fa34674145599510ca5421f55be0585438247f 100644 (file)
@@ -20,6 +20,7 @@
 #  include <deal.II/base/config.h>
 
 #  include <deal.II/base/graph_coloring.h>
+#  include <deal.II/base/iterator_range.h>
 #  include <deal.II/base/multithread_info.h>
 #  include <deal.II/base/parallel.h>
 #  include <deal.II/base/template_constraints.h>
@@ -33,6 +34,7 @@
 #  endif
 
 #  include <functional>
+#  include <iterator>
 #  include <memory>
 #  include <utility>
 #  include <vector>
@@ -1089,6 +1091,72 @@ namespace WorkStream
   }
 
 
+
+  /**
+   * Same as the function above, but for iterator ranges and C-style arrays.
+   * A class that fulfills the requirements of an iterator range defines the
+   * functions `IteratorRangeType::begin()` and `IteratorRangeType::end()`,
+   * both of which return iterators to elements that form the bounds of the
+   * range.
+   */
+  template <typename Worker,
+            typename Copier,
+            typename IteratorRangeType,
+            typename ScratchData,
+            typename CopyData,
+            typename = typename std::enable_if<
+              has_begin_and_end<IteratorRangeType>::value>::type>
+  void
+  run(IteratorRangeType  iterator_range,
+      Worker             worker,
+      Copier             copier,
+      const ScratchData &sample_scratch_data,
+      const CopyData &   sample_copy_data,
+      const unsigned int queue_length = 2 * MultithreadInfo::n_threads(),
+      const unsigned int chunk_size   = 8)
+  {
+    // Call the function above
+    run(iterator_range.begin(),
+        iterator_range.end(),
+        worker,
+        copier,
+        sample_scratch_data,
+        sample_copy_data,
+        queue_length,
+        chunk_size);
+  }
+
+
+
+  /**
+   * Same as the function above, but for deal.II's IteratorRange.
+   */
+  template <typename Worker,
+            typename Copier,
+            typename Iterator,
+            typename ScratchData,
+            typename CopyData>
+  void
+  run(const IteratorRange<Iterator> &iterator_range,
+      Worker                         worker,
+      Copier                         copier,
+      const ScratchData &            sample_scratch_data,
+      const CopyData &               sample_copy_data,
+      const unsigned int queue_length = 2 * MultithreadInfo::n_threads(),
+      const unsigned int chunk_size   = 8)
+  {
+    // Call the function above
+    run(iterator_range.begin(),
+        iterator_range.end(),
+        worker,
+        copier,
+        sample_scratch_data,
+        sample_copy_data,
+        queue_length,
+        chunk_size);
+  }
+
+
   // Implementation 3:
   template <typename Worker,
             typename Copier,
@@ -1227,6 +1295,109 @@ namespace WorkStream
         chunk_size);
   }
 
+
+  template <typename MainClass,
+            typename Iterator,
+            typename ScratchData,
+            typename CopyData>
+  void
+  run(const typename IteratorRange<Iterator>::IteratorOverIterators &begin,
+      const typename IteratorRange<
+        typename identity<Iterator>::type>::IteratorOverIterators &end,
+      MainClass &                                                  main_object,
+      void (MainClass::*worker)(const Iterator &, ScratchData &, CopyData &),
+      void (MainClass::*copier)(const CopyData &),
+      const ScratchData &sample_scratch_data,
+      const CopyData &   sample_copy_data,
+      const unsigned int queue_length = 2 * MultithreadInfo::n_threads(),
+      const unsigned int chunk_size   = 8)
+  {
+    // forward to the other function
+    run(begin,
+        end,
+        std::bind(worker,
+                  std::ref(main_object),
+                  std::placeholders::_1,
+                  std::placeholders::_2,
+                  std::placeholders::_3),
+        std::bind(copier, std::ref(main_object), std::placeholders::_1),
+        sample_scratch_data,
+        sample_copy_data,
+        queue_length,
+        chunk_size);
+  }
+
+
+
+  /**
+   * Same as the function above, but for iterator ranges and C-style arrays.
+   * A class that fulfills the requirements of an iterator range defines the
+   * functions `IteratorRangeType::begin()` and `IteratorRangeType::end()`,
+   * both of which return iterators to elements that form the bounds of the
+   * range.
+   */
+  template <typename MainClass,
+            typename IteratorRangeType,
+            typename ScratchData,
+            typename CopyData,
+            typename = typename std::enable_if<
+              has_begin_and_end<IteratorRangeType>::value>::type>
+  void
+  run(IteratorRangeType iterator_range,
+      MainClass &       main_object,
+      void (MainClass::*worker)(
+        const typename identity<IteratorRangeType>::type::iterator &,
+        ScratchData &,
+        CopyData &),
+      void (MainClass::*copier)(const CopyData &),
+      const ScratchData &sample_scratch_data,
+      const CopyData &   sample_copy_data,
+      const unsigned int queue_length = 2 * MultithreadInfo::n_threads(),
+      const unsigned int chunk_size   = 8)
+  {
+    // Call the function above
+    run(std::begin(iterator_range),
+        std::end(iterator_range),
+        main_object,
+        worker,
+        copier,
+        sample_scratch_data,
+        sample_copy_data,
+        queue_length,
+        chunk_size);
+  }
+
+
+
+  /**
+   * Same as the function above, but for deal.II's IteratorRange.
+   */
+  template <typename MainClass,
+            typename Iterator,
+            typename ScratchData,
+            typename CopyData>
+  void
+  run(IteratorRange<Iterator> iterator_range,
+      MainClass &             main_object,
+      void (MainClass::*worker)(const Iterator &, ScratchData &, CopyData &),
+      void (MainClass::*copier)(const CopyData &),
+      const ScratchData &sample_scratch_data,
+      const CopyData &   sample_copy_data,
+      const unsigned int queue_length = 2 * MultithreadInfo::n_threads(),
+      const unsigned int chunk_size   = 8)
+  {
+    // Call the function above
+    run(std::begin(iterator_range),
+        std::end(iterator_range),
+        main_object,
+        worker,
+        copier,
+        sample_scratch_data,
+        sample_copy_data,
+        queue_length,
+        chunk_size);
+  }
+
 } // namespace WorkStream
 
 
diff --git a/tests/base/work_stream_01a.cc b/tests/base/work_stream_01a.cc
new file mode 100644 (file)
index 0000000..37c6a50
--- /dev/null
@@ -0,0 +1,72 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2008 - 2017 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+// test functions in namespace WorkStream
+// This test is based off base/work_stream_01.cc, but for iterator ranges
+
+#include <deal.II/base/work_stream.h>
+
+#include "../tests.h"
+
+
+struct ScratchData
+{};
+
+
+struct CopyData
+{
+  unsigned int computed;
+};
+
+
+struct X
+{
+  void
+  worker(const std::vector<unsigned int>::iterator &i,
+         ScratchData &,
+         CopyData &ad)
+  {
+    ad.computed = *i * 2;
+  }
+
+  void
+  copier(const CopyData &ad)
+  {
+    deallog << ad.computed << std::endl;
+  }
+};
+
+
+void
+test()
+{
+  std::vector<unsigned int> v;
+  for (unsigned int i = 0; i < 20; ++i)
+    v.push_back(i);
+
+  X x;
+  WorkStream::run(v, x, &X::worker, &X::copier, ScratchData(), CopyData());
+}
+
+
+
+int
+main()
+{
+  initlog();
+
+  test();
+}
diff --git a/tests/base/work_stream_01a.output b/tests/base/work_stream_01a.output
new file mode 100644 (file)
index 0000000..bc020eb
--- /dev/null
@@ -0,0 +1,21 @@
+
+DEAL::0
+DEAL::2
+DEAL::4
+DEAL::6
+DEAL::8
+DEAL::10
+DEAL::12
+DEAL::14
+DEAL::16
+DEAL::18
+DEAL::20
+DEAL::22
+DEAL::24
+DEAL::26
+DEAL::28
+DEAL::30
+DEAL::32
+DEAL::34
+DEAL::36
+DEAL::38
diff --git a/tests/base/work_stream_01b.cc b/tests/base/work_stream_01b.cc
new file mode 100644 (file)
index 0000000..2001991
--- /dev/null
@@ -0,0 +1,82 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2008 - 2017 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+// test functions in namespace WorkStream
+// This test is based off base/work_stream_01.cc, but for iterator ranges
+
+#include <deal.II/base/work_stream.h>
+
+#include <deal.II/grid/filtered_iterator.h>
+
+#include "../tests.h"
+
+
+struct ScratchData
+{};
+
+
+struct CopyData
+{
+  unsigned int computed;
+};
+
+
+using IteratorType      = typename std::vector<unsigned int>::iterator;
+using IteratorRangeType = IteratorRange<IteratorType>;
+
+static_assert(
+  std::is_same<typename IteratorRangeType::iterator, IteratorType>::value,
+  "Iterator types not the same");
+
+struct X
+{
+  void
+  worker(const IteratorType &i, ScratchData &, CopyData &ad)
+  {
+    ad.computed = *i * 2;
+  }
+
+  void
+  copier(const CopyData &ad)
+  {
+    deallog << ad.computed << std::endl;
+  }
+};
+
+
+void
+test()
+{
+  std::vector<unsigned int> v;
+  for (unsigned int i = 0; i < 20; ++i)
+    v.push_back(i);
+
+  const IteratorRangeType iterator_range(v.begin(), v.end());
+
+  X x;
+  WorkStream::run(
+    iterator_range, x, &X::worker, &X::copier, ScratchData(), CopyData());
+}
+
+
+
+int
+main()
+{
+  initlog();
+
+  test();
+}
diff --git a/tests/base/work_stream_01b.output b/tests/base/work_stream_01b.output
new file mode 100644 (file)
index 0000000..bc020eb
--- /dev/null
@@ -0,0 +1,21 @@
+
+DEAL::0
+DEAL::2
+DEAL::4
+DEAL::6
+DEAL::8
+DEAL::10
+DEAL::12
+DEAL::14
+DEAL::16
+DEAL::18
+DEAL::20
+DEAL::22
+DEAL::24
+DEAL::26
+DEAL::28
+DEAL::30
+DEAL::32
+DEAL::34
+DEAL::36
+DEAL::38

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.