Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
TBBTaskGroup.hh
Go to the documentation of this file.
1//
2// MIT License
3// Copyright (c) 2020 Jonathan R. Madsen
4// Permission is hereby granted, free of charge, to any person obtaining a copy
5// of this software and associated documentation files (the "Software"), to deal
6// in the Software without restriction, including without limitation the rights
7// to use, copy, modify, merge, publish, distribute, sublicense, and
8// copies of the Software, and to permit persons to whom the Software is
9// furnished to do so, subject to the following conditions:
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
12// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
13// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
16// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
17// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18//
19// ---------------------------------------------------------------
20// Tasking class header file
21//
22// Class Description:
23//
24// This file wraps a TBB task_group into a TaskGroup
25//
26// ---------------------------------------------------------------
27// Author: Jonathan Madsen (Jun 21st 2018)
28// ---------------------------------------------------------------
29
30#pragma once
31
32#include "PTL/TaskGroup.hh"
33#include <functional>
34#include <memory>
35
36#if defined(PTL_USE_TBB)
37# include <tbb/tbb.h>
38#endif
39
40namespace PTL
41{
42class ThreadPool;
43
44//--------------------------------------------------------------------------------------//
45#if defined(PTL_USE_TBB)
46
47class ThreadPool;
48namespace
49{
50typedef ::tbb::task_group tbb_task_group_t;
51}
52
53//--------------------------------------------------------------------------------------//
54
55template <typename Tp, typename Arg = Tp>
56class TBBTaskGroup : public TaskGroup<Tp, Arg>
57{
58public:
59 //------------------------------------------------------------------------//
60 typedef decay_t<Arg> ArgTp;
61 typedef TBBTaskGroup<Tp, Arg> this_type;
62 typedef TaskGroup<Tp, Arg> base_type;
63 typedef typename base_type::result_type result_type;
64 typedef typename base_type::packaged_task_type packaged_task_type;
65 typedef typename base_type::future_type future_type;
66 typedef typename base_type::promise_type promise_type;
67 typedef typename JoinFunction<Tp, Arg>::Type join_type;
68 typedef tbb::task_group tbb_task_group_t;
69 //------------------------------------------------------------------------//
70 template <typename... Args>
71 using task_type = Task<ArgTp, decay_t<Args>...>;
72 //------------------------------------------------------------------------//
73
74public:
75 // Constructor
76 template <typename Func>
77 TBBTaskGroup(Func&& _join, ThreadPool* _tp = nullptr)
78 : base_type(std::forward<Func>(_join), _tp)
79 , m_tbb_task_group(new tbb_task_group_t)
80 {}
81 template <typename Up = Tp, enable_if_t<std::is_same<Up, void>::value, int> = 0>
82 TBBTaskGroup(ThreadPool* _tp = nullptr)
83 : base_type(_tp)
84 , m_tbb_task_group(new tbb_task_group_t)
85 {}
86
87 // Destructor
88 virtual ~TBBTaskGroup()
89 {
90 delete m_tbb_task_group;
91 this->clear();
92 }
93
94 // delete copy-construct
95 TBBTaskGroup(const this_type&) = delete;
96 // define move-construct
97 TBBTaskGroup(this_type&& rhs) = default;
98
99 // delete copy-assign
100 this_type& operator=(const this_type& rhs) = delete;
101 // define move-assign
102 this_type& operator=(this_type&& rhs) = default;
103
104public:
105 //------------------------------------------------------------------------//
106 template <typename Up>
107 Up* operator+=(Up* _task)
108 {
109 // store in list
110 vtask_list.push_back(_task);
111 // thread-safe increment of tasks in task group
112 operator++();
113 // add the future
114 m_task_set.push_back(std::move(_task->get_future()));
115 // return
116 return _task;
117 }
118
119public:
120 //------------------------------------------------------------------------//
121 template <typename Func, typename... Args>
122 task_type<Args...>* wrap(Func&& func, Args... args)
123 {
124 return operator+=(
125 new task_type<Args...>(this, std::forward<Func>(func), args...));
126 }
127
128public:
129 //------------------------------------------------------------------------//
130 template <typename Func, typename... Args>
131 void run(Func&& func, Args... args)
132 {
133 auto _func = [=]() { return func(args...); };
134 auto _task = wrap(std::move(_func));
135 auto _lamb = [=]() { (*_task)(); };
136 m_tbb_task_group->run(_lamb);
137 }
138 //------------------------------------------------------------------------//
139 template <typename Func, typename... Args>
140 void exec(Func&& func, Args... args)
141 {
142 auto _func = [=]() { return func(args...); };
143 auto _task = wrap(std::move(_func));
144 auto _lamb = [=]() { (*_task)(); };
145 m_tbb_task_group->run(_lamb);
146 }
147 //------------------------------------------------------------------------//
148 template <typename Func, typename... Args, typename Up = Tp,
149 enable_if_t<std::is_same<Up, void>::value, int> = 0>
150 void parallel_for(uintmax_t nitr, uintmax_t, Func&& func, Args... args)
151 {
152 tbb::parallel_for(tbb::blocked_range<size_t>(0, nitr),
153 [&](const tbb::blocked_range<size_t>& range) {
154 for(size_t i = range.begin(); i != range.end(); ++i)
155 func(args...);
156 });
157 }
158
159public:
160 //------------------------------------------------------------------------//
161 // this is not a native Tasking task group
162 virtual bool is_native_task_group() const override { return false; }
163
164 //------------------------------------------------------------------------//
165 // wait on tbb::task_group, not internal thread-pool
166 virtual void wait() override
167 {
168 base_type::wait();
169 m_tbb_task_group->wait();
170 }
171
172public:
173 using base_type::begin;
174 using base_type::cbegin;
175 using base_type::cend;
176 using base_type::clear;
177 using base_type::end;
178 using base_type::get_tasks;
179
180 //------------------------------------------------------------------------//
181 // wait to finish
182 template <typename Up = Tp, enable_if_t<!std::is_void<Up>::value, int> = 0>
183 inline Up join(Up accum = {})
184 {
185 this->wait();
186 for(auto& itr : m_task_set)
187 {
188 using RetT = decay_t<decltype(itr.get())>;
189 accum = m_join(std::ref(accum), std::forward<RetT>(itr.get()));
190 }
191 this->clear();
192 return accum;
193 }
194 //------------------------------------------------------------------------//
195 // wait to finish
196 template <typename Up = Tp, typename Rp = Arg,
197 enable_if_t<std::is_void<Up>::value && std::is_void<Rp>::value, int> = 0>
198 inline void join()
199 {
200 this->wait();
201 for(auto& itr : m_task_set)
202 itr.get();
203 m_join();
204 this->clear();
205 }
206 //------------------------------------------------------------------------//
207 // wait to finish
208 template <typename Up = Tp, typename Rp = Arg,
209 enable_if_t<std::is_void<Up>::value && !std::is_void<Rp>::value, int> = 0>
210 inline void join()
211 {
212 this->wait();
213 for(auto& itr : m_task_set)
214 {
215 using RetT = decay_t<decltype(itr.get())>;
216 m_join(std::forward<RetT>(itr.get()));
217 }
218 this->clear();
219 }
220
221protected:
222 // Protected variables
223 tbb_task_group_t* m_tbb_task_group;
224 using base_type:: operator++;
225 using base_type:: operator--;
226 using base_type::m_join;
227 using base_type::m_task_set;
228 using base_type::vtask_list;
229};
230
231//--------------------------------------------------------------------------------------//
232#else
233//--------------------------------------------------------------------------------------//
234
235template <typename Tp, typename Arg = Tp>
237
238//--------------------------------------------------------------------------------------//
239#endif
240//--------------------------------------------------------------------------------------//
241
242} // namespace PTL
Definition: AutoLock.hh:254
TaskGroup< Tp, Arg > TBBTaskGroup
typename std::decay< T >::type decay_t
Definition: Globals.hh:52
tbb::task_group tbb_task_group_t
Definition: ThreadData.hh:88
std::function< JoinT(JoinT &, JoinArg &&)> Type
Definition: TaskGroup.hh:70