Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TExecutor.cxx
Go to the documentation of this file.
1// @(#)root/thread:$Id$
2// Author: Xavier Valls September 2020
3
4/*************************************************************************
5 * Copyright (C) 1995-2020, 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#include "ROOT/TExecutor.hxx"
13
14//////////////////////////////////////////////////////////////////////////
15///
16/// \class ROOT::Internal::TExecutor
17/// \brief This class implements the interface to execute the same task
18/// multiple times, sequentially or in parallel depending on the execution policy passed
19/// as a first parameter on construction, and possibly with different arguments every time.
20///
21/// ###ROOT::Internal::TExecutor::Map
22/// The two possible usages of the Map method are:\n
23/// * `Map(F func, unsigned nTimes)`: func is executed nTimes with no arguments
24/// * `Map(F func, T& args)`: func is executed on each element of the collection of arguments args
25///
26/// For either signature, func is executed as many times as needed by a pool of
27/// n workers; where n tipically defaults to the number of cores.\n
28/// A collection containing the result of each execution is returned.\n
29/// **Note:** the user is responsible for the deletion of any object that might
30/// be created upon execution of func, returned objects included. ROOT::::Internal::TExecutor never
31/// deletes what it returns, it simply forgets it.\n
32///
33/// \param func
34/// \parblock
35/// a callable object, such as a lambda expression, an std::function, a
36/// functor object or a function that takes zero arguments (for the first signature)
37/// or one (for the second signature).
38/// \endparblock
39/// \param args
40/// \parblock
41/// a standard vector, a ROOT::TSeq of integer type or an initializer list for the second signature.
42/// An integer only for the first.\n
43/// \endparblock
44///
45/// **Note:** in cases where the function to be executed takes more than
46/// zero/one argument but all are fixed except zero/one, the function can be wrapped
47/// in a lambda or via std::bind to give it the right signature.\n
48///
49/// #### Return value:
50/// An std::vector. The elements in the container
51/// will be the objects returned by func.
52///
53/// ### ROOT::Internal::TExecutor::MapReduce
54/// This set of methods behaves exactly like Map, but takes an additional
55/// function as a third argument. This function is applied to the set of
56/// objects returned by the corresponding Map execution to "squash" them
57/// into a single object. The signature of the reduce function should be `(const std::vector<T>) -> T`
58///
59/// An integer can be passed as the fourth argument indicating the number of chunks we want to divide our work in.
60/// <b>(Note: Please be aware that chunking is only available when the policy is kMultiThread, ignoring this argument in
61/// other cases)</b> This may be useful to avoid the overhead introduced when running really short tasks. In this case,
62/// the reduction function should be independent of the size of the vector returned by Map due to optimization of the
63/// number of chunks.
64///
65/// #### Examples:
66/// ~~~{.cpp}
67/// root[] ROOT::Internal::TExecutor pool; auto ten = pool.MapReduce([]() { return 1; }, 10, [](const std::vector<int>
68/// &v) { return std::accumulate(v.begin(), v.end(), 0); })
69/// root[] ROOT::Internal::TExecutor
70/// pool(ROOT::EExecutionPolicy::kMultiProcess); auto hist = pool.MapReduce(CreateAndFillHists, 10,
71/// PoolUtils::ReduceObjects);
72/// ~~~
73///
74//////////////////////////////////////////////////////////////////////////
75
76namespace ROOT {
77namespace Internal {
78TExecutor::TExecutor(ROOT::EExecutionPolicy execPolicy, unsigned nWorkers): fExecPolicy(execPolicy) {
79 switch(fExecPolicy) {
81 fSequentialExecutor = std::make_unique<ROOT::TSequentialExecutor>();
82 break;
83#ifdef R__USE_IMT
85 fThreadExecutor = std::make_unique<ROOT::TThreadExecutor>(nWorkers);
86 break;
87#endif
88#ifndef R__WIN32
90 fProcessExecutor = std::make_unique<ROOT::TProcessExecutor>(nWorkers);
91 break;
92#endif
93 default:
94 throw std::invalid_argument(
95 "Invalid execution policy. Potential issues:\n* kMultiThread policy not available when ROOT is compiled with IMT=OFF.\n* kMultiprocess policy not available on Windows");
96 }
97}
98}
99}
std::unique_ptr< ROOT::TThreadExecutor > fThreadExecutor
std::unique_ptr< ROOT::TSequentialExecutor > fSequentialExecutor
TExecutor(unsigned nWorkers=0)
Class constructor.
Definition TExecutor.hxx:45
ROOT::EExecutionPolicy fExecPolicy
Definition TExecutor.hxx:97
std::unique_ptr< ROOT::TProcessExecutor > fProcessExecutor
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...