Logo ROOT   6.07/09
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 // exclude in case ROOT does not have IMT support
16 #ifdef R__USE_IMT
17 
18 #include "ROOT/TExecutor.hxx"
19 #include "tbb/tbb.h"
20 #include <numeric>
21 
22 namespace ROOT {
23 
24 class TThreadExecutor: public TExecutor<TThreadExecutor> {
25 public:
26  explicit TThreadExecutor(){
27  fInitTBB.initialize();
28  }
29 
30  explicit TThreadExecutor(size_t nThreads){
31  fInitTBB.initialize(nThreads);
32  }
33 
34  ~TThreadExecutor() {
35  fInitTBB.terminate();
36  }
37 
38 
39  template<class F, class Cond = noReferenceCond<F>>
40  auto Map(F func, unsigned nTimes) -> std::vector<typename std::result_of<F()>::type>;
41  /// \cond
42  template<class F, class INTEGER, class Cond = noReferenceCond<F, INTEGER>>
44  template<class F, class T, class Cond = noReferenceCond<F, T>>
45  auto Map(F func, std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type>;
46  // / \endcond
48 
49  template<class T, class BINARYOP> auto Reduce(const std::vector<T> &objs, BINARYOP redfunc) -> decltype(redfunc(objs.front(), objs.front()));
51 
52 private:
53  tbb::task_scheduler_init fInitTBB{tbb::task_scheduler_init::deferred};
54 };
55 
56 /************ TEMPLATE METHODS IMPLEMENTATION ******************/
57 
58 //////////////////////////////////////////////////////////////////////////
59 /// Execute func (with no arguments) nTimes in parallel.
60 /// A vector containg executions' results is returned.
61 /// Functions that take more than zero arguments can be executed (with
62 /// fixed arguments) by wrapping them in a lambda or with std::bind.
63 template<class F, class Cond>
64 auto TThreadExecutor::Map(F func, unsigned nTimes) -> std::vector<typename std::result_of<F()>::type>
65 {
66  using retType = decltype(func());
67  std::vector<retType> reslist(nTimes);
68 
69  tbb::parallel_for(0U, nTimes, [&](unsigned int i) {
70  reslist[i] = func();
71  });
72 
73  return reslist;
74 }
75 
76 template<class F, class INTEGER, class Cond>
78 {
79  unsigned start = *args.begin();
80  unsigned end = *args.end();
81  using retType = decltype(func(start));
82  std::vector<retType> reslist(end-start);
83 
84  tbb::parallel_for(start, end, [&](unsigned int i) {
85  reslist[i] = func(i);
86  });
87 
88  return reslist;
89 }
90 
91 // tell doxygen to ignore this (\endcond closes the statement)
92 /// \cond
93 
94 // actual implementation of the Map method. all other calls with arguments eventually
95 // call this one
96 template<class F, class T, class Cond>
97 auto TThreadExecutor::Map(F func, std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type>
98 {
99  // //check whether func is callable
100  using retType = decltype(func(args.front()));
101 
102  unsigned int fNToProcess = args.size();
103  std::vector<retType> reslist(fNToProcess);
104 
105  tbb::parallel_for(0U, fNToProcess, [&](size_t i) {
106  reslist[i] = func(args[i]);
107  });
108  return reslist;
109 }
110 
111 // // tell doxygen to stop ignoring code
112 // /// \endcond
113 
114 template<class T, class BINARYOP>
115 auto TThreadExecutor::Reduce(const std::vector<T> &objs, BINARYOP redfunc) -> decltype(redfunc(objs.front(), objs.front()))
116 {
117  // check we can apply reduce to objs
118  static_assert(std::is_same<decltype(redfunc(objs.front(), objs.front())), T>::value, "redfunc does not have the correct signature");
119  return tbb::parallel_reduce(tbb::blocked_range<decltype(objs.begin())>(objs.begin(), objs.end()), T{},
120  [redfunc](tbb::blocked_range<decltype(objs.begin())> const & range, T init) {
121  return std::accumulate(range.begin(), range.end(), init, redfunc);
122  }, redfunc);
123 }
124 
125 } // namespace ROOT
126 
127 #endif // R__USE_IMT
128 #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)
auto Reduce(const std::vector< T > &objs, R redfunc) -> decltype(redfunc(objs))
Definition: TExecutor.hxx:167
auto Map(F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
Execute func (with no arguments) nTimes in parallel.
Definition: TExecutor.hxx:79
static Int_t init()
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