Ignore:
Timestamp:
06/23/23 14:35:34 (12 months ago)
Author:
ymipsl
Message:

Improvment of event scheduler. Now a hierachical approach make possible event scheduling accross different process groups, if a parent group of process is totally overlapping a child group of process.
YM

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS3/trunk/src/event_scheduler.hpp

    r2518 r2522  
    2727        */ 
    2828       CEventScheduler(const MPI_Comm& comm) ; 
    29  
     29       CEventScheduler(const MPI_Comm& comm, size_t schedulerLevel) ; 
    3030 
    3131       //! Destructor 
     
    4040        */ 
    4141       void registerEvent(const size_t timeLine, const size_t contextHashId) ; 
     42        
     43       private: 
     44       CEventScheduler* getBaseScheduler(void) { if (childScheduler_== nullptr) return this; else return childScheduler_->getBaseScheduler();} 
    4245 
    43  
    44  
     46       public: 
    4547       //! public interface for query if the event defined by timeLine and hashId is sheduled next 
    4648       /*! 
     
    5153        *  If the event is scheduled next, it is remove from the `eventStack` queue list   
    5254        */     
    53        bool queryEvent(const size_t timeLine, const size_t contextHashId) ; 
    54        void popEvent() { eventStack_.pop() ; } 
    55  
     55       bool queryEvent(const size_t timeLine, const size_t contextHashId) { return getBaseScheduler()->queryEvent_(timeLine, contextHashId); } 
     56       bool queryEvent_(const size_t timeLine, const size_t contextHashId) ; 
     57       void popEvent() { getBaseScheduler()->popEvent_() ; } 
     58       void popEvent_() { eventStack_.pop() ; } 
     59       bool isRoot(void) { return parent_[0]==mpiRank_ ;} 
     60       void setParentScheduler(shared_ptr<CEventScheduler> parentScheduler) { parentScheduler_ = parentScheduler ;} 
     61       void setChildScheduler(shared_ptr<CEventScheduler> childScheduler) { childScheduler_ = childScheduler ;} 
     62       void splitScheduler(const MPI_Comm& splittedComm, shared_ptr<CEventScheduler>& parent, shared_ptr<CEventScheduler>& child) ; 
    5663 
    5764       //! Public interface to give the hand to the instance to check pending or incoming message. 
     
    5966        * Must be called periodicaly. Call `checkParentRequest` and `checkChildRequest` private method. 
    6067        */ 
    61        void checkEvent(void) ; 
     68       void checkEvent(void) { getBaseScheduler()->checkEvent_(); }  
     69       void checkEvent_(void) ; 
    6270 
    6371       private: 
    64  
    65  
     72         void initialize(const MPI_Comm& comm) ; 
     73        
    6674       //! Send an event to the parent of level `lev+1` 
    6775       /*! 
     
    7179        *  The event is sent by an asynchrounous MPI_ISend 
    7280        */ 
    73        void registerEvent(const size_t timeLine, const size_t contextHashId, const size_t lev) ; 
     81       
     82       void registerEvent(const size_t timeLine, const size_t contextHashId, const size_t schedulerLevel) ; 
     83       void registerEvent(const size_t timeLine, const size_t contextHashId, const size_t schedulerLevel, const size_t lev) ; 
    7484 
    7585 
     
    108118        * Asynchronus MPI_ISend is used. 
    109119        */ 
    110        void bcastEvent(const size_t timeLine, const size_t contextHashId, const size_t lev) ; 
     120       void bcastEvent(const size_t timeLine, const size_t contextHashId, const size_t schedulerLevel ,const size_t lev) ; 
    111121        
    112122 
     
    118128         size_t timeLine ; /*!< Time line id of the event in the context */ 
    119129         size_t hashId ; /*!< hassh id of the context */ 
     130         size_t schedulerLevel ; /*!< hierarchical level of scherduler */ 
    120131         size_t level ;  /*!<hierarchical level of the communication*/ 
    121132 
     
    127138         bool operator==(const SEvent& e) const 
    128139         {  
    129            if (timeLine == e.timeLine && hashId == e.hashId && level==e.level) return true ; 
     140           if (timeLine == e.timeLine && hashId == e.hashId && level==e.level && schedulerLevel==e.schedulerLevel) return true ; 
    130141           else return false ; 
    131142         } ; 
     
    142153           if (timeLine < e.timeLine) return true ; 
    143154           else if (timeLine == e.timeLine && hashId < e.hashId) return true ; 
    144            else if (timeLine == e.timeLine && hashId == e.hashId && level<e.level) return true ; 
     155           else if (timeLine == e.timeLine && hashId == e.hashId && schedulerLevel<e.schedulerLevel) return true ; 
     156           else if (timeLine == e.timeLine && hashId == e.hashId && schedulerLevel==e.schedulerLevel && level<e.level) return true ; 
    145157           else return false ; 
    146158         } ; 
    147159       } ;        
    148          
    149  
     160        
    150161       //! Pending request struture. It keep send or receive buffer from asynchronous communication while the request is not complete. 
    151162       struct SPendingRequest 
    152163       { 
    153          size_t buffer[3] ;      /*!< communication buffer : timeLine, hashId, level */ 
     164         size_t buffer[4] ;      /*!< communication buffer : timeLine, hashId, level */ 
    154165         MPI_Request request ;   /*!< pending MPI request */  
    155166       } ; 
     
    171182       vector<vector<int> >  child_ ; /*!< List of child rank for each level */ 
    172183       vector<int> nbChild_ ;         /*!< Number of child for each level */     
     184        
     185       shared_ptr<CEventScheduler> parentScheduler_ ; 
     186       shared_ptr<CEventScheduler> childScheduler_ ; 
     187       bool hasParentScheduler_=false ; 
     188       size_t schedulerLevel_ ; 
    173189 
    174190    } ; 
Note: See TracChangeset for help on using the changeset viewer.