From 4a89471223632a01eabc659ec16f50059427f74d Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Sun, 5 Dec 2021 14:50:48 -0700 Subject: [PATCH] Minimal change to make WorkStream work with newer TBB versions. --- include/deal.II/base/work_stream.h | 55 +++++++++++++++++------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/include/deal.II/base/work_stream.h b/include/deal.II/base/work_stream.h index 9810a6de06..ac8ae1e4df 100644 --- a/include/deal.II/base/work_stream.h +++ b/include/deal.II/base/work_stream.h @@ -186,7 +186,7 @@ namespace WorkStream * A class that creates a sequence of items from a range of iterators. */ template - class IteratorRangeToItemStream : public tbb::filter + class IteratorRangeToItemStream { public: /** @@ -326,8 +326,7 @@ namespace WorkStream const unsigned int chunk_size, const ScratchData &sample_scratch_data, const CopyData & sample_copy_data) - : tbb::filter(/*is_serial=*/true) - , remaining_iterator_range(begin, end) + : remaining_iterator_range(begin, end) , item_buffer(buffer_size) , sample_scratch_data(sample_scratch_data) , chunk_size(chunk_size) @@ -352,8 +351,8 @@ namespace WorkStream /** * Create an item and return a pointer to it. */ - virtual void * - operator()(void *) override + void * + operator()() { // find first unused item. we know that there must be one // because we have set the maximal number of tokens in flight @@ -472,7 +471,7 @@ namespace WorkStream * can run in parallel. */ template - class TBBWorker : public tbb::filter + class TBBWorker { public: /** @@ -484,8 +483,7 @@ namespace WorkStream const std::function & worker, bool copier_exist = true) - : tbb::filter(/* is_serial= */ false) - , worker(worker) + : worker(worker) , copier_exist(copier_exist) {} @@ -494,7 +492,7 @@ namespace WorkStream * Work on an item. */ void * - operator()(void *item) override + operator()(void *&item) const { // first unpack the current item using ItemType = @@ -609,7 +607,7 @@ namespace WorkStream * This flag is true if the copier stage exist. If it does not, the * worker has to free the buffer. Otherwise the copier will do it. */ - bool copier_exist; + const bool copier_exist; }; @@ -620,7 +618,7 @@ namespace WorkStream * items are copied in the same order in which they are created. */ template - class TBBCopier : public tbb::filter + class TBBCopier { public: /** @@ -630,8 +628,7 @@ namespace WorkStream * similar. */ TBBCopier(const std::function &copier) - : tbb::filter(/*is_serial=*/true) - , copier(copier) + : copier(copier) {} @@ -639,7 +636,7 @@ namespace WorkStream * Work on a single item. */ void * - operator()(void *item) override + operator()(void *&item) const { // first unpack the current item using ItemType = @@ -703,26 +700,36 @@ namespace WorkStream { // create the three stages of the pipeline IteratorRangeToItemStream - iterator_range_to_item_stream(begin, + iterator_range_to_item_stream(begin, end, queue_length, chunk_size, sample_scratch_data, sample_copy_data); + auto tbb_item_stream_filter = tbb::make_filter( + tbb::filter::serial, [&](tbb::flow_control &fc) -> void * { + if (const auto item = iterator_range_to_item_stream()) + return item; + else + { + fc.stop(); + return nullptr; + } + }); TBBWorker worker_filter(worker); + auto tbb_worker_filter = + tbb::make_filter(tbb::filter::parallel, + worker_filter); + TBBCopier copier_filter(copier); + auto tbb_copier_filter = + tbb::make_filter(tbb::filter::serial, copier_filter); // now create a pipeline from these stages - tbb::pipeline assembly_line; - assembly_line.add_filter(iterator_range_to_item_stream); - assembly_line.add_filter(worker_filter); - assembly_line.add_filter(copier_filter); - - // and run it - assembly_line.run(queue_length); - - assembly_line.clear(); + tbb::parallel_pipeline(queue_length, + tbb_item_stream_filter & tbb_worker_filter & + tbb_copier_filter); } } // namespace tbb_no_coloring -- 2.39.5