18 #ifndef ROOT_TMVA_Executor
19 #define ROOT_TMVA_Executor
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;
54 if (ROOT::IsImplicitMTEnabled() ) {
56 fMTExecImpl = std::unique_ptr< ROOT::TThreadExecutor>(
new ROOT::TThreadExecutor());
58 ::Error(
"Executor",
"Cannot have TMVA in multi-threads mode when ROOT is built without IMT");
63 fSeqExecImpl = std::unique_ptr<ROOT::TSequentialExecutor>(
new ROOT::TSequentialExecutor());
73 explicit Executor(
int nthreads) {
76 if ( nthreads != 1 ) {
78 fMTExecImpl = std::unique_ptr< ROOT::TThreadExecutor>(
new ROOT::TThreadExecutor(nthreads));
80 ::Error(
"Executor",
"Cannot have TMVA in multi-threads mode when ROOT is built without IMT");
85 fSeqExecImpl = std::unique_ptr<ROOT::TSequentialExecutor>(
new ROOT::TSequentialExecutor());
89 ROOT::TThreadExecutor * GetMultiThreadExecutor() {
90 if (fMTExecImpl)
return fMTExecImpl.get();
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();
99 unsigned int GetPoolSize()
const {
100 if (!fMTExecImpl)
return 1;
102 return fMTExecImpl->GetPoolSize();
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);
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);
119 template<
class Function,
class INTEGER>
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);
126 void Foreach(Function func, ROOT::TSeq<INTEGER> args,
unsigned = 0){
127 fSeqExecImpl->Foreach(func, args);
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);
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);
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);
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);
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);
164 std::unique_ptr<ROOT::TThreadExecutor> fMTExecImpl;
166 std::unique_ptr<ROOT::TSequentialExecutor> fMTExecImpl;
168 std::unique_ptr<ROOT::TSequentialExecutor> fSeqExecImpl;