12 #ifndef ROOT_TThreadExecutor 13 #define ROOT_TThreadExecutor 15 #include "RConfigure.h" 20 # if !defined(__ROOTCLING__) && !defined(G__DICTIONARY) 21 # error "Cannot use ROOT::TThreadExecutor without defining R__USE_IMT." 45 void Foreach(
F func,
unsigned nTimes);
46 template<
class F,
class INTEGER>
49 template<
class F,
class T>
50 void Foreach(
F func, std::initializer_list<T> args);
52 template<
class F,
class T>
53 void Foreach(
F func, std::vector<T> &args);
56 template<
class F,
class Cond = noReferenceCond<F>>
58 template<
class F,
class INTEGER,
class Cond = noReferenceCond<F, INTEGER>>
60 template<
class F,
class T,
class Cond = noReferenceCond<F, T>>
68 template<
class F,
class R,
class Cond = noReferenceCond<F>>
70 template<
class F,
class R,
class Cond = noReferenceCond<F>>
72 template<
class F,
class INTEGER,
class R,
class Cond = noReferenceCond<F, INTEGER>>
75 template<
class F,
class T,
class R,
class Cond = noReferenceCond<F, T>>
78 template<
class F,
class T,
class R,
class Cond = noReferenceCond<F, T>>
80 template<
class F,
class T,
class R,
class Cond = noReferenceCond<F, T>>
84 template<
class T,
class BINARYOP>
auto Reduce(
const std::vector<T> &objs, BINARYOP redfunc) -> decltype(redfunc(objs.front(), objs.front()));
85 template<
class T,
class R>
auto Reduce(
const std::vector<T> &objs,
R redfunc) -> decltype(redfunc(objs));
88 template<
class F,
class R,
class Cond = noReferenceCond<F>>
90 template<
class F,
class INTEGER,
class R,
class Cond = noReferenceCond<F, INTEGER>>
92 template<
class F,
class T,
class R,
class Cond = noReferenceCond<F, T>>
94 template<
class F,
class T,
class R,
class Cond = noReferenceCond<F, T>>
101 template<
class T,
class R>
102 auto SeqReduce(
const std::vector<T> &objs,
R redfunc) -> decltype(redfunc(objs));
104 std::shared_ptr<ROOT::Internal::TPoolManager>
fSched =
nullptr;
115 ParallelFor(0U, nTimes, 1, [&](
unsigned int){func();});
121 template<
class F,
class INTEGER>
130 template<
class F,
class T>
132 std::vector<T> vargs(std::move(args));
140 template<
class F,
class T>
142 unsigned int nToProcess = args.size();
143 ParallelFor(0U, nToProcess, 1, [&](
unsigned int i){func(args[i]);});
151 template<
class F,
class Cond>
153 using retType = decltype(func());
154 std::vector<retType> reslist(nTimes);
155 auto lambda = [&](
unsigned int i)
168 template<
class F,
class INTEGER,
class Cond>
170 unsigned start = *args.begin();
171 unsigned end = *args.end();
172 unsigned seqStep = args.step();
174 using retType = decltype(func(start));
175 std::vector<retType> reslist(end - start);
176 auto lambda = [&](
unsigned int i)
178 reslist[i] = func(i);
189 template<
class F,
class R,
class Cond>
193 return Map(func, nTimes);
196 unsigned step = (nTimes + nChunks - 1) / nChunks;
198 unsigned actualChunks = (nTimes + step - 1) / step;
199 using retType = decltype(func());
200 std::vector<retType> reslist(actualChunks);
201 auto lambda = [&](
unsigned int i)
203 std::vector<retType> partialResults(std::min(nTimes-i, step));
204 for (
unsigned j = 0; j < step && (i + j) < nTimes; j++) {
205 partialResults[j] = func();
207 reslist[i / step] = redfunc(partialResults);
220 template<
class F,
class T,
class Cond>
223 using retType = decltype(func(args.front()));
225 unsigned int nToProcess = args.size();
226 std::vector<retType> reslist(nToProcess);
228 auto lambda = [&](
unsigned int i)
230 reslist[i] = func(args[i]);
243 template<
class F,
class INTEGER,
class R,
class Cond>
247 return Map(func, args);
250 unsigned start = *args.begin();
251 unsigned end = *args.end();
252 unsigned seqStep = args.step();
253 unsigned step = (end - start + nChunks - 1) / nChunks;
255 unsigned actualChunks = (end - start + step - 1) / step;
257 using retType = decltype(func(start));
258 std::vector<retType> reslist(actualChunks);
259 auto lambda = [&](
unsigned int i)
261 std::vector<retType> partialResults(std::min(end-i, step));
262 for (
unsigned j = 0; j < step && (i + j) < end; j+=seqStep) {
263 partialResults[j] = func(i + j);
265 reslist[i / step] = redfunc(partialResults);
278 template<
class F,
class T,
class R,
class Cond>
282 return Map(func, args);
285 unsigned int nToProcess = args.size();
286 unsigned step = (nToProcess + nChunks - 1) / nChunks;
288 unsigned actualChunks = (nToProcess + step - 1) / step;
290 using retType = decltype(func(args.front()));
291 std::vector<retType> reslist(actualChunks);
292 auto lambda = [&](
unsigned int i)
294 std::vector<T> partialResults(step);
295 for (
unsigned j = 0; j < step && (i + j) < nToProcess; j++) {
296 partialResults[j] = func(args[i + j]);
298 reslist[i / step] = redfunc(partialResults);
311 template<
class F,
class T,
class R,
class Cond>
313 std::vector<T> vargs(std::move(args));
314 const auto &reslist =
Map(func, vargs, redfunc, nChunks);
327 template<
class F,
class R,
class Cond>
329 return Reduce(
Map(func, nTimes), redfunc);
332 template<
class F,
class R,
class Cond>
334 return Reduce(
Map(func, nTimes, redfunc, nChunks), redfunc);
337 template<
class F,
class INTEGER,
class R,
class Cond>
339 return Reduce(
Map(func, args, redfunc, nChunks), redfunc);
342 template<
class F,
class T,
class R,
class Cond>
344 return Reduce(
Map(func, args, redfunc, nChunks), redfunc);
348 template<
class F,
class T,
class R,
class Cond>
353 template<
class F,
class T,
class R,
class Cond>
355 return Reduce(
Map(func, args, redfunc, nChunks), redfunc);
361 template<
class T,
class BINARYOP>
365 static_assert(std::is_same<decltype(redfunc(objs.front(), objs.front())),
T>::value,
"redfunc does not have the correct signature");
372 template<
class T,
class R>
376 static_assert(std::is_same<decltype(redfunc(objs)),
T>::value,
"redfunc does not have the correct signature");
380 template<
class T,
class R>
383 return redfunc(objs);
void Foreach(F func, unsigned nTimes)
Execute func (with no arguments) nTimes in parallel.
Namespace for new ROOT classes and functions.
auto SeqReduce(const std::vector< T > &objs, R redfunc) -> decltype(redfunc(objs))
void ParallelFor(unsigned start, unsigned end, unsigned step, const std::function< void(unsigned int i)> &f)
This class defines an interface to execute the same task multiple times in parallel, possibly with different arguments every time.
double ParallelReduce(const std::vector< double > &objs, const std::function< double(double a, double b)> &redfunc)
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
auto Reduce(const std::vector< T > &objs, BINARYOP redfunc) -> decltype(redfunc(objs.front(), objs.front()))
"Reduce" an std::vector into a single object in parallel by passing a binary operator as the second a...
This class provides a simple interface to execute the same task multiple times in parallel...
TThreadExecutor & operator=(TThreadExecutor &)=delete
TThreadExecutor()
Class constructor.
A pseudo container class which is a generator of indices.
auto MapReduce(F func, unsigned nTimes, R redfunc) -> typename std::result_of< F()>::type
This method behaves just like Map, but an additional redfunc function must be provided.
auto Map(F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
Execute func (with no arguments) nTimes in parallel.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
std::shared_ptr< ROOT::Internal::TPoolManager > fSched