Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TExecutor.hxx
Go to the documentation of this file.
1// @(#)root/thread:$Id$
2// Author: Xavier Valls September 2020
3
4/*************************************************************************
5 * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11#ifndef ROOT_TExecutor
12#define ROOT_TExecutor
13
14#include "ROOT/RConfig.hxx"
16#include "ROOT/TSeq.hxx"
18#ifdef R__USE_IMT
20#endif
21#ifndef R__WIN32
23#endif
24#include "TROOT.h"
26
27#include <initializer_list>
28#include <memory>
29#include <thread>
30#include <type_traits> //std::enable_if
31#include <stdexcept> //std::invalid_argument
32#include <utility> //std::move
33
34namespace ROOT{
35
36namespace Internal{
37class TExecutor: public TExecutorCRTP<TExecutor> {
39
40public:
41
42 /// \brief Class constructor. Sets the default execution policy and initializes the corresponding executor.
43 /// Defaults to multithreaded execution policy if ROOT is compiled with IMT=ON and IsImplicitMTEnabled. Otherwise it defaults to a serial execution policy
44 /// \param nWorkers [optional] Number of parallel workers, only taken into account if the execution policy is kMultiThread
45 explicit TExecutor(unsigned nWorkers = 0) :
47
48 /// \brief Class constructor. Sets the execution policy and initializes the corresponding executor.
49 /// \param execPolicy Execution policy(kMultiThread, kMultiprocess, kSerial) to process the data
50 /// \param nWorkers [optional] Number of parallel workers, only taken into account if the execution policy is kMultiThread
51 explicit TExecutor(ROOT::EExecutionPolicy execPolicy, unsigned nWorkers = 0);
52
53 TExecutor(const TExecutor &) = delete;
54 TExecutor &operator=(const TExecutor &) = delete;
55
56 /// Return the execution policy the executor is set to
58
59 // Map
60 //
62
63 // MapReduce
64 // the late return types also check at compile-time whether redfunc is compatible with func,
65 // other than checking that func is compatible with the type of arguments.
66 // a static_assert check in TExecutor::Reduce is used to check that redfunc is compatible with the type returned by func
68 template <class F, class R, class Cond = validMapReturnCond<F>>
69 auto MapReduce(F func, unsigned nTimes, R redfunc, unsigned nChunks) -> InvokeResult_t<F>;
70 template <class F, class INTEGER, class R, class Cond = validMapReturnCond<F, INTEGER>>
71 auto MapReduce(F func, ROOT::TSeq<INTEGER> args, R redfunc, unsigned nChunks) -> InvokeResult_t<F, INTEGER>;
72 template <class F, class T, class R, class Cond = validMapReturnCond<F, T>>
73 auto MapReduce(F func, std::initializer_list<T> args, R redfunc, unsigned nChunks) -> InvokeResult_t<F, T>;
74 template <class F, class T, class R, class Cond = validMapReturnCond<F, T>>
75 auto MapReduce(F func, std::vector<T> &args, R redfunc, unsigned nChunks) -> InvokeResult_t<F, T>;
76 template <class F, class T, class R, class Cond = validMapReturnCond<F, T>>
77 auto MapReduce(F func, const std::vector<T> &args, R redfunc, unsigned nChunks) -> InvokeResult_t<F, T>;
78
79 // Reduce
80 //
82
83 unsigned GetPoolSize() const;
84
85private:
86 // Implementation of the Map functions declared in the parent class (TExecutorCRTP)
87 //
88 template <class F, class Cond = validMapReturnCond<F>>
89 auto MapImpl(F func, unsigned nTimes) -> std::vector<InvokeResult_t<F>>;
90 template <class F, class INTEGER, class Cond = validMapReturnCond<F, INTEGER>>
91 auto MapImpl(F func, ROOT::TSeq<INTEGER> args) -> std::vector<InvokeResult_t<F, INTEGER>>;
92 template <class F, class T, class Cond = validMapReturnCond<F, T>>
93 auto MapImpl(F func, std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>;
94 template <class F, class T, class Cond = validMapReturnCond<F, T>>
95 auto MapImpl(F func, const std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>;
96
98
99 // When they are not available, we use a placeholder type instead of TThreadExecutor or TProcessExecutor.
100 // The corresponding data members will not be used.
102#ifdef R__USE_IMT
103# define R__EXECUTOR_THREAD ROOT::TThreadExecutor
104#else
105# define R__EXECUTOR_THREAD Unused_t
106#endif
107#ifndef R__WIN32
108# define R__EXECUTOR_PROCESS ROOT::TProcessExecutor
109#else
110# define R__EXECUTOR_PROCESS Unused_t
111#endif
112
113 std::unique_ptr<R__EXECUTOR_THREAD> fThreadExecutor;
114 std::unique_ptr<R__EXECUTOR_PROCESS> fProcessExecutor;
115 std::unique_ptr<ROOT::TSequentialExecutor> fSequentialExecutor;
116
117#undef R__EXECUTOR_THREAD
118#undef R__EXECUTOR_PROCESS
119
120 /// \brief Helper class to get the correct return type from the Map function,
121 /// necessary to infer the ResolveExecutorAndMap function type
122 template<class F, class CONTAINER>
123 struct MapRetType {
125 };
126
127 template<class F>
128 struct MapRetType<F, unsigned> {
130 };
131
132
133 /// \brief Function called from Map to select and execute the correct Executor
134 /// according to the set Execution Policy.
135 template<class F, class T>
136 auto ResolveExecutorAndMap(F func, T&& args) -> std::vector<typename MapRetType<F, typename std::decay<T>::type>::type> {
137 std::vector<typename MapRetType<F, typename std::decay<T>::type>::type> res;
138 switch(fExecPolicy) {
140 res = fSequentialExecutor->Map(func, std::forward<T>(args));
141 break;
143 res = fThreadExecutor->Map(func, std::forward<T>(args));
144 break;
146 res = fProcessExecutor->Map(func, std::forward<T>(args));
147 break;
148 default:
149 break;
150 }
151 return res;
152 }
153};
154
155
156//////////////////////////////////////////////////////////////////////////
157/// \brief Execute a function without arguments several times.
158/// Implementation of the Map method.
159///
160/// \copydetails TExecutorCRTP::Map(F func,unsigned nTimes)
161template <class F, class Cond>
162auto TExecutor::MapImpl(F func, unsigned nTimes) -> std::vector<InvokeResult_t<F>>
163{
164 return ResolveExecutorAndMap(func, nTimes);
165}
166
167//////////////////////////////////////////////////////////////////////////
168/// \brief Execute a function over a sequence of indexes.
169/// Implementation of the Map method.
170///
171/// \copydetails TExecutorCRTP::Map(F func,ROOT::TSeq<INTEGER> args)
172template <class F, class INTEGER, class Cond>
173auto TExecutor::MapImpl(F func, ROOT::TSeq<INTEGER> args) -> std::vector<InvokeResult_t<F, INTEGER>>
174{
175 return ResolveExecutorAndMap(func, args);
176}
177
178//////////////////////////////////////////////////////////////////////////
179/// \brief Execute a function over the elements of a vector.
180/// Implementation of the Map method.
181///
182/// \copydetails TExecutorCRTP::Map(F func,std::vector<T> &args)
183template <class F, class T, class Cond>
184auto TExecutor::MapImpl(F func, std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>
185{
186 return ResolveExecutorAndMap(func, args);
187}
188
189//////////////////////////////////////////////////////////////////////////
190/// \brief Execute a function over the elements of an immutable vector.
191/// Implementation of the Map method.
192///
193/// \copydetails TExecutorCRTP::Map(F func,const std::vector<T> &args)
194template <class F, class T, class Cond>
195auto TExecutor::MapImpl(F func, const std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>
196{
197 return ResolveExecutorAndMap(func, args);
198}
199
200//////////////////////////////////////////////////////////////////////////
201/// \brief Execute a function `nTimes` (Map) and accumulate the results into a single value (Reduce).
202/// Benefits from partial reduction into `nChunks` intermediate results if the execution policy is multithreaded.
203/// Otherwise, <b>it ignores the nChunks argument</b> and performs a normal MapReduce operation.
204///
205/// \param func Function to be executed. Must take an element of the sequence passed as second argument as a parameter.
206/// \param nTimes Number of times function should be called.
207/// \param redfunc Reduction function to combine the results of the calls to `func` into partial results, and these
208/// into a final result. Must return the same type as `func` and should be callable with `const std::vector<T>` where T
209/// is the output of `func`.
210/// \param nChunks Number of chunks to split the input data for processing.
211/// \return A value result of "reducing" the vector returned by the Map operation into a single object.
212template <class F, class R, class Cond>
213auto TExecutor::MapReduce(F func, unsigned nTimes, R redfunc, unsigned nChunks) -> InvokeResult_t<F>
214{
215 // check we can apply reduce to objs
216 static_assert(std::is_invocable_v<R, std::vector<InvokeResult_t<F>>>, "redfunc does not have the correct signature");
217 if (fExecPolicy == ROOT::EExecutionPolicy::kMultiThread) {
218 return fThreadExecutor->MapReduce(func, nTimes, redfunc, nChunks);
219 }
220 return Reduce(Map(func, nTimes), redfunc);
221}
222
223//////////////////////////////////////////////////////////////////////////
224/// \brief Execute a function over a sequence of indexes (Map) and accumulate the results into a single value (Reduce).
225/// Benefits from partial reduction into `nChunks` intermediate results if the execution policy is multithreaded.
226/// Otherwise, <b>it ignores the nChunks argument</b> and performs a normal MapReduce operation.
227///
228/// \param func Function to be executed. Must take an element of the sequence passed assecond argument as a parameter.
229/// \param args Sequence of indexes to execute `func` on.
230/// \param redfunc Reduction function to combine the results of the calls to `func` into partial results, and these
231/// into a final result. Must return the same type as `func` and should be callable with `std::vector<T>` where T is the
232/// output of `func`.
233/// \param nChunks Number of chunks to split the input data for processing.
234/// \return A value result of "reducing" the vector returned by the Map operation into a single object.
235template <class F, class INTEGER, class R, class Cond>
236auto TExecutor::MapReduce(F func, ROOT::TSeq<INTEGER> args, R redfunc, unsigned nChunks) -> InvokeResult_t<F, INTEGER>
237{
238 static_assert(std::is_invocable_v<R, std::vector<InvokeResult_t<F, INTEGER>>>,
239 "redfunc does not have the correct signature");
240 if (fExecPolicy == ROOT::EExecutionPolicy::kMultiThread) {
241 return fThreadExecutor->MapReduce(func, args, redfunc, nChunks);
242 }
243 return Reduce(Map(func, args), redfunc);
244}
245
246//////////////////////////////////////////////////////////////////////////
247/// \brief Execute a function over the elements of an initializer_list (Map) and accumulate the results into a single
248/// value (Reduce). Benefits from partial reduction into `nChunks` intermediate results if the execution policy is
249/// multithreaded. Otherwise, <b>it ignores the nChunks argument</b> and performs a normal MapReduce operation.
250///
251/// \param func Function to be executed. Must take an element of the sequence passed as second argument as a parameter.
252/// \param args initializer_list for a vector to apply `func` on.
253/// \param redfunc Reduction function to combine the results of the calls to `func` into partial results, and these
254/// into a final result. Must return the same type as `func` and should be callable with `const std::vector<T>` where T
255/// is the output of `func`.
256/// \param nChunks Number of chunks to split the input data for processing.
257/// \return A value result of "reducing" the vector returned by the Map operation into a single object.
258template <class F, class T, class R, class Cond>
259auto TExecutor::MapReduce(F func, std::initializer_list<T> args, R redfunc, unsigned nChunks) -> InvokeResult_t<F, T>
260{
261 static_assert(std::is_invocable_v<R, std::vector<InvokeResult_t<F, T>>>,
262 "redfunc does not have the correct signature");
263 if (fExecPolicy == ROOT::EExecutionPolicy::kMultiThread) {
264 return fThreadExecutor->MapReduce(func, args, redfunc, nChunks);
265 }
266 return Reduce(Map(func, args), redfunc);
267}
268
269//////////////////////////////////////////////////////////////////////////
270/// \brief Execute a function over the elements of a vector (Map) and accumulate the results into a single value
271/// (Reduce). Benefits from partial reduction into `nChunks` intermediate results if the execution policy is
272/// multithreaded. Otherwise, <b>it ignores the nChunks argument</b> and performs a normal MapReduce operation.
273///
274/// \param func Function to be executed. Must take an element of the sequence passed assecond argument as a parameter.
275/// \param args Vector of elements passed as an argument to `func`.
276/// \param redfunc Reduction function to combine the results of the calls to `func` into partial results, and these
277/// into a final result. Must return the same type as `func` and should be callable with `const std::vector<T>` where T
278/// is the output of `func`.
279/// \param nChunks Number of chunks to split the input data for processing.
280/// \return A value result of "reducing" the vector returned by the Map operation into a single object.
281template <class F, class T, class R, class Cond>
282auto TExecutor::MapReduce(F func, std::vector<T> &args, R redfunc, unsigned nChunks) -> InvokeResult_t<F, T>
283{
284 static_assert(std::is_invocable_v<R, std::vector<InvokeResult_t<F, T>>>,
285 "redfunc does not have the correct signature");
286 if (fExecPolicy == ROOT::EExecutionPolicy::kMultiThread) {
287 return fThreadExecutor->MapReduce(func, args, redfunc, nChunks);
288 }
289 return Reduce(Map(func, args), redfunc);
290}
291
292//////////////////////////////////////////////////////////////////////////
293/// \brief Execute a function over the elements of an immutable vector (Map) and accumulate the results into a single
294/// value (Reduce). Benefits from partial reduction into `nChunks` intermediate results if the execution policy is
295/// multithreaded. Otherwise, <b>it ignores the nChunks argument</b> and performs a normal MapReduce operation.
296///
297/// \param func Function to be executed. Must take an element of the sequence passed assecond argument as a parameter.
298/// \param args Immutable vector, whose elements are passed as an argument to `func`.
299/// \param redfunc Reduction function to combine the results of the calls to `func` into partial results, and these
300/// into a final result. Must return the same type as `func` and should be callable with `const std::vector<T>` where T
301/// is the output of `func`.
302/// \param nChunks Number of chunks to split the input data for processing.
303/// \return A value result of "reducing" the vector returned by the Map operation into a single object.
304template <class F, class T, class R, class Cond>
305auto TExecutor::MapReduce(F func, const std::vector<T> &args, R redfunc, unsigned nChunks) -> InvokeResult_t<F, T>
306{
307 static_assert(std::is_invocable_v<R, std::vector<InvokeResult_t<F, T>>>,
308 "redfunc does not have the correct signature");
309 if (fExecPolicy == ROOT::EExecutionPolicy::kMultiThread) {
310 return fThreadExecutor->MapReduce(func, args, redfunc, nChunks);
311 }
312 return Reduce(Map(func, args), redfunc);
313}
314
315//////////////////////////////////////////////////////////////////////////
316/// \brief Return the number of pooled workers.
317///
318/// \return The number of workers in the pool in the executor used as a backend.
319
320inline unsigned TExecutor::GetPoolSize() const
321{
322 unsigned poolSize{0u};
323 switch(fExecPolicy){
325 poolSize = fSequentialExecutor->GetPoolSize();
326 break;
328 poolSize = fThreadExecutor->GetPoolSize();
329 break;
331 poolSize = fProcessExecutor->GetPoolSize();
332 break;
333 default:
334 break;
335 }
336 return poolSize;
337}
338
339} // namespace Internal
340} // namespace ROOT
341
342#endif
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
This class implements the interface to execute the same task multiple times, sequentially or in paral...
Definition TExecutor.hxx:37
auto MapReduce(F func, unsigned nTimes, R redfunc, unsigned nChunks) -> InvokeResult_t< F >
Execute a function nTimes (Map) and accumulate the results into a single value (Reduce).
auto ResolveExecutorAndMap(F func, T &&args) -> std::vector< typename MapRetType< F, typename std::decay< T >::type >::type >
Function called from Map to select and execute the correct Executor according to the set Execution Po...
std::unique_ptr< ROOT::TThreadExecutor > fThreadExecutor
std::unique_ptr< ROOT::TSequentialExecutor > fSequentialExecutor
ROOT::EExecutionPolicy Policy() const
Return the execution policy the executor is set to.
Definition TExecutor.hxx:57
auto MapImpl(F func, unsigned nTimes) -> std::vector< InvokeResult_t< F > >
Execute a function without arguments several times.
TExecutor(unsigned nWorkers=0)
Class constructor.
Definition TExecutor.hxx:45
TExecutor & operator=(const TExecutor &)=delete
TExecutor(const TExecutor &)=delete
ROOT::EExecutionPolicy fExecPolicy
Definition TExecutor.hxx:97
unsigned GetPoolSize() const
Return the number of pooled workers.
std::unique_ptr< ROOT::TProcessExecutor > fProcessExecutor
This class defines an interface to execute the same task multiple times, possibly in parallel and wit...
ROOT::TypeTraits::InvokeResult_t< F, Args... > InvokeResult_t
auto Map(F func, unsigned nTimes) -> std::vector< InvokeResult_t< F > >
Execute a function without arguments several times.
T * Reduce(const std::vector< T * > &mergeObjs)
"Reduce" an std::vector into a single object by using the object's Merge method.
A pseudo container class which is a generator of indices.
Definition TSeq.hxx:67
#define F(x, y, z)
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
Definition TROOT.cxx:568
Helper class to get the correct return type from the Map function, necessary to infer the ResolveExec...
InvokeResult_t< F, typename CONTAINER::value_type > type