Logo ROOT  
Reference Guide
Executor.h
Go to the documentation of this file.
1// @(#)root/tmva $Id$
2// Author: Lorenzo Moneta
3/*************************************************************************
4 * Copyright (C) 2019, ROOT/TMVA *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11//////////////////////////////////////////////////////////////////////////
12//
13// Defining Executor classes to be used in TMVA
14// wrapping the functionality of the ROOT TThreadExecutor and
15// ROOT TSequential Executor
16//
17/////////////////////////////////////////////////////////////////////////
18#ifndef ROOT_TMVA_Executor
19#define ROOT_TMVA_Executor
20
21#include <memory>
22
24#ifdef R__USE_IMT
26#endif
27
28#include <TROOT.h>
29#include <TError.h>
30
31namespace TMVA {
32
33
34/// Base Excutor class
35class Executor {
36
37public:
38
39 template< class F, class... T>
40 using noReferenceCond = typename std::enable_if<"Function can't return a reference" &&
41 !(std::is_reference<typename std::result_of<F(T...)>::type>::value)>::type;
42
43
44
45 //////////////////////////////////////
46 /// Default constructor of TMVA Executor class
47 /// if ROOT::EnableIMplicitMT has not been called then by default a serial executor will be created
48 /// A user can create a thread pool and enable multi-thread excution by calling TMVA::Config::Instance()::EnableMT(nthreads)
49 /// For releasing the thread pool used by TMVA one can do it by calling TMVA::Config::Instance()::DisableMT() or
50 /// calling TMVA::Config::Instance()::EnableMT with only one thread
51 ////////////////////////////////////////////
53 // enable MT in TMVA if ROOT::IsImplicitMT is enabled
55#ifdef R__USE_IMT
56 fMTExecImpl = std::unique_ptr< ROOT::TThreadExecutor>(new ROOT::TThreadExecutor());
57#else
58 ::Error("Executor","Cannot have TMVA in multi-threads mode when ROOT is built without IMT");
59#endif
60 }
61 // case of single thread usage
62 if (!fMTExecImpl)
63 fSeqExecImpl = std::unique_ptr<ROOT::TSequentialExecutor>(new ROOT::TSequentialExecutor());
64 }
65
66 //////////////////////////////////////
67 /// Constructor of TMVA Executor class
68 /// Explicit specify the number of threads. In this case if nthreads is > 1 a multi-threaded executor will be created and
69 /// TMVA will run in MT.
70 /// If nthreads = 1 instead TMVA will run in sequential mode
71 /// If nthreads = 0 TMVA will use the default thread pool size
72 ////////////////////////////////////////////
73 explicit Executor(int nthreads) {
74 // enable MT in TMVA if :
75 // - no specific MT
76 if ( nthreads != 1 ) {
77#ifdef R__USE_IMT
78 fMTExecImpl = std::unique_ptr< ROOT::TThreadExecutor>(new ROOT::TThreadExecutor(nthreads));
79#else
80 ::Error("Executor","Cannot have TMVA in multi-threads mode when ROOT is built without IMT");
81#endif
82 }
83 // case of single thread usage
84 if (!fMTExecImpl)
85 fSeqExecImpl = std::unique_ptr<ROOT::TSequentialExecutor>(new ROOT::TSequentialExecutor());
86 }
87
88#ifdef R__USE_IMT
90 if (fMTExecImpl) return fMTExecImpl.get();
91 else {
92 fMTExecImpl = std::unique_ptr< ROOT::TThreadExecutor>(new ROOT::TThreadExecutor());
93 Info("GetThreadExecutor","Creating a TThread executor with a pool with a defult size of %d",fMTExecImpl->GetPoolSize());
94 return fMTExecImpl.get();
95 }
96 }
97#endif
98
99 unsigned int GetPoolSize() const {
100 if (!fMTExecImpl) return 1;
101#ifdef R__USE_IMT
102 return fMTExecImpl->GetPoolSize();
103#else
104 return 1;
105#endif
106 }
107
108 /// wrap TExecutor::Foreach
109 template<class Function>
110 void Foreach(Function func, unsigned int nTimes, unsigned nChunks = 0) {
111 if (fMTExecImpl) fMTExecImpl->Foreach(func,nTimes, nChunks);
112 else fSeqExecImpl->Foreach(func,nTimes);
113 }
114 template<class Function, class T>
115 void Foreach(Function func, std::vector<T> & args, unsigned nChunks = 0) {
116 if (fMTExecImpl) fMTExecImpl->Foreach(func,args, nChunks);
117 else fSeqExecImpl->Foreach(func, args);
118 }
119 template<class Function, class INTEGER>
120#ifdef R__USE_IMT
121 void Foreach(Function func, ROOT::TSeq<INTEGER> args, unsigned nChunks = 0){
122 if (fMTExecImpl) fMTExecImpl->Foreach(func,args, nChunks);
123 else fSeqExecImpl->Foreach(func, args);
124 }
125#else
126 void Foreach(Function func, ROOT::TSeq<INTEGER> args, unsigned /*nChunks*/ = 0){
127 fSeqExecImpl->Foreach(func, args);
128 }
129#endif
130
131 /// Wrap TExecutor::Map functions
132 template<class F, class Cond = noReferenceCond<F>>
133 auto Map(F func, unsigned nTimes) -> std::vector<typename std::result_of<F()>::type> {
134 if (fMTExecImpl) return fMTExecImpl->Map(func,nTimes);
135 else return fSeqExecImpl->Map(func, nTimes);
136 }
137 template<class F, class INTEGER, class Cond = noReferenceCond<F, INTEGER>>
138 auto Map(F func, ROOT::TSeq<INTEGER> args) -> std::vector<typename std::result_of<F(INTEGER)>::type> {
139 if (fMTExecImpl) return fMTExecImpl->Map(func,args);
140 else return fSeqExecImpl->Map(func, args);
141 }
142
143 /// Wrap TExecutor::MapReduce functions
144 template<class F, class INTEGER, class R, class Cond = noReferenceCond<F, INTEGER>>
145 auto MapReduce(F func, ROOT::TSeq<INTEGER> args, R redfunc) -> typename std::result_of<F(INTEGER)>::type {
146 if (fMTExecImpl) return fMTExecImpl->MapReduce(func, args, redfunc);
147 else return fSeqExecImpl->MapReduce(func, args, redfunc);
148 }
149 template<class F, class INTEGER, class R, class Cond = noReferenceCond<F, INTEGER>>
150 auto MapReduce(F func, ROOT::TSeq<INTEGER> args, R redfunc, unsigned nChunks) -> typename std::result_of<F(INTEGER)>::type {
151 if (fMTExecImpl) return fMTExecImpl->MapReduce(func, args, redfunc, nChunks);
152 else return fSeqExecImpl->MapReduce(func, args, redfunc);
153 }
154
155 ///Wrap Reduce function
156 template<class T, class R>
157 auto Reduce(const std::vector<T> &objs, R redfunc) -> decltype(redfunc(objs)) {
158 if (fMTExecImpl) return fMTExecImpl->Reduce(objs, redfunc);
159 else return fSeqExecImpl->Reduce(objs, redfunc);
160 }
161 //template<class T> T* Reduce(const std::vector<T*> &mergeObjs);
162
163#ifdef R__USE_IMT
164 std::unique_ptr<ROOT::TThreadExecutor> fMTExecImpl;
165#else
166 std::unique_ptr<ROOT::TSequentialExecutor> fMTExecImpl; // if not using MT the two pointers will be of same type
167#endif
168 std::unique_ptr<ROOT::TSequentialExecutor> fSeqExecImpl;
169};
170
171} // end namespace TMVA
172
173#endif
#define R(a, b, c, d, e, f, g, h, i)
Definition: RSha256.hxx:110
void Info(const char *location, const char *msgfmt,...)
void Error(const char *location, const char *msgfmt,...)
int type
Definition: TGX11.cxx:120
Double_t(* Function)(Double_t)
Definition: Functor.C:4
A pseudo container class which is a generator of indices.
Definition: TSeq.hxx:66
This class provides a simple interface to execute the same task multiple times in parallel,...
Base Excutor class.
Definition: Executor.h:35
void Foreach(Function func, unsigned int nTimes, unsigned nChunks=0)
wrap TExecutor::Foreach
Definition: Executor.h:110
auto MapReduce(F func, ROOT::TSeq< INTEGER > args, R redfunc, unsigned nChunks) -> typename std::result_of< F(INTEGER)>::type
Definition: Executor.h:150
std::unique_ptr< ROOT::TSequentialExecutor > fSeqExecImpl
Definition: Executor.h:168
typename std::enable_if<"Function can't return a reference" &&!(std::is_reference< typename std::result_of< F(T...)>::type >::value)>::type noReferenceCond
Definition: Executor.h:41
auto Reduce(const std::vector< T > &objs, R redfunc) -> decltype(redfunc(objs))
Wrap Reduce function.
Definition: Executor.h:157
unsigned int GetPoolSize() const
Definition: Executor.h:99
auto MapReduce(F func, ROOT::TSeq< INTEGER > args, R redfunc) -> typename std::result_of< F(INTEGER)>::type
Wrap TExecutor::MapReduce functions.
Definition: Executor.h:145
auto Map(F func, ROOT::TSeq< INTEGER > args) -> std::vector< typename std::result_of< F(INTEGER)>::type >
Definition: Executor.h:138
void Foreach(Function func, std::vector< T > &args, unsigned nChunks=0)
Definition: Executor.h:115
Executor()
Default constructor of TMVA Executor class if ROOT::EnableIMplicitMT has not been called then by defa...
Definition: Executor.h:52
std::unique_ptr< ROOT::TThreadExecutor > fMTExecImpl
Definition: Executor.h:164
void Foreach(Function func, ROOT::TSeq< INTEGER > args, unsigned nChunks=0)
Definition: Executor.h:121
Executor(int nthreads)
Constructor of TMVA Executor class Explicit specify the number of threads.
Definition: Executor.h:73
ROOT::TThreadExecutor * GetMultiThreadExecutor()
Definition: Executor.h:89
auto Map(F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
Wrap TExecutor::Map functions.
Definition: Executor.h:133
#define F(x, y, z)
double T(double x)
Definition: ChebyshevPol.h:34
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
Definition: TROOT.cxx:611
create variable transformations