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;