Logo ROOT  
Reference Guide
TSequentialExecutor.hxx
Go to the documentation of this file.
1// @(#)root/thread:$Id$
2// Author: Xavier Valls November 2017
3
4/*************************************************************************
5 * Copyright (C) 1995-2006, 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_TSequentialExecutor
12#define ROOT_TSequentialExecutor
13
14#include "RConfigure.h"
15
16#include "ROOT/TExecutor.hxx"
17#include <numeric>
18#include <vector>
19
20namespace ROOT {
21
22 class TSequentialExecutor: public TExecutor<TSequentialExecutor> {
23 public:
24 explicit TSequentialExecutor(){};
25
28
29 template<class F>
30 void Foreach(F func, unsigned nTimes);
31 template<class F, class INTEGER>
32 void Foreach(F func, ROOT::TSeq<INTEGER> args);
33 /// \cond
34 template<class F, class T>
35 void Foreach(F func, std::initializer_list<T> args);
36 /// \endcond
37 template<class F, class T>
38 void Foreach(F func, std::vector<T> &args);
39
41 template<class F, class Cond = noReferenceCond<F>>
42 auto Map(F func, unsigned nTimes) -> std::vector<typename std::result_of<F()>::type>;
43 template<class F, class INTEGER, class Cond = noReferenceCond<F, INTEGER>>
44 auto Map(F func, ROOT::TSeq<INTEGER> args) -> std::vector<typename std::result_of<F(INTEGER)>::type>;
45 template<class F, class T, class Cond = noReferenceCond<F, T>>
46 auto Map(F func, std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type>;
47
48 // // MapReduce
49 // // the late return types also check at compile-time whether redfunc is compatible with func,
50 // // other than checking that func is compatible with the type of arguments.
51 // // a static_assert check in TSequentialExecutor::Reduce is used to check that redfunc is compatible with the type returned by func
53 template<class F, class R, class Cond = noReferenceCond<F>>
54 auto MapReduce(F func, unsigned nTimes, R redfunc) -> typename std::result_of<F()>::type;
55 template<class F, class T, class R, class Cond = noReferenceCond<F, T>>
56 auto MapReduce(F func, std::vector<T> &args, R redfunc) -> typename std::result_of<F(T)>::type;
57
59 template<class T, class R> auto Reduce(const std::vector<T> &objs, R redfunc) -> decltype(redfunc(objs));
60 };
61
62 /************ TEMPLATE METHODS IMPLEMENTATION ******************/
63
64 //////////////////////////////////////////////////////////////////////////
65 /// Execute func (with no arguments) nTimes.
66 /// Functions that take more than zero arguments can be executed (with
67 /// fixed arguments) by wrapping them in a lambda or with std::bind.
68 template<class F>
69 void TSequentialExecutor::Foreach(F func, unsigned nTimes) {
70 for (auto i = 0U; i < nTimes; ++i) func();
71 }
72
73 //////////////////////////////////////////////////////////////////////////
74 /// Execute func, taking an element of a
75 /// sequence as argument.
76 template<class F, class INTEGER>
78 for(auto i : args) func(i);
79 }
80
81 /// \cond
82 //////////////////////////////////////////////////////////////////////////
83 /// Execute func, taking an element of a
84 /// initializer_list as argument.
85 template<class F, class T>
86 void TSequentialExecutor::Foreach(F func, std::initializer_list<T> args) {
87 std::vector<T> vargs(std::move(args));
88 Foreach(func, vargs);
89 }
90 /// \endcond
91
92 //////////////////////////////////////////////////////////////////////////
93 /// Execute func, taking an element of an
94 /// std::vector as argument.
95 template<class F, class T>
96 void TSequentialExecutor::Foreach(F func, std::vector<T> &args) {
97 unsigned int nToProcess = args.size();
98 for(auto i: ROOT::TSeqI(nToProcess)) func(args[i]);
99 }
100
101 //////////////////////////////////////////////////////////////////////////
102 /// Execute func (with no arguments) nTimes.
103 /// A vector containg executions' results is returned.
104 /// Functions that take more than zero arguments can be executed (with
105 /// fixed arguments) by wrapping them in a lambda or with std::bind.
106 template<class F, class Cond>
107 auto TSequentialExecutor::Map(F func, unsigned nTimes) -> std::vector<typename std::result_of<F()>::type> {
108 using retType = decltype(func());
109 std::vector<retType> reslist(nTimes);
110 for(auto i: ROOT::TSeqI(nTimes)) reslist[i] = func();
111 return reslist;
112 }
113
114 //////////////////////////////////////////////////////////////////////////
115 /// Execute func, taking an element of a
116 /// sequence as argument.
117 /// A vector containg executions' results is returned.
118 template<class F, class INTEGER, class Cond>
119 auto TSequentialExecutor::Map(F func, ROOT::TSeq<INTEGER> args) -> std::vector<typename std::result_of<F(INTEGER)>::type> {
120 using retType = decltype(func(*args.begin()));
121 std::vector<retType> reslist(args.size());
122 for(auto i: args) reslist[i] = func(i);
123 return reslist;
124 }
125
126 //////////////////////////////////////////////////////////////////////////
127 /// Execute func, taking an element of an
128 /// std::vector as argument.
129 /// A vector containg executions' results is returned.
130 // actual implementation of the Map method. all other calls with arguments eventually
131 // call this one
132 template<class F, class T, class Cond>
133 auto TSequentialExecutor::Map(F func, std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type> {
134 // //check whether func is callable
135 using retType = decltype(func(args.front()));
136 unsigned int nToProcess = args.size();
137 std::vector<retType> reslist(nToProcess);
138 for(auto i: ROOT::TSeqI(nToProcess)) reslist[i] = func(args[i]);
139 return reslist;
140 }
141
142 template<class F, class R, class Cond>
143 auto TSequentialExecutor::MapReduce(F func, unsigned nTimes, R redfunc) -> typename std::result_of<F()>::type {
144 return Reduce(Map(func, nTimes), redfunc);
145 }
146
147 template<class F, class T, class R, class Cond>
148 auto TSequentialExecutor::MapReduce(F func, std::vector<T> &args, R redfunc) -> typename std::result_of<F(T)>::type {
149 return Reduce(Map(func, args), redfunc);
150 }
151
152 //////////////////////////////////////////////////////////////////////////
153 /// "Reduce" an std::vector into a single object by passing a
154 /// function as the second argument defining the reduction operation.
155 template<class T, class R>
156 auto TSequentialExecutor::Reduce(const std::vector<T> &objs, R redfunc) -> decltype(redfunc(objs))
157 {
158 // check we can apply reduce to objs
159 static_assert(std::is_same<decltype(redfunc(objs)), T>::value, "redfunc does not have the correct signature");
160 return redfunc(objs);
161 }
162
163} // namespace ROOT
164#endif
#define R(a, b, c, d, e, f, g, h, i)
Definition: RSha256.hxx:110
int type
Definition: TGX11.cxx:120
This class defines an interface to execute the same task multiple times in parallel,...
Definition: TExecutor.hxx:61
A pseudo container class which is a generator of indices.
Definition: TSeq.hxx:66
void Foreach(F func, unsigned nTimes)
Execute func (with no arguments) nTimes.
auto MapReduce(F func, unsigned nTimes, R redfunc) -> typename std::result_of< F()>::type
auto Map(F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
Execute func (with no arguments) nTimes.
auto Reduce(const std::vector< T > &objs, R redfunc) -> decltype(redfunc(objs))
"Reduce" an std::vector into a single object by passing a function as the second argument defining th...
TSequentialExecutor(TSequentialExecutor &)=delete
TSequentialExecutor & operator=(TSequentialExecutor &)=delete
#define F(x, y, z)
double T(double x)
Definition: ChebyshevPol.h:34
auto Map(Args &&... args) -> decltype(ROOT::Detail::VecOps::MapFromTuple(std::forward_as_tuple(args...), std::make_index_sequence< sizeof...(args) - 1 >()))
Create new collection applying a callable to the elements of the input collection.
Definition: RVec.hxx:910
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: StringConv.hxx:21