Logo ROOT  
Reference Guide
ROOT::TThreadExecutor Class Reference

This class provides a simple interface to execute the same task multiple times in parallel, possibly with different arguments every time.

This mimics the behaviour of python's pool.Map method.

ROOT::TThreadExecutor::Map

This class inherits its interfaces from ROOT::TExecutor
. The two possible usages of the Map method are:

  • Map(F func, unsigned nTimes): func is executed nTimes with no arguments
  • Map(F func, T& args): func is executed on each element of the collection of arguments args

For either signature, func is executed as many times as needed by a pool of nThreads threads; It defaults to the number of cores.
A collection containing the result of each execution is returned.
Note: the user is responsible for the deletion of any object that might be created upon execution of func, returned objects included: ROOT::TThreadExecutor never deletes what it returns, it simply forgets it.

Parameters
funca lambda expression, an std::function, a loaded macro, a functor class or a function that takes zero arguments (for the first signature) or one (for the second signature).
argsa standard vector, a ROOT::TSeq of integer type or an initializer list for the second signature. An integer only for the first.

Note: in cases where the function to be executed takes more than zero/one argument but all are fixed except zero/one, the function can be wrapped in a lambda or via std::bind to give it the right signature.

Return value:

An std::vector. The elements in the container will be the objects returned by func.

Examples:

root[] ROOT::TThreadExecutor pool; auto hists = pool.Map(CreateHisto, 10);
root[] ROOT::TThreadExecutor pool(2); auto squares = pool.Map([](int a) { return a*a; }, {1,2,3});

ROOT::TThreadExecutor::MapReduce

This set of methods behaves exactly like Map, but takes an additional function as a third argument. This function is applied to the set of objects returned by the corresponding Map execution to "squash" them to a single object. This function should be independent of the size of the vector returned by Map due to optimization of the number of chunks.

If this function is a binary operator, the "squashing" will be performed in parallel. This is exclusive to ROOT::TThreadExecutor and not any other ROOT::TExecutor-derived classes.
An integer can be passed as the fourth argument indicating the number of chunks we want to divide our work in. This may be useful to avoid the overhead introduced when running really short tasks.

Examples:

root[] ROOT::TThreadExecutor pool; auto ten = pool.MapReduce([]() { return 1; }, 10, [](std::vector<int> v) { return std::accumulate(v.begin(), v.end(), 0); })
root[] ROOT::TThreadExecutor pool; auto hist = pool.MapReduce(CreateAndFillHists, 10, PoolUtils::ReduceObjects);

Definition at line 35 of file TThreadExecutor.hxx.

Public Member Functions

 TThreadExecutor (TThreadExecutor &)=delete
 
 TThreadExecutor (UInt_t nThreads=0u)
 Class constructor. More...
 
template<class F , class T >
void Foreach (F func, const std::vector< T > &args, unsigned nChunks=0)
 Execute func in parallel, taking an element of a std::vector as argument. More...
 
template<class F , class INTEGER >
void Foreach (F func, ROOT::TSeq< INTEGER > args, unsigned nChunks=0)
 Execute func in parallel, taking an element of a sequence as argument. More...
 
template<class F , class T >
void Foreach (F func, std::vector< T > &args, unsigned nChunks=0)
 Execute func in parallel, taking an element of an std::vector as argument. More...
 
template<class F >
void Foreach (F func, unsigned nTimes, unsigned nChunks=0)
 Execute func (with no arguments) nTimes in parallel. More...
 
unsigned GetPoolSize ()
 
template<class F , class INTEGER , class Cond = noReferenceCond<F, INTEGER>>
auto Map (F func, ROOT::TSeq< INTEGER > args) -> std::vector< typename std::result_of< F(INTEGER)>::type >
 Execute func in parallel, taking an element of a sequence as argument. More...
 
template<class F , class T , class Cond = noReferenceCond<F, T>>
auto Map (F func, std::vector< T > &args) -> std::vector< typename std::result_of< F(T)>::type >
 Execute func in parallel, taking an element of an std::vector as argument. More...
 
