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#include "ROOT/TypeTraits.hxx" // InvokeResult_t
18
19#include <initializer_list>
20#include <numeric> //std::accumulate
21#include <utility> //std::move
22#include <vector>
23
24namespace ROOT {
25
26 class TSequentialExecutor: public TExecutorCRTP<TSequentialExecutor> {
28
29 template <typename F, typename... Args>
30 using InvokeResult_t = ROOT::TypeTraits::InvokeResult_t<F, Args...>;
31
32 public:
33
37
38 // Foreach
39 //
40 template<class F>
41 void Foreach(F func, unsigned nTimes);
42 template<class F, class INTEGER>
43 void Foreach(F func, ROOT::TSeq<INTEGER> args);
44 template<class F, class T>
45 void Foreach(F func, std::initializer_list<T> args);
46 template<class F, class T>
47 void Foreach(F func, std::vector<T> &args);
48 template<class F, class T>
49 void Foreach(F func, const std::vector<T> &args);
50
51 // Map
52 //
54
55 // MapReduce
56 // the late return types also check at compile-time whether redfunc is compatible with func,
57 // other than checking that func is compatible with the type of arguments.
58 // a static_assert check in TSequentialExecutor::Reduce is used to check that redfunc is compatible with the type returned by func
60
61 // Reduce
62 //
64
65 //////////////////////////////////////////////////////////////////////////
66 /// \brief Return the number of workers in the sequential executor: a single one.
67 ///
68 /// \return The number of workers in the pool, one.
69 unsigned GetPoolSize() const { return 1u; }
70
71 private:
72 // Implementation of the Map functions declared in the parent class (TExecutorCRTP)
73 //
74 template<class F, class Cond = noReferenceCond<F>>
75 auto MapImpl(F func, unsigned nTimes) -> std::vector<InvokeResult_t<F>>;
76 template<class F, class INTEGER, class Cond = noReferenceCond<F, INTEGER>>
77 auto MapImpl(F func, ROOT::TSeq<INTEGER> args) -> std::vector<InvokeResult_t<F, INTEGER>>;
78 template<class F, class T, class Cond = noReferenceCond<F, T>>
79 auto MapImpl(F func, std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>;
80 template<class F, class T, class Cond = noReferenceCond<F, T>>
81 auto MapImpl(F func, const std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>;
82 };
83
84 /************ TEMPLATE METHODS IMPLEMENTATION ******************/
85
86 //////////////////////////////////////////////////////////////////////////
87 /// \brief Execute a function without arguments several times, dividing the execution in nChunks.
88 ///
89 /// \param func Function to be executed.
90 /// \param nTimes Number of times function should be called.
91 template<class F>
92 void TSequentialExecutor::Foreach(F func, unsigned nTimes) {
93 for (auto i = 0U; i < nTimes; ++i) func();
94 }
95
96 //////////////////////////////////////////////////////////////////////////
97 /// \brief Execute a function over a sequence of indexes, dividing the execution in nChunks.
98 ///
99 /// \param func Function to be executed. Must take an element of the sequence passed assecond argument as a parameter.
100 /// \param args Sequence of indexes to execute `func` on.
101 template<class F, class INTEGER>
103 for(auto i : args) func(i);
104 }
105
106 //////////////////////////////////////////////////////////////////////////
107 /// \brief Execute a function over the elements of an initializer_list, dividing the execution in nChunks.
108 ///
109 /// \param func Function to be executed on the elements of the initializer_list passed as second parameter.
110 /// \param args initializer_list for a vector to apply `func` on.
111 template<class F, class T>
112 void TSequentialExecutor::Foreach(F func, std::initializer_list<T> args) {
113 std::vector<T> vargs(std::move(args));
114 Foreach(func, vargs);
115 }
116
117 //////////////////////////////////////////////////////////////////////////
118 /// \brief Execute a function over the elements of a vector, dividing the execution in nChunks.
119 ///
120 /// \param func Function to be executed on the elements of the vector passed as second parameter.
121 /// \param args Vector of elements passed as an argument to `func`.
122 template<class F, class T>
123 void TSequentialExecutor::Foreach(F func, std::vector<T> &args) {
124 for(auto &&arg: args) {
125 func(arg);
126 }
127 }
128
129 //////////////////////////////////////////////////////////////////////////
130 /// \brief Execute a function over the elements of an immutable vector, dividing the execution in nChunks.
131 ///
132 /// \param func Function to be executed on the elements of the immutable vector passed as second parameter.
133 /// \param args Immutable vector of elements passed as an argument to `func`.
134 template<class F, class T>
135 void TSequentialExecutor::Foreach(F func, const std::vector<T> &args) {
136 for(auto &&arg: args) {
137 func(arg);
138 }
139 }
140
141 //////////////////////////////////////////////////////////////////////////
142 /// \brief Execute a function without arguments several times.
143 /// Implementation of the Map method.
144 ///
145 /// \copydetails TExecutorCRTP::Map(F func,unsigned nTimes)
146 template<class F, class Cond>
147 auto TSequentialExecutor::MapImpl(F func, unsigned nTimes) -> std::vector<InvokeResult_t<F>> {
148 using retType = decltype(func());
149 std::vector<retType> reslist;
150 reslist.reserve(nTimes);
151 while(reslist.size() < nTimes) {
152 reslist.emplace_back(func());
153 }
154 return reslist;
155 }
156
157 //////////////////////////////////////////////////////////////////////////
158 /// \brief Execute a function over a sequence of indexes.
159 /// Implementation of the Map method.
160 ///
161 /// \copydetails TExecutorCRTP::Map(F func,ROOT::TSeq<INTEGER> args)
162 template<class F, class INTEGER, class Cond>
163 auto TSequentialExecutor::MapImpl(F func, ROOT::TSeq<INTEGER> args) -> std::vector<InvokeResult_t<F, INTEGER>> {
164 using retType = decltype(func(*args.begin()));
165 std::vector<retType> reslist;
166 reslist.reserve(args.size());
167 for(auto i: args)
168 reslist.emplace_back(func(i));
169 return reslist;
170 }
171
172 //////////////////////////////////////////////////////////////////////////
173 /// \brief Execute a function over the elements of a vector in parallel
174 /// Implementation of the Map method.
175 ///
176 /// \copydetails TExecutorCRTP::Map(F func,std::vector<T> &args)
177 template<class F, class T, class Cond>
178 auto TSequentialExecutor::MapImpl(F func, std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>> {
179 // //check whether func is callable
180 using retType = decltype(func(args.front()));
181 std::vector<retType> reslist;
182 reslist.reserve(args.size());
183 for(auto &&arg: args) {
184 reslist.emplace_back(func(arg));
185 }
186 return reslist;
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)
194 template<class F, class T, class Cond>
195 auto TSequentialExecutor::MapImpl(F func, const std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>> {
196 // //check whether func is callable
197 using retType = decltype(func(args.front()));
198 std::vector<retType> reslist;
199 reslist.reserve(args.size());
200 for(auto &&arg: args) {
201 reslist.emplace_back(func(arg));
202 }
203 return reslist;
204 }
205
206} // namespace ROOT
207#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.
ROOT::TypeTraits::InvokeResult_t< F, Args... > InvokeResult_t
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)
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.