Geant4-11
TaskGroup.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// ---------------------------------------------------------------
21// Tasking class header file
22//
23// Class Description:
24//
25// This file creates the a class for handling a group of tasks that
26// can be independently joined
27//
28// ---------------------------------------------------------------
29// Author: Jonathan Madsen (Feb 13th 2018)
30// ---------------------------------------------------------------
31
32#pragma once
33
34#include "PTL/JoinFunction.hh"
35#include "PTL/Task.hh"
36#include "PTL/ThreadData.hh"
37#include "PTL/ThreadPool.hh"
38
39#include <atomic>
40#include <cstdint>
41#include <cstdlib>
42#include <deque>
43#include <future>
44#include <iostream>
45#include <memory>
46#include <vector>
47
48#if defined(PTL_USE_TBB)
49# include <tbb/tbb.h>
50#endif
51
52namespace PTL
53{
54namespace internal
55{
56std::atomic_uintmax_t&
58
61
62intmax_t
64} // namespace internal
65template <typename Tp, typename Arg = Tp, intmax_t MaxDepth = 0>
67{
68public:
69 //------------------------------------------------------------------------//
70 template <typename Up>
71 using container_type = std::vector<Up>;
72
73 using tid_type = std::thread::id;
74 using size_type = uintmax_t;
75 using lock_t = Mutex;
76 using atomic_int = std::atomic_intmax_t;
77 using atomic_uint = std::atomic_uintmax_t;
80 using result_type = Tp;
81 using task_pointer = std::shared_ptr<TaskFuture<ArgTp>>;
84 using promise_type = std::promise<ArgTp>;
85 using future_type = std::future<ArgTp>;
86 using packaged_task_type = std::packaged_task<ArgTp()>;
89 using iterator = typename future_list_t::iterator;
90 using reverse_iterator = typename future_list_t::reverse_iterator;
91 using const_iterator = typename future_list_t::const_iterator;
92 using const_reverse_iterator = typename future_list_t::const_reverse_iterator;
93 //------------------------------------------------------------------------//
94 template <typename... Args>
96 //------------------------------------------------------------------------//
97
98public:
99 // Constructor
100 template <typename Func>
102
103 template <typename Up = Tp>
105 enable_if_t<std::is_void<Up>::value, int> = 0);
106
107 // Destructor
109
110 // delete copy-construct
111 TaskGroup(const this_type&) = delete;
112 // define move-construct
113 TaskGroup(this_type&& rhs) = default;
114 // delete copy-assign
115 this_type& operator=(const this_type& rhs) = delete;
116 // define move-assign
117 this_type& operator=(this_type&& rhs) = default;
118
119public:
120 template <typename Up>
121 std::shared_ptr<Up> operator+=(std::shared_ptr<Up>&& _task);
122
123 // wait to finish
124 void wait();
125
126 // increment (prefix)
127 intmax_t operator++() { return ++(m_tot_task_count); }
128 intmax_t operator++(int) { return (m_tot_task_count)++; }
129 intmax_t operator--() { return --(m_tot_task_count); }
130 intmax_t operator--(int) { return (m_tot_task_count)--; }
131
132 // size
133 intmax_t size() const { return m_tot_task_count.load(); }
134
135 // get the locks/conditions
138
139 // identifier
140 uintmax_t id() const { return m_id; }
141
142 // thread pool
144 ThreadPool*& pool() { return m_pool; }
145 ThreadPool* pool() const { return m_pool; }
146
147 bool is_native_task_group() const { return (m_tbb_task_group) ? false : true; }
148 bool is_main() const { return this_tid() == m_main_tid; }
149
150 // check if any tasks are still pending
151 intmax_t pending() { return m_tot_task_count.load(); }
152
153 static void set_verbose(int level) { f_verbose = level; }
154
156
157 void notify();
159 void reserve(size_t _n)
160 {
161 m_task_list.reserve(_n);
162 m_future_list.reserve(_n);
163 }
164
165public:
166 template <typename Func, typename... Args>
167 std::shared_ptr<task_type<Args...>> wrap(Func func, Args... args)
168 {
169 return operator+=(std::make_shared<task_type<Args...>>(
170 is_native_task_group(), m_depth, std::move(func), std::move(args)...));
171 }
172
173 template <typename Func, typename... Args, typename Up = Tp>
175
176 template <typename Func, typename... Args, typename Up = Tp>
178
179 template <typename Func, typename... Args>
180 void run(Func func, Args... args)
181 {
182 exec(std::move(func), std::move(args)...);
183 }
184
185protected:
186 template <typename Up, typename Func, typename... Args>
188
189 template <typename Up, typename Func, typename... Args>
191
192 // shorter typedefs
197
198public:
199 //------------------------------------------------------------------------//
200 // Get tasks with non-void return types
201 //
203 const future_list_t& get_tasks() const { return m_future_list; }
204
205 //------------------------------------------------------------------------//
206 // iterate over tasks with return type
207 //
208 itr_t begin() { return m_future_list.begin(); }
209 itr_t end() { return m_future_list.end(); }
210 citr_t begin() const { return m_future_list.begin(); }
211 citr_t end() const { return m_future_list.end(); }
212 citr_t cbegin() const { return m_future_list.begin(); }
213 citr_t cend() const { return m_future_list.end(); }
214 ritr_t rbegin() { return m_future_list.rbegin(); }
215 ritr_t rend() { return m_future_list.rend(); }
216 critr_t rbegin() const { return m_future_list.rbegin(); }
217 critr_t rend() const { return m_future_list.rend(); }
218
219 //------------------------------------------------------------------------//
220 // wait to finish
221 template <typename Up = Tp, enable_if_t<!std::is_void<Up>::value, int> = 0>
222 inline Up join(Up accum = {});
223 //------------------------------------------------------------------------//
224 // wait to finish
225 template <typename Up = Tp, typename Rp = Arg,
226 enable_if_t<std::is_void<Up>::value && std::is_void<Rp>::value, int> = 0>
227 inline void join();
228 //------------------------------------------------------------------------//
229 // wait to finish
230 template <typename Up = Tp, typename Rp = Arg,
231 enable_if_t<std::is_void<Up>::value && !std::is_void<Rp>::value, int> = 0>
232 inline void join();
233 //------------------------------------------------------------------------//
234 // clear the task result history
235 void clear();
236
237protected:
238 //------------------------------------------------------------------------//
239 // get the thread id
240 static tid_type this_tid() { return std::this_thread::get_id(); }
241
242 //------------------------------------------------------------------------//
243 // get the task count
245 const atomic_int& task_count() const { return m_tot_task_count; }
246
247protected:
248 static int f_verbose;
249 // Private variables
252 tid_type m_main_tid = std::this_thread::get_id();
261
262private:
264};
265
266} // namespace PTL
267
268#include "PTL/TaskGroup.icc"
static char ** args
Definition: G4Xt.cc:51
ritr_t rend()
Definition: TaskGroup.hh:215
intmax_t operator++()
Definition: TaskGroup.hh:127
void internal_update()
std::atomic_intmax_t atomic_int
Definition: TaskGroup.hh:76
itr_t begin()
Definition: TaskGroup.hh:208
container_type< future_type > future_list_t
Definition: TaskGroup.hh:87
typename future_list_t::reverse_iterator reverse_iterator
Definition: TaskGroup.hh:90
ThreadPool * pool() const
Definition: TaskGroup.hh:145
std::promise< ArgTp > promise_type
Definition: TaskGroup.hh:84
intmax_t size() const
Definition: TaskGroup.hh:133
future_list_t m_future_list
Definition: TaskGroup.hh:260
Up join(Up accum={})
tbb_task_group_t * m_tbb_task_group
Definition: TaskGroup.hh:258
std::atomic_uintmax_t atomic_uint
Definition: TaskGroup.hh:77
std::vector< Up > container_type
Definition: TaskGroup.hh:71
decay_t< Arg > ArgTp
Definition: TaskGroup.hh:79
ritr_t rbegin()
Definition: TaskGroup.hh:214
TaskGroup(const this_type &)=delete
iterator itr_t
Definition: TaskGroup.hh:193
ThreadPool * m_pool
Definition: TaskGroup.hh:257
const atomic_int & task_count() const
Definition: TaskGroup.hh:245
typename JoinFunction< Tp, Arg >::Type join_type
Definition: TaskGroup.hh:88
citr_t end() const
Definition: TaskGroup.hh:211
citr_t cbegin() const
Definition: TaskGroup.hh:212
intmax_t operator++(int)
Definition: TaskGroup.hh:128
TaskGroup(ThreadPool *_tp=internal::get_default_threadpool(), enable_if_t< std::is_void< Up >::value, int >=0)
const future_list_t & get_tasks() const
Definition: TaskGroup.hh:203
bool is_native_task_group() const
Definition: TaskGroup.hh:147
citr_t cend() const
Definition: TaskGroup.hh:213
typename future_list_t::const_iterator const_iterator
Definition: TaskGroup.hh:91
intmax_t operator--()
Definition: TaskGroup.hh:129
std::packaged_task< ArgTp()> packaged_task_type
Definition: TaskGroup.hh:86
critr_t rend() const
Definition: TaskGroup.hh:217
static void set_verbose(int level)
Definition: TaskGroup.hh:153
enable_if_t< std::is_void< Up >::value, void > local_exec(Func func, Args... args)
std::thread::id tid_type
Definition: TaskGroup.hh:73
join_type m_join
Definition: TaskGroup.hh:256
task_list_t m_task_list
Definition: TaskGroup.hh:259
Condition condition_t
Definition: TaskGroup.hh:78
static tid_type this_tid()
Definition: TaskGroup.hh:240
atomic_int m_tot_task_count
Definition: TaskGroup.hh:253
atomic_int & task_count()
Definition: TaskGroup.hh:244
const_reverse_iterator critr_t
Definition: TaskGroup.hh:196
const_iterator citr_t
Definition: TaskGroup.hh:194
ThreadPool *& pool()
Definition: TaskGroup.hh:144
static int f_verbose
Definition: TaskGroup.hh:248
condition_t & task_cond()
Definition: TaskGroup.hh:137
intmax_t operator--(int)
Definition: TaskGroup.hh:130
tid_type m_main_tid
Definition: TaskGroup.hh:252
reverse_iterator ritr_t
Definition: TaskGroup.hh:195
lock_t m_task_lock
Definition: TaskGroup.hh:254
std::shared_ptr< task_type< Args... > > wrap(Func func, Args... args)
Definition: TaskGroup.hh:167
void run(Func func, Args... args)
Definition: TaskGroup.hh:180
future_list_t & get_tasks()
Definition: TaskGroup.hh:202
bool is_main() const
Definition: TaskGroup.hh:148
enable_if_t<!std::is_void< Up >::value, void > local_exec(Func func, Args... args)
uintmax_t size_type
Definition: TaskGroup.hh:74
typename future_list_t::iterator iterator
Definition: TaskGroup.hh:89
TaskGroup(Func &&_join, ThreadPool *_tp=internal::get_default_threadpool())
lock_t & task_lock()
Definition: TaskGroup.hh:136
enable_if_t< std::is_void< Up >::value, void > exec(Func func, Args... args)
uintmax_t id() const
Definition: TaskGroup.hh:140
citr_t begin() const
Definition: TaskGroup.hh:210
condition_t m_task_cond
Definition: TaskGroup.hh:255
intmax_t m_depth
Definition: TaskGroup.hh:251
uintmax_t m_id
Definition: TaskGroup.hh:250
typename future_list_t::const_reverse_iterator const_reverse_iterator
Definition: TaskGroup.hh:92
std::shared_ptr< TaskFuture< ArgTp > > task_pointer
Definition: TaskGroup.hh:81
void set_pool(ThreadPool *tp)
Definition: TaskGroup.hh:143
std::future< ArgTp > future_type
Definition: TaskGroup.hh:85
void reserve(size_t _n)
Definition: TaskGroup.hh:159
critr_t rbegin() const
Definition: TaskGroup.hh:216
TaskGroup(this_type &&rhs)=default
container_type< task_pointer > task_list_t
Definition: TaskGroup.hh:82
intmax_t pending()
Definition: TaskGroup.hh:151
enable_if_t<!std::is_void< Up >::value, void > exec(Func func, Args... args)
this_type & operator=(const this_type &rhs)=delete
this_type & operator=(this_type &&rhs)=default
ScopeDestructor get_scope_destructor()
std::shared_ptr< Up > operator+=(std::shared_ptr< Up > &&_task)
The task class is supplied to thread_pool.
Definition: Task.hh:132
std::shared_ptr< T > shared_ptr
Definition: memory.h:15
intmax_t get_task_depth()
Definition: TaskGroup.cc:61
ThreadPool * get_default_threadpool()
Definition: TaskGroup.cc:53
std::atomic_uintmax_t & task_group_counter()
Definition: TaskGroup.cc:46
Definition: AutoLock.hh:254
std::condition_variable Condition
Definition: Threading.hh:135
std::mutex Mutex
Definition: Threading.hh:77
typename std::decay< T >::type decay_t
Definition: Globals.hh:68
typename std::enable_if< B, T >::type enable_if_t
Definition: Globals.hh:71
std::function< JoinT(JoinT &, JoinArg &&)> Type
Definition: JoinFunction.hh:48