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-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 
15 #include "ROOT/TExecutorCRTP.hxx"
16 #include "ROOT/TSeq.hxx"
17 
18 #include <initializer_list>
19 #include <numeric> //std::accumulate
20 #include <type_traits> //std::enable_if, std::result_of
21 #include <utility> //std::move
22 #include <vector>
23 
24 namespace ROOT {
25 
26  class TSequentialExecutor: public TExecutorCRTP<TSequentialExecutor> {
27  friend TExecutorCRTP;
28  public:
29 
30  TSequentialExecutor() = default;
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 = noReferenceCond<F>>
71  auto MapImpl(F func, unsigned nTimes) -> std::vector<typename std::result_of<F()>::type>;
72  template<class F, class INTEGER, class Cond = noReferenceCond<F, INTEGER>>
73  auto MapImpl(F func, ROOT::TSeq<INTEGER> args) -> std::vector<typename std::result_of<F(INTEGER)>::type>;
74  template<class F, class T, class Cond = noReferenceCond<F, T>>
75  auto MapImpl(F func, std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type>;
76  template<class F, class T, class Cond = noReferenceCond<F, T>>
77  auto MapImpl(F func, const std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type>;
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<typename std::result_of<F()>::type> {
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<typename std::result_of<F(INTEGER)>::type> {
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<typename std::result_of<F(T)>::type> {
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<typename std::result_of<F(T)>::type> {
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
ROOT::TExecutorCRTP
This class defines an interface to execute the same task multiple times, possibly in parallel and wit...
Definition: TExecutorCRTP.hxx:102
F
#define F(x, y, z)
ROOT::TSequentialExecutor::TExecutorCRTP
friend TExecutorCRTP
Definition: TSequentialExecutor.hxx:27
ROOT::TSequentialExecutor
Definition: TSequentialExecutor.hxx:26
TExecutorCRTP.hxx
EExecutionPolicy.hxx
ROOT::TSequentialExecutor::Foreach
void Foreach(F func, unsigned nTimes)
Execute a function without arguments several times, dividing the execution in nChunks.
Definition: TSequentialExecutor.hxx:88
ROOT::TSequentialExecutor::operator=
TSequentialExecutor & operator=(const TSequentialExecutor &)=delete
TSeq.hxx
ROOT::TSequentialExecutor::TSequentialExecutor
TSequentialExecutor(const TSequentialExecutor &)=delete
ROOT::Math::Chebyshev::T
double T(double x)
Definition: ChebyshevPol.h:34
ROOT::TSequentialExecutor::GetPoolSize
unsigned GetPoolSize() const
Return the number of workers in the sequential executor: a single one.
Definition: TSequentialExecutor.hxx:65
ROOT::TSeq
A pseudo container class which is a generator of indices.
Definition: TSeq.hxx:66
type
int type
Definition: TGX11.cxx:121
ROOT::TSequentialExecutor::TSequentialExecutor
TSequentialExecutor()=default
ROOT
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: EExecutionPolicy.hxx:4
ROOT::TSequentialExecutor::MapImpl
auto MapImpl(F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
Execute a function without arguments several times.
Definition: TSequentialExecutor.hxx:143