Logo ROOT   6.08/07
Reference Guide
TThreadExecutor.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_TThreadExecutor
13 #define ROOT_TThreadExecutor
14 
15 #include "RConfigure.h"
16 
17 // exclude in case ROOT does not have IMT support
18 #ifndef R__USE_IMT
19 // No need to error out for dictionaries.
20 # if !defined(__ROOTCLING__) && !defined(G__DICTIONARY)
21 # error "Cannot use ROOT::TThreadExecutor without defining R__USE_IMT."
22 # endif
23 #else
24 #include "ROOT/TExecutor.hxx"
25 
26 #include <memory>
27 #include <numeric>
28 #include <functional>
29 
30 namespace tbb { class task_scheduler_init;}
31 
32 namespace ROOT {
33 
34 class TThreadExecutor: public TExecutor<TThreadExecutor> {
35 template<class T>
36 friend class ParallelReductionResolver;
37 
38 public:
39  explicit TThreadExecutor();
40 
41  explicit TThreadExecutor(size_t nThreads);
42 
43  TThreadExecutor(TThreadExecutor &) = delete;
44  TThreadExecutor & operator=(TThreadExecutor &) = delete;
45 
46  ~TThreadExecutor();
47 
48  template<class F, class Cond = noReferenceCond<F>>
49  auto Map(F func, unsigned nTimes) -> std::vector<typename std::result_of<F()>::type>;
50  /// \cond
51  template<class F, class INTEGER, class Cond = noReferenceCond<F, INTEGER>>
53  template<class F, class T, class Cond = noReferenceCond<F, T>>
54  auto Map(F func, std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type>;
55  // / \endcond
56  using TExecutor<TThreadExecutor>::Map;
57 
58  template<class T, class BINARYOP> auto Reduce(const std::vector<T> &objs, BINARYOP redfunc) -> decltype(redfunc(objs.front(), objs.front()));
59  template<class T, class R> auto Reduce(const std::vector<T> &objs, R redfunc) -> decltype(redfunc(objs));
60 
61 private:
62  void ParallelFor(unsigned start, unsigned end, const std::function<void(unsigned int i)> &f);
63  double ParallelReduce(const std::vector<double> &objs, const std::function<double(double a, double b)> &redfunc);
64  float ParallelReduce(const std::vector<float> &objs, const std::function<float(float a, float b)> &redfunc);
65  template<class T, class R>
66  auto SeqReduce(const std::vector<T> &objs, R redfunc) -> decltype(redfunc(objs));
67  std::unique_ptr<tbb::task_scheduler_init> fInitTBB;
68 };
69 
70 /************ TEMPLATE METHODS IMPLEMENTATION ******************/
71 
72 //////////////////////////////////////////////////////////////////////////
73 /// Execute func (with no arguments) nTimes in parallel.
74 /// A vector containg executions' results is returned.
75 /// Functions that take more than zero arguments can be executed (with
76 /// fixed arguments) by wrapping them in a lambda or with std::bind.
77 template<class F, class Cond>
78 auto TThreadExecutor::Map(F func, unsigned nTimes) -> std::vector<typename std::result_of<F()>::type>
79 {
80  using retType = decltype(func());
81  std::vector<retType> reslist(nTimes);
82 
83  auto lambda = [&](unsigned int i){reslist[i] = func();};
84  ParallelFor(0U, nTimes, lambda);
85 
86  return reslist;
87 }
88 
89 template<class F, class INTEGER, class Cond>
91 {
92  unsigned start = *args.begin();
93  unsigned end = *args.end();
94  using retType = decltype(func(start));
95  std::vector<retType> reslist(end-start);
96 
97  auto lambda = [&](unsigned int i){reslist[i] = func(i);};
98  ParallelFor(start, end, lambda);
99 
100  return reslist;
101 }
102 
103 // tell doxygen to ignore this (\endcond closes the statement)
104 /// \cond
105 
106 // actual implementation of the Map method. all other calls with arguments eventually
107 // call this one
108 template<class F, class T, class Cond>
109 auto TThreadExecutor::Map(F func, std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type>
110 {
111  // //check whether func is callable
112  using retType = decltype(func(args.front()));
113 
114  unsigned int fNToProcess = args.size();
115  std::vector<retType> reslist(fNToProcess);
116 
117  auto lambda = [&](unsigned int i){reslist[i] = func(args[i]);};
118  ParallelFor(0U, fNToProcess, lambda);
119 
120  return reslist;
121 }
122 
123 // // tell doxygen to stop ignoring code
124 // /// \endcond
125 
126 template<class T, class BINARYOP>
127 auto TThreadExecutor::Reduce(const std::vector<T> &objs, BINARYOP redfunc) -> decltype(redfunc(objs.front(), objs.front()))
128 {
129  // check we can apply reduce to objs
130  static_assert(std::is_same<decltype(redfunc(objs.front(), objs.front())), T>::value, "redfunc does not have the correct signature");
131  return ParallelReduce(objs, redfunc);
132 }
133 
134 template<class T, class R>
135 auto TThreadExecutor::Reduce(const std::vector<T> &objs, R redfunc) -> decltype(redfunc(objs))
136 {
137  // check we can apply reduce to objs
138  static_assert(std::is_same<decltype(redfunc(objs)), T>::value, "redfunc does not have the correct signature");
139  return SeqReduce(objs, redfunc);
140 }
141 
142 template<class T, class R>
143 auto TThreadExecutor::SeqReduce(const std::vector<T> &objs, R redfunc) -> decltype(redfunc(objs))
144 {
145  return redfunc(objs);
146 }
147 
148 } // namespace ROOT
149 
150 #endif // R__USE_IMT
151 #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
TArc * a
Definition: textangle.C:12
#define F(x, y, z)
double f(double x)
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
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
TRandom3 R
a TMatrixD.
Definition: testIO.cxx:28