Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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-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_TSequentialExecutor
12#define ROOT_TSequentialExecutor
13
16#include "ROOT/TSeq.hxx"
17
18#include <initializer_list>
19#include <numeric> //std::accumulate
20#include <utility> //std::move
21#include <vector>
22
23namespace ROOT {
24
25 class TSequentialExecutor: public TExecutorCRTP<TSequentialExecutor> {
27
28 public:
29
33
34 // Foreach
35 //
36 template<class F>
37 void Foreach(F func, unsigned nTimes);
38 template<class F, class INTEGER>
39 void Foreach(F func, ROOT::TSeq<INTEGER> args);
40 template<class F, class T>
41 void Foreach(F func, std::initializer_list<T> args);
42 template<class F, class T>
43 void Foreach(F func, std::vector<T> &args);
44 template<class F, class T>
45 void Foreach(F func, const std::vector<T> &args);
46
47 // Map
48 //
50
51 // MapReduce
52 // the late return types also check at compile-time whether redfunc is compatible with func,
53 // other than checking that func is compatible with the type of arguments.
54 // a static_assert check in TSequentialExecutor::Reduce is used to check that redfunc is compatible with the type returned by func
56
57 // Reduce
58 //
60
61 //////////////////////////////////////////////////////////////////////////
62 /// \brief Return the number of workers in the sequential executor: a single one.
63 ///
64 /// \return The number of workers in the pool, one.
65 unsigned GetPoolSize() const { return 1u; }
66
67 private:
68 // Implementation of the Map functions declared in the parent class (TExecutorCRTP)
69 //
70 template<class F, class Cond = validMapReturnCond<F>>
71 auto MapImpl(F func, unsigned nTimes) -> std::vector<InvokeResult_t<F>>;
72 template<class F, class INTEGER, class Cond = validMapReturnCond<F, INTEGER>>
73 auto MapImpl(F func, ROOT::TSeq<INTEGER> args) -> std::vector<InvokeResult_t<F, INTEGER>>;
74 template<class F, class T, class Cond = validMapReturnCond<F, T>>
75 auto MapImpl(F func, std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>;
76 template<class F, class T, class Cond = validMapReturnCond<F, T>>
77 auto MapImpl(F func, const std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>;
78 };
79
80 /************ TEMPLATE METHODS IMPLEMENTATION ******************/
81
82 //////////////////////////////////////////////////////////////////////////
83 /// \brief Execute a function without arguments several times, dividing the execution in nChunks.
84 ///
85 /// \param func Function to be executed.
86 /// \param nTimes Number of times function should be called.
87 template<class F>
88 void TSequentialExecutor::Foreach(F func, unsigned nTimes) {
89 for (auto i = 0U; i < nTimes; ++i) func();
90 }
91
92 //////////////////////////////////////////////////////////////////////////
93 /// \brief Execute a function over a sequence of indexes, dividing the execution in nChunks.
94 ///
95 /// \param func Function to be executed. Must take an element of the sequence passed assecond argument as a parameter.
96 /// \param args Sequence of indexes to execute `func` on.
97 template<class F, class INTEGER>
99 for(auto i : args) func(i);
100 }
101
102 //////////////////////////////////////////////////////////////////////////
103 /// \brief Execute a function over the elements of an initializer_list, dividing the execution in nChunks.
104 ///
105 /// \param func Function to be executed on the elements of the initializer_list passed as second parameter.
106 /// \param args initializer_list for a vector to apply `func` on.
107 template<class F, class T>
108 void TSequentialExecutor::Foreach(F func, std::initializer_list<T> args) {
109 std::vector<T> vargs(std::move(args));
110 Foreach(func, vargs);
111 }
112
113 //////////////////////////////////////////////////////////////////////////
114 /// \brief Execute a function over the elements of a vector, dividing the execution in nChunks.
115 ///
116 /// \param func Function to be executed on the elements of the vector passed as second parameter.
117 /// \param args Vector of elements passed as an argument to `func`.
118 template<class F, class T>
119 void TSequentialExecutor::Foreach(F func, std::vector<T> &args) {
120 for(auto &&arg: args) {
121 func(arg);
122 }
123 }
124
125 //////////////////////////////////////////////////////////////////////////
126 /// \brief Execute a function over the elements of an immutable vector, dividing the execution in nChunks.
127 ///
128 /// \param func Function to be executed on the elements of the immutable vector passed as second parameter.
129 /// \param args Immutable vector of elements passed as an argument to `func`.
130 template<class F, class T>
131 void TSequentialExecutor::Foreach(F func, const std::vector<T> &args) {
132 for(auto &&arg: args) {
133 func(arg);
134 }
135 }
136
137 //////////////////////////////////////////////////////////////////////////
138 /// \brief Execute a function without arguments several times.
139 /// Implementation of the Map method.
140 ///
141 /// \copydetails TExecutorCRTP::Map(F func,unsigned nTimes)
142 template<class F, class Cond>
143 auto TSequentialExecutor::MapImpl(F func, unsigned nTimes) -> std::vector<InvokeResult_t<F>> {
144 using retType = decltype(func());
145 std::vector<retType> reslist;
146 reslist.reserve(nTimes);
147 while(reslist.size() < nTimes) {
148 reslist.emplace_back(func());
149 }
150 return reslist;
151 }
152
153 //////////////////////////////////////////////////////////////////////////
154 /// \brief Execute a function over a sequence of indexes.
155 /// Implementation of the Map method.
156 ///
157 /// \copydetails TExecutorCRTP::Map(F func,ROOT::TSeq<INTEGER> args)
158 template<class F, class INTEGER, class Cond>
159 auto TSequentialExecutor::MapImpl(F func, ROOT::TSeq<INTEGER> args) -> std::vector<InvokeResult_t<F, INTEGER>> {
160 using retType = decltype(func(*args.begin()));
161 std::vector<retType> reslist;
162 reslist.reserve(args.size());
163 for(auto i: args)
164 reslist.emplace_back(func(i));
165 return reslist;
166 }
167
168 //////////////////////////////////////////////////////////////////////////
169 /// \brief Execute a function over the elements of a vector in parallel
170 /// Implementation of the Map method.
171 ///
172 /// \copydetails TExecutorCRTP::Map(F func,std::vector<T> &args)
173 template<class F, class T, class Cond>
174 auto TSequentialExecutor::MapImpl(F func, std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>> {
175 // //check whether func is callable
176 using retType = decltype(func(args.front()));
177 std::vector<retType> reslist;
178 reslist.reserve(args.size());
179 for(auto &&arg: args) {
180 reslist.emplace_back(func(arg));
181 }
182 return reslist;
183 }
184
185 //////////////////////////////////////////////////////////////////////////
186 /// \brief Execute a function over the elements of an immutable vector.
187 /// Implementation of the Map method.
188 ///
189 /// \copydetails TExecutorCRTP::Map(F func,const std::vector<T> &args)
190 template<class F, class T, class Cond>
191 auto TSequentialExecutor::MapImpl(F func, const std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>> {
192 // //check whether func is callable
193 using retType = decltype(func(args.front()));
194 std::vector<retType> reslist;
195 reslist.reserve(args.size());
196 for(auto &&arg: args) {
197 reslist.emplace_back(func(arg));
198 }
199 return reslist;
200 }
201
202} // namespace ROOT
203#endif
This class defines an interface to execute the same task multiple times, possibly in parallel and wit...
auto MapReduce(F func, unsigned nTimes, R redfunc) -> InvokeResult_t< F >
Execute a function without arguments several times (Map) and accumulate the results into a single val...
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
void Foreach(F func, unsigned nTimes)
Execute a function without arguments several times, dividing the execution in nChunks.
unsigned GetPoolSize() const
Return the number of workers in the sequential executor: a single one.
auto MapImpl(F func, unsigned nTimes) -> std::vector< InvokeResult_t< F > >
Execute a function without arguments several times.
TSequentialExecutor(const TSequentialExecutor &)=delete
TSequentialExecutor & operator=(const TSequentialExecutor &)=delete
#define F(x, y, z)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...