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