Logo ROOT   6.10/09
Reference Guide
TThreadExecutor.cxx
Go to the documentation of this file.
2 #include "tbb/tbb.h"
3 
4 //////////////////////////////////////////////////////////////////////////
5 ///
6 /// \class ROOT::TThreadExecutor
7 /// \brief This class provides a simple interface to execute the same task
8 /// multiple times in parallel, possibly with different arguments every
9 /// time. This mimics the behaviour of python's pool.Map method.
10 ///
11 /// ###ROOT::TThreadExecutor::Map
12 /// This class inherits its interfaces from ROOT::TExecutor\n.
13 /// The two possible usages of the Map method are:\n
14 /// * Map(F func, unsigned nTimes): func is executed nTimes with no arguments
15 /// * Map(F func, T& args): func is executed on each element of the collection of arguments args
16 ///
17 /// For either signature, func is executed as many times as needed by a pool of
18 /// nThreads threads; It defaults to the number of cores.\n
19 /// A collection containing the result of each execution is returned.\n
20 /// **Note:** the user is responsible for the deletion of any object that might
21 /// be created upon execution of func, returned objects included: ROOT::TThreadExecutor never
22 /// deletes what it returns, it simply forgets it.\n
23 ///
24 /// \param func
25 /// \parblock
26 /// a lambda expression, an std::function, a loaded macro, a
27 /// functor class or a function that takes zero arguments (for the first signature)
28 /// or one (for the second signature).
29 /// \endparblock
30 /// \param args
31 /// \parblock
32 /// a standard vector, a ROOT::TSeq of integer type or an initializer list for the second signature.
33 /// An integer only for the first.
34 /// \endparblock
35 /// **Note:** in cases where the function to be executed takes more than
36 /// zero/one argument but all are fixed except zero/one, the function can be wrapped
37 /// in a lambda or via std::bind to give it the right signature.\n
38 ///
39 /// #### Return value:
40 /// An std::vector. The elements in the container
41 /// will be the objects returned by func.
42 ///
43 ///
44 /// #### Examples:
45 ///
46 /// ~~~{.cpp}
47 /// root[] ROOT::TThreadExecutor pool; auto hists = pool.Map(CreateHisto, 10);
48 /// root[] ROOT::TThreadExecutor pool(2); auto squares = pool.Map([](int a) { return a*a; }, {1,2,3});
49 /// ~~~
50 ///
51 /// ###ROOT::TThreadExecutor::MapReduce
52 /// This set of methods behaves exactly like Map, but takes an additional
53 /// function as a third argument. This function is applied to the set of
54 /// objects returned by the corresponding Map execution to "squash" them
55 /// to a single object.
56 ///
57 /// If this function is a binary operator, the "squashing" will be performed in parallel.
58 /// This is exclusive to ROOT::TThreadExecutor and not any other ROOT::TExecutor-derived classes.\n
59 /// An integer can be passed as the fourth argument indicating the number of chunks we want to divide our work in.
60 /// This may be useful to avoid the overhead introduced when running really short tasks.
61 ///
62 /// ####Examples:
63 /// ~~~{.cpp}
64 /// root[] ROOT::TThreadExecutor pool; auto ten = pool.MapReduce([]() { return 1; }, 10, [](std::vector<int> v) { return std::accumulate(v.begin(), v.end(), 0); })
65 /// root[] ROOT::TThreadExecutor pool; auto hist = pool.MapReduce(CreateAndFillHists, 10, PoolUtils::ReduceObjects);
66 /// ~~~
67 ///
68 //////////////////////////////////////////////////////////////////////////
69 
70 
71 namespace ROOT {
72 
73  //////////////////////////////////////////////////////////////////////////
74  /// Class constructor.
75  /// If the scheduler is active, gets a pointer to it.
76  /// If not, initializes the pool of threads with the number of logical threads supported by the hardware.
77  TThreadExecutor::TThreadExecutor(): TThreadExecutor::TThreadExecutor(tbb::task_scheduler_init::default_num_threads()) {}
78  //////////////////////////////////////////////////////////////////////////
79  /// Class constructor.
80  /// nThreads is the number of threads that will be spawned. If the scheduler is active (ImplicitMT enabled, another TThreadExecutor instance),
81  /// it won't change the number of threads.
83  {
85  }
86 
87  void TThreadExecutor::ParallelFor(unsigned int start, unsigned int end, unsigned step, const std::function<void(unsigned int i)> &f)
88  {
89  tbb::parallel_for(start, end, step, f);
90  }
91 
92  double TThreadExecutor::ParallelReduce(const std::vector<double> &objs, const std::function<double(double a, double b)> &redfunc)
93  {
94  return tbb::parallel_reduce(tbb::blocked_range<decltype(objs.begin())>(objs.begin(), objs.end()), double{},
95  [redfunc](tbb::blocked_range<decltype(objs.begin())> const & range, double init) {
96  return std::accumulate(range.begin(), range.end(), init, redfunc);
97  }, redfunc);
98  }
99 
100  float TThreadExecutor::ParallelReduce(const std::vector<float> &objs, const std::function<float(float a, float b)> &redfunc)
101  {
102  return tbb::parallel_reduce(tbb::blocked_range<decltype(objs.begin())>(objs.begin(), objs.end()), float{},
103  [redfunc](tbb::blocked_range<decltype(objs.begin())> const & range, float init) {
104  return std::accumulate(range.begin(), range.end(), init, redfunc);
105  }, redfunc);
106  }
107 }
std::shared_ptr< TPoolManager > GetPoolManager(UInt_t nThreads=0)
Get a shared pointer to the manager.
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
void ParallelFor(unsigned start, unsigned end, unsigned step, const std::function< void(unsigned int i)> &f)
TArc * a
Definition: textangle.C:12
double ParallelReduce(const std::vector< double > &objs, const std::function< double(double a, double b)> &redfunc)
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:146
This class provides a simple interface to execute the same task multiple times in parallel...
unsigned int UInt_t
Definition: RtypesCore.h:42
TThreadExecutor()
Class constructor.
double f(double x)
static Int_t init()
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
std::shared_ptr< ROOT::Internal::TPoolManager > fSched