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