template<class F , class Cond = noReferenceCond<F>>
auto Map (F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
 Execute func (with no arguments) nTimes in parallel. More...
 
template<class F , class INTEGER , class R , class Cond = noReferenceCond<F, INTEGER>>
auto MapReduce (F func, ROOT::TSeq< INTEGER > args, R redfunc, unsigned nChunks) -> typename std::result_of< F(INTEGER)>::type
 
template<class F , class T , class R , class Cond = noReferenceCond<F, T>>
auto MapReduce (F func, std::vector< T > &args, R redfunc) -> typename std::result_of< F(T)>::type
 
template<class F , class T , class R , class Cond = noReferenceCond<F, T>>
auto MapReduce (F func, std::vector< T > &args, R redfunc, unsigned nChunks) -> typename std::result_of< F(T)>::type
 
template<class F , class R , class Cond = noReferenceCond<F>>
auto MapReduce (F func, unsigned nTimes, R redfunc) -> typename std::result_of< F()>::type
 This method behaves just like Map, but an additional redfunc function must be provided. More...
 
template<class F , class R , class Cond = noReferenceCond<F>>
auto MapReduce (F func, unsigned nTimes, R redfunc, unsigned nChunks) -> typename std::result_of< F()>::type
 
TThreadExecutoroperator= (TThreadExecutor &)=delete
 
template<class T , class BINARYOP >
auto Reduce (const std::vector< T > &objs, BINARYOP redfunc) -> decltype(redfunc(objs.front(), objs.front()))
 "Reduce" an std::vector into a single object in parallel by passing a binary operator as the second argument to act on pairs of elements of the std::vector. More...
 
template<class T , class R >
auto Reduce (const std::vector< T > &objs, R redfunc) -> decltype(redfunc(objs))
 "Reduce" an std::vector into a single object by passing a function as the second argument defining the reduction operation. More...
 
- Public Member Functions inherited from ROOT::TExecutor< TThreadExecutor >
 TExecutor ()=default
 
 TExecutor (size_t)
 
auto Map (F func, ROOT::TSeq< INTEGER > args) -> std::vector< typename std::result_of< F(INTEGER)>::type >
 Execute func in parallel, taking an element of a sequence as argument. More...
 
auto Map (F func, std::initializer_list< T > args) -> std::vector< typename std::result_of< F(T)>::type >
 Execute func in parallel, taking an element of the std::initializer_list as argument. More...
 
auto Map (F func, std::vector< T > &args) -> std::vector< typename std::result_of< F(T)>::type >
 Execute func in parallel, taking an element of an std::vector as argument. More...
 
auto Map (F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
 Execute func (with no arguments) nTimes in parallel. More...
 
auto MapReduce (F func, ROOT::TSeq< INTEGER > args, R redfunc) -> typename std::result_of< F(INTEGER)>::type
 This method behaves just like Map, but an additional redfunc function must be provided. More...
 
auto MapReduce (F func, std::initializer_list< T > args, R redfunc) -> typename std::result_of< F(T)>::type
 
T * MapReduce (F func, std::vector< T * > &args)
 
T * Reduce (const std::vector< T * > &mergeObjs)
 "Reduce" an std::vector into a single object by using the object's Merge More...
 

Protected Member Functions

template<class F , class INTEGER , class R , class Cond = noReferenceCond<F, INTEGER>>
auto Map (F func, ROOT::TSeq< INTEGER > args, R redfunc, unsigned nChunks) -> std::vector< typename std::result_of< F(INTEGER)>::type >
 Execute func in parallel, taking an element of a sequence as argument. More...
 
template<class F , class T , class R , class Cond = noReferenceCond<F, T>>
auto Map (F func, std::initializer_list< T > args, R redfunc, unsigned nChunks) -> std::vector< typename std::result_of< F(T)>::type >
 
template<class F , class T , class R , class Cond = noReferenceCond<F, T>>
auto Map (F func, std::vector< T > &args, R redfunc, unsigned nChunks) -> std::vector< typename std::result_of< F(T)>::type >
 
template<class F , class R , class Cond = noReferenceCond<F>>
auto Map (F func, unsigned nTimes, R redfunc, unsigned nChunks) -> std::vector< typename std::result_of< F()>::type >
 Execute func (with no arguments) nTimes in parallel. More...
 

Private Member Functions

void ParallelFor (unsigned start, unsigned end, unsigned step, const std::function< void(unsigned int i)> &f)
 
double ParallelReduce (const std::vector< double > &objs, const std::function< double(double a, double b)> &redfunc)
 
float ParallelReduce (const std::vector< float > &objs, const std::function< float(float a, float b)> &redfunc)
 
template<class T , class R >
auto SeqReduce (const std::vector< T > &objs, R redfunc) -> decltype(redfunc(objs))
 

Private Attributes

std::shared_ptr< ROOT::Internal::RTaskArenaWrapperfTaskArenaW = nullptr
 

Additional Inherited Members

- Public Types inherited from ROOT::TExecutor< TThreadExecutor >
using noReferenceCond = typename std::enable_if<"Function can't return a reference" &&!(std::is_reference< typename std::result_of< F(T...)>::type >::value)>::type
 

#include <ROOT/TThreadExecutor.hxx>

Inheritance diagram for ROOT::TThreadExecutor:
[legend]

Constructor & Destructor Documentation

◆ TThreadExecutor() [1/2]

ROOT::TThreadExecutor::TThreadExecutor ( UInt_t  nThreads = 0u)
explicit

Class constructor.

If the scheduler is active (e.g. because another TThreadExecutor is in flight, or ROOT::EnableImplicitMT() was called), work with the current pool of threads. If not, initialize the pool of threads, spawning nThreads. nThreads' default value, 0, initializes the pool with as many logical threads as are available in the system (see NLogicalCores in RTaskArenaWrapper.cxx).

At construction time, TThreadExecutor automatically enables ROOT's thread-safety locks as per calling ROOT::EnableThreadSafety().

Definition at line 135 of file TThreadExecutor.cxx.

◆ TThreadExecutor() [2/2]

ROOT::TThreadExecutor::TThreadExecutor ( TThreadExecutor )
delete

Member Function Documentation

◆ Foreach() [1/4]

template<class F , class T >
void ROOT::TThreadExecutor::Foreach ( F  func,
const std::vector< T > &  args,
unsigned  nChunks = 0 
)

Execute func in parallel, taking an element of a std::vector as argument.

Definition at line 191 of file TThreadExecutor.hxx.

◆ Foreach() [2/4]

template<class F , class INTEGER >
void ROOT::TThreadExecutor::Foreach ( F  func,
ROOT::TSeq< INTEGER >  args,
unsigned  nChunks = 0 
)

Execute func in parallel, taking an element of a sequence as argument.

Definition at line 137 of file TThreadExecutor.hxx.

◆ Foreach() [3/4]

template<class F , class T >
void ROOT::TThreadExecutor::Foreach ( F  func,
std::vector< T > &  args,
unsigned  nChunks = 0 
)

Execute func in parallel, taking an element of an std::vector as argument.

Definition at line 171 of file TThreadExecutor.hxx.

◆ Foreach() [4/4]

template<class F >
void ROOT::TThreadExecutor::Foreach ( F  func,
unsigned  nTimes,
unsigned  nChunks = 0 
)

Execute func (with no arguments) nTimes in parallel.

Functions that take more than zero arguments can be executed (with fixed arguments) by wrapping them in a lambda or with std::bind.

Definition at line 117 of file TThreadExecutor.hxx.

◆ GetPoolSize()

unsigned ROOT::TThreadExecutor::GetPoolSize ( )

Definition at line 162 of file TThreadExecutor.cxx.

◆ Map() [1/7]

template<class F , class INTEGER , class Cond >
auto ROOT::TThreadExecutor::Map ( F  func,
ROOT::TSeq< INTEGER >  args 
) -> std::vector<typename std::result_of<F(INTEGER)>::type>

Execute func in parallel, taking an element of a sequence as argument.

A vector containg executions' results is returned.

Definition at line 231 of file TThreadExecutor.hxx.

◆ Map() [2/7]

template<class F , class INTEGER , class R , class Cond >
auto ROOT::TThreadExecutor::Map ( F  func,
ROOT::TSeq< INTEGER >  args,
R  redfunc,
unsigned  nChunks 
) -> std::vector<typename std::result_of<F(INTEGER)>::type>
protected

Execute func in parallel, taking an element of a sequence as argument.

Divides and groups the executions in nChunks (if it doesn't make sense will reduce the number of chunks) with partial reduction
A vector containg partial reductions' results is returned.

Definition at line 306 of file TThreadExecutor.hxx.

◆ Map() [3/7]

template<class F , class T , class R , class Cond = noReferenceCond<F, T>>
auto ROOT::TThreadExecutor::Map ( F  func,
std::initializer_list< T >  args,
R  redfunc,
unsigned  nChunks 
) -> std::vector< typename std::result_of< F(T)>::type >
protected

◆ Map() [4/7]

template<class F , class T , class Cond >
auto ROOT::TThreadExecutor::Map ( F  func,
std::vector< T > &  args 
) -> std::vector<typename std::result_of<F(T)>::type>

Execute func in parallel, taking an element of an std::vector as argument.

A vector containg executions' results is returned.

Definition at line 283 of file TThreadExecutor.hxx.

◆ Map() [5/7]

template<class F , class T , class R , class Cond = noReferenceCond<F, T>>
auto ROOT::TThreadExecutor::Map ( F  func,
std::vector< T > &  args,
R  redfunc,
unsigned  nChunks 
) -> std::vector< typename std::result_of< F(T)>::type >
protected

◆ Map() [6/7]

template<class F , class Cond >
auto ROOT::TThreadExecutor::Map ( F  func,
unsigned  nTimes 
) -> std::vector<typename std::result_of<F()>::type>

Execute func (with no arguments) nTimes in parallel.

A vector containg executions' results is returned. Functions that take more than zero arguments can be executed (with fixed arguments) by wrapping them in a lambda or with std::bind.

Definition at line 214 of file TThreadExecutor.hxx.

◆ Map() [7/7]

template<class F , class R , class Cond >
auto ROOT::TThreadExecutor::Map ( F  func,
unsigned  nTimes,
R  redfunc,
unsigned  nChunks 
) -> std::vector<typename std::result_of<F()>::type>
protected

Execute func (with no arguments) nTimes in parallel.

Divides and groups the executions in nChunks (if it doesn't make sense will reduce the number of chunks) with partial reduction; A vector containg partial reductions' results is returned.

Definition at line 252 of file TThreadExecutor.hxx.

◆ MapReduce() [1/5]

template<class F , class INTEGER , class R , class Cond >
auto ROOT::TThreadExecutor::MapReduce ( F  func,
ROOT::TSeq< INTEGER >  args,
R  redfunc,
unsigned  nChunks 
) -> typename std::result_of<F(INTEGER)>::type

Definition at line 400 of file TThreadExecutor.hxx.

◆ MapReduce() [2/5]

template<class F , class T , class R , class Cond >
auto ROOT::TThreadExecutor::MapReduce ( F  func,
std::vector< T > &  args,
R  redfunc 
) -> typename std::result_of<F(T)>::type

Definition at line 411 of file TThreadExecutor.hxx.

◆ MapReduce() [3/5]

template<class F , class T , class R , class Cond >
auto ROOT::TThreadExecutor::MapReduce ( F  func,
std::vector< T > &  args,
R  redfunc,
unsigned  nChunks 
) -> typename std::result_of<F(T)>::type

Definition at line 416 of file TThreadExecutor.hxx.

◆ MapReduce() [4/5]

template<class F , class R , class Cond >
auto ROOT::TThreadExecutor::MapReduce ( F  func,
unsigned  nTimes,
R  redfunc 
) -> typename std::result_of<F()>::type

This method behaves just like Map, but an additional redfunc function must be provided.

redfunc is applied to the vector Map would return and must return the same type as func. In practice, redfunc can be used to "squash" the vector returned by Map into a single object by merging, adding, mixing the elements of the vector.
The fourth argument indicates the number of chunks we want to divide our work in.

Definition at line 390 of file TThreadExecutor.hxx.

◆ MapReduce() [5/5]

template<class F , class R , class Cond >
auto ROOT::TThreadExecutor::MapReduce ( F  func,
unsigned  nTimes,
R  redfunc,
unsigned  nChunks 
) -> typename std::result_of<F()>::type

Definition at line 395 of file TThreadExecutor.hxx.

◆ operator=()

TThreadExecutor& ROOT::TThreadExecutor::operator= ( TThreadExecutor )
delete

◆ ParallelFor()

void ROOT::TThreadExecutor::ParallelFor ( unsigned  start,
unsigned  end,
unsigned  step,
const std::function< void(unsigned int i)> &  f 
)
private

Definition at line 140 of file TThreadExecutor.cxx.

◆ ParallelReduce() [1/2]

double ROOT::TThreadExecutor::ParallelReduce ( const std::vector< double > &  objs,
const std::function< double(double a, double b)> &  redfunc 
)
private

Definition at line 150 of file TThreadExecutor.cxx.

◆ ParallelReduce() [2/2]

float ROOT::TThreadExecutor::ParallelReduce ( const std::vector< float > &  objs,
const std::function< float(float a, float b)> &  redfunc 
)
private

Definition at line 156 of file TThreadExecutor.cxx.

◆ Reduce() [1/2]

template<class T , class BINARYOP >
auto ROOT::TThreadExecutor::Reduce ( const std::vector< T > &  objs,
BINARYOP  redfunc 
) -> decltype(redfunc(objs.front(), objs.front()))

"Reduce" an std::vector into a single object in parallel by passing a binary operator as the second argument to act on pairs of elements of the std::vector.

Definition at line 424 of file TThreadExecutor.hxx.

◆ Reduce() [2/2]

template<class T , class R >
auto ROOT::TThreadExecutor::Reduce ( const std::vector< T > &  objs,
R  redfunc 
) -> decltype(redfunc(objs))

"Reduce" an std::vector into a single object by passing a function as the second argument defining the reduction operation.

Definition at line 435 of file TThreadExecutor.hxx.

◆ SeqReduce()

template<class T , class R >
auto ROOT::TThreadExecutor::SeqReduce ( const std::vector< T > &  objs,
R  redfunc 
) -> decltype(redfunc(objs))
private

Definition at line 443 of file TThreadExecutor.hxx.

Member Data Documentation

◆ fTaskArenaW

std::shared_ptr<ROOT::Internal::RTaskArenaWrapper> ROOT::TThreadExecutor::fTaskArenaW = nullptr
private

Definition at line 107 of file TThreadExecutor.hxx.

Libraries for ROOT::TThreadExecutor:
[legend]

The documentation for this class was generated from the following files:
ROOT::ExecutorUtils::ReduceObjects
Merge collection of TObjects.
Definition: PoolUtils.h:35
ROOT::TThreadExecutor
This class provides a simple interface to execute the same task multiple times in parallel,...
Definition: TThreadExecutor.hxx:35
v
@ v
Definition: rootcling_impl.cxx:3635
a
auto * a
Definition: textangle.C:12
ROOT::TThreadExecutor::Map
auto Map(F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
Execute func (with no arguments) nTimes in parallel.
Definition: TThreadExecutor.hxx:214
ROOT::TThreadExecutor::MapReduce
auto MapReduce(F func, unsigned nTimes, R redfunc) -> typename std::result_of< F()>::type
This method behaves just like Map, but an additional redfunc function must be provided.
Definition: TThreadExecutor.hxx:390