Logo ROOT   6.08/07
Reference Guide
TExecutor.hxx
Go to the documentation of this file.
1 // @(#)root/thread:$Id$
2 // Author: Xavier Valls March 2016
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 
12 #ifndef ROOT_TExecutor
13 #define ROOT_TExecutor
14 
15 #include "ROOT/TSeq.hxx"
16 #include "TList.h"
17 #include <vector>
18 
19 namespace ROOT {
20 
21 template<class subc>
22 class TExecutor {
23 public:
24  explicit TExecutor() = default;
25  explicit TExecutor(size_t /* nThreads */ ){};
26 
27  template< class F, class... T>
28  using noReferenceCond = typename std::enable_if<"Function can't return a reference" && !(std::is_reference<typename std::result_of<F(T...)>::type>::value)>::type;
29 
30  // // Map
31  // //these late return types allow for a compile-time check of compatibility between function signatures and args,
32  // //and a compile-time check that the argument list implements a front() method (all STL sequence containers have it)
33  template<class F, class Cond = noReferenceCond<F>>
34  auto Map(F func, unsigned nTimes) -> std::vector<typename std::result_of<F()>::type>;
35  // /// \cond doxygen should ignore these methods
36  template<class F, class INTEGER, class Cond = noReferenceCond<F, INTEGER>>
38  template<class F, class T, class Cond = noReferenceCond<F, T>>
39  auto Map(F func, std::initializer_list<T> args) -> std::vector<typename std::result_of<F(T)>::type>;
40  template<class F, class T, class Cond = noReferenceCond<F, T>>
41  auto Map(F func, std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type>;
42  // // // / \endcond
43 
44  // // MapReduce
45  // // the late return types also check at compile-time whether redfunc is compatible with func,
46  // // other than checking that func is compatible with the type of arguments.
47  // // a static_assert check in TExecutor<subc>::Reduce is used to check that redfunc is compatible with the type returned by func
48  template<class F, class R, class Cond = noReferenceCond<F>>
49  auto MapReduce(F func, unsigned nTimes, R redfunc) -> typename std::result_of<F()>::type;
50  template<class F, class INTEGER, class R, class Cond = noReferenceCond<F, INTEGER>>
51  auto MapReduce(F func, ROOT::TSeq<INTEGER> args, R redfunc) -> typename std::result_of<F(INTEGER)>::type;
52  // /// \cond doxygen should ignore these methods
53  template<class F, class T, class R, class Cond = noReferenceCond<F, T>>
54  auto MapReduce(F func, std::initializer_list<T> args, R redfunc) -> typename std::result_of<F(T)>::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  // /// \endcond
58 
59  template<class T> T* Reduce(const std::vector<T*> &mergeObjs);
60 
61 private:
62  inline subc & Derived()
63  {
64  return *static_cast<subc*>(this);
65  }
66 };
67 
68 //////////////////////////////////////////////////////////////////////////
69 /// Execute func (with no arguments) nTimes in parallel.
70 /// A vector containg executions' results is returned.
71 /// Functions that take more than zero arguments can be executed (with
72 /// fixed arguments) by wrapping them in a lambda or with std::bind.
73 template<class subc> template<class F, class Cond>
74 auto TExecutor<subc>::Map(F func, unsigned nTimes) -> std::vector<typename std::result_of<F()>::type>
75 {
76  return Derived().Map(func, nTimes);
77 }
78 
79 // //////////////////////////////////////////////////////////////////////////
80 // /// Execute func in parallel distributing the elements of the args collection between the workers.
81 // /// See class description for the valid types of collections and containers that can be used.
82 // /// A vector containing each execution's result is returned. The user is responsible of deleting
83 // /// objects that might be created upon the execution of func, returned objects included.
84 // /// **Note:** the collection of arguments is modified by Map and should be considered empty or otherwise
85 // /// invalidated after Map's execution (std::move might be applied to it).
86 
87 // tell doxygen to ignore this (\endcond closes the statement)
88 /// \cond
89 template<class subc> template<class F, class INTEGER, class Cond>
91 {
92  return Derived().Map(func, args);
93 }
94 
95 template<class subc> template<class F, class T, class Cond>
96 auto TExecutor<subc>::Map(F func, std::initializer_list<T> args) -> std::vector<typename std::result_of<F(T)>::type>
97 {
98  std::vector<T> vargs(std::move(args));
99  const auto &reslist = Map(func, vargs);
100  return reslist;
101 }
102 
103 // actual implementation of the Map method. all other calls with arguments eventually
104 // call this one
105 
106 template<class subc> template<class F, class T, class Cond>
107 auto TExecutor<subc>::Map(F func, std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type>
108 {
109  return Derived().Map(func, args);
110 }
111 
112 // //////////////////////////////////////////////////////////////////////////
113 // /// This method behaves just like Map, but an additional redfunc function
114 // /// must be provided. redfunc is applied to the vector Map would return and
115 // /// must return the same type as func. In practice, redfunc can be used to
116 // /// "squash" the vector returned by Map into a single object by merging,
117 // /// adding, mixing the elements of the vector.
118 template<class subc> template<class F, class R, class Cond>
119 auto TExecutor<subc>::MapReduce(F func, unsigned nTimes, R redfunc) -> typename std::result_of<F()>::type
120 {
121  return Derived().Reduce(Map(func, nTimes), redfunc);
122 }
123 
124 //////////////////////////////////////////////////////////////////////////
125 /// This method behaves just like Map, but an additional redfunc function
126 /// must be provided. redfunc is applied to the vector Map would return and
127 /// must return the same type as func. In practice, redfunc can be used to
128 /// "squash" the vector returned by Map into a single object by merging,
129 /// adding, mixing the elements of the vector.
130 
131 /// \cond doxygen should ignore these methods
132 template<class subc> template<class F, class INTEGER, class R, class Cond>
133 auto TExecutor<subc>::MapReduce(F func, ROOT::TSeq<INTEGER> args, R redfunc) -> typename std::result_of<F(INTEGER)>::type
134 {
135  return Derived().Reduce(Map(func, args), redfunc);
136 }
137 
138 template<class subc> template<class F, class T, class R, class Cond>
139 auto TExecutor<subc>::MapReduce(F func, std::initializer_list<T> args, R redfunc) -> typename std::result_of<F(T)>::type
140 {
141  return Derived().Reduce(Map(func, args), redfunc);
142 }
143 
144 template<class subc> template<class F, class T, class R, class Cond>
145 auto TExecutor<subc>::MapReduce(F func, std::vector<T> &args, R redfunc) -> typename std::result_of<F(T)>::type
146 {
147  return Derived().Reduce(Map(func, args), redfunc);
148 }
149 
150 } // end namespace ROOT
151 
152 #endif
This namespace contains pre-defined functions to be used in conjuction with TExecutor::Map and TExecu...
Definition: StringConv.hxx:21
double T(double x)
Definition: ChebyshevPol.h:34
#define F(x, y, z)
A pseudo container class which is a generator of indices.
Definition: TSeq.hxx:66
int type
Definition: TGX11.cxx:120
double func(double *x, double *p)
Definition: stressTF1.cxx:213
TRandom3 R
a TMatrixD.
Definition: testIO.cxx:28