Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:22:42

0001 // @(#)root/thread:$Id$
0002 // Author: Xavier Valls November 2017
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 #ifndef ROOT_TSequentialExecutor
0012 #define ROOT_TSequentialExecutor
0013 
0014 #include "ROOT/EExecutionPolicy.hxx"
0015 #include "ROOT/TExecutorCRTP.hxx"
0016 #include "ROOT/TSeq.hxx"
0017 
0018 #include <initializer_list>
0019 #include <numeric> //std::accumulate
0020 #include <utility> //std::move
0021 #include <vector>
0022 
0023 namespace ROOT {
0024 
0025    class TSequentialExecutor: public TExecutorCRTP<TSequentialExecutor> {
0026       friend TExecutorCRTP;
0027 
0028    public:
0029 
0030       TSequentialExecutor() = default;
0031       TSequentialExecutor(const TSequentialExecutor &) = delete;
0032       TSequentialExecutor &operator=(const TSequentialExecutor &) = delete;
0033 
0034       // Foreach
0035       //
0036       template<class F>
0037       void Foreach(F func, unsigned nTimes);
0038       template<class F, class INTEGER>
0039       void Foreach(F func, ROOT::TSeq<INTEGER> args);
0040       template<class F, class T>
0041       void Foreach(F func, std::initializer_list<T> args);
0042       template<class F, class T>
0043       void Foreach(F func, std::vector<T> &args);
0044       template<class F, class T>
0045       void Foreach(F func, const std::vector<T> &args);
0046 
0047       // Map
0048       //
0049       using TExecutorCRTP<TSequentialExecutor>::Map;
0050 
0051       // MapReduce
0052       // the late return types also check at compile-time whether redfunc is compatible with func,
0053       // other than checking that func is compatible with the type of arguments.
0054       // a static_assert check in TSequentialExecutor::Reduce is used to check that redfunc is compatible with the type returned by func
0055       using TExecutorCRTP<TSequentialExecutor>::MapReduce;
0056 
0057       // Reduce
0058       //
0059       using TExecutorCRTP<TSequentialExecutor>::Reduce;
0060 
0061       //////////////////////////////////////////////////////////////////////////
0062       /// \brief Return the number of workers in the sequential executor: a single one.
0063       ///
0064       /// \return The number of workers in the pool, one.
0065       unsigned GetPoolSize() const { return 1u; }
0066 
0067    private:
0068        // Implementation of the Map functions declared in the parent class (TExecutorCRTP)
0069       //
0070       template<class F, class Cond = validMapReturnCond<F>>
0071       auto MapImpl(F func, unsigned nTimes) -> std::vector<InvokeResult_t<F>>;
0072       template<class F, class INTEGER, class Cond = validMapReturnCond<F, INTEGER>>
0073       auto MapImpl(F func, ROOT::TSeq<INTEGER> args) -> std::vector<InvokeResult_t<F, INTEGER>>;
0074       template<class F, class T, class Cond = validMapReturnCond<F, T>>
0075       auto MapImpl(F func, std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>;
0076       template<class F, class T, class Cond = validMapReturnCond<F, T>>
0077       auto MapImpl(F func, const std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>;
0078    };
0079 
0080    /************ TEMPLATE METHODS IMPLEMENTATION ******************/
0081 
0082    //////////////////////////////////////////////////////////////////////////
0083    /// \brief Execute a function without arguments several times, dividing the execution in nChunks.
0084    ///
0085    /// \param func Function to be executed.
0086    /// \param nTimes Number of times function should be called.
0087    template<class F>
0088    void TSequentialExecutor::Foreach(F func, unsigned nTimes) {
0089       for (auto i = 0U; i < nTimes; ++i) func();
0090    }
0091 
0092    //////////////////////////////////////////////////////////////////////////
0093    /// \brief Execute a function over a sequence of indexes, dividing the execution in nChunks.
0094    ///
0095    /// \param func Function to be executed. Must take an element of the sequence passed assecond argument as a parameter.
0096    /// \param args Sequence of indexes to execute `func` on.
0097    template<class F, class INTEGER>
0098    void TSequentialExecutor::Foreach(F func, ROOT::TSeq<INTEGER> args) {
0099       for(auto i : args) func(i);
0100    }
0101 
0102    //////////////////////////////////////////////////////////////////////////
0103    /// \brief Execute a function over the elements of an initializer_list, dividing the execution in nChunks.
0104    ///
0105    /// \param func Function to be executed on the elements of the initializer_list passed as second parameter.
0106    /// \param args initializer_list for a vector to apply `func` on.
0107    template<class F, class T>
0108    void TSequentialExecutor::Foreach(F func, std::initializer_list<T> args) {
0109       std::vector<T> vargs(std::move(args));
0110       Foreach(func, vargs);
0111    }
0112 
0113    //////////////////////////////////////////////////////////////////////////
0114    /// \brief Execute a function over the elements of a vector, dividing the execution in nChunks.
0115    ///
0116    /// \param func Function to be executed on the elements of the vector passed as second parameter.
0117    /// \param args Vector of elements passed as an argument to `func`.
0118    template<class F, class T>
0119    void TSequentialExecutor::Foreach(F func, std::vector<T> &args) {
0120       for(auto &&arg: args) {
0121          func(arg);
0122       }
0123    }
0124 
0125    //////////////////////////////////////////////////////////////////////////
0126    /// \brief Execute a function over the elements of an immutable vector, dividing the execution in nChunks.
0127    ///
0128    /// \param func Function to be executed on the elements of the immutable vector passed as second parameter.
0129    /// \param args Immutable vector of elements passed as an argument to `func`.
0130    template<class F, class T>
0131    void TSequentialExecutor::Foreach(F func, const std::vector<T> &args) {
0132       for(auto &&arg: args) {
0133          func(arg);
0134       }
0135    }
0136 
0137    //////////////////////////////////////////////////////////////////////////
0138    /// \brief Execute a function without arguments several times.
0139    /// Implementation of the Map method.
0140    ///
0141    /// \copydetails TExecutorCRTP::Map(F func,unsigned nTimes)
0142    template<class F, class Cond>
0143    auto TSequentialExecutor::MapImpl(F func, unsigned nTimes) -> std::vector<InvokeResult_t<F>> {
0144       using retType = decltype(func());
0145       std::vector<retType> reslist;
0146       reslist.reserve(nTimes);
0147       while(reslist.size() < nTimes) {
0148          reslist.emplace_back(func());
0149       }
0150       return reslist;
0151    }
0152 
0153    //////////////////////////////////////////////////////////////////////////
0154    /// \brief Execute a function over a sequence of indexes.
0155    /// Implementation of the Map method.
0156    ///
0157    /// \copydetails TExecutorCRTP::Map(F func,ROOT::TSeq<INTEGER> args)
0158    template<class F, class INTEGER, class Cond>
0159    auto TSequentialExecutor::MapImpl(F func, ROOT::TSeq<INTEGER> args) -> std::vector<InvokeResult_t<F, INTEGER>> {
0160       using retType = decltype(func(*args.begin()));
0161       std::vector<retType> reslist;
0162       reslist.reserve(args.size());
0163       for(auto i: args)
0164          reslist.emplace_back(func(i));
0165       return reslist;
0166    }
0167 
0168    //////////////////////////////////////////////////////////////////////////
0169    /// \brief Execute a function over the elements of a vector in parallel
0170    /// Implementation of the Map method.
0171    ///
0172    /// \copydetails TExecutorCRTP::Map(F func,std::vector<T> &args)
0173    template<class F, class T, class Cond>
0174    auto TSequentialExecutor::MapImpl(F func, std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>> {
0175       // //check whether func is callable
0176       using retType = decltype(func(args.front()));
0177       std::vector<retType> reslist;
0178       reslist.reserve(args.size());
0179       for(auto &&arg: args) {
0180          reslist.emplace_back(func(arg));
0181       }
0182       return reslist;
0183    }
0184 
0185    //////////////////////////////////////////////////////////////////////////
0186    /// \brief Execute a function over the elements of an immutable vector.
0187    /// Implementation of the Map method.
0188    ///
0189    /// \copydetails TExecutorCRTP::Map(F func,const std::vector<T> &args)
0190    template<class F, class T, class Cond>
0191    auto TSequentialExecutor::MapImpl(F func, const std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>> {
0192       // //check whether func is callable
0193       using retType = decltype(func(args.front()));
0194       std::vector<retType> reslist;
0195       reslist.reserve(args.size());
0196       for(auto &&arg: args) {
0197          reslist.emplace_back(func(arg));
0198       }
0199       return reslist;
0200    }
0201 
0202 } // namespace ROOT
0203 #endif