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