- Timestamp:
- 06/23/23 14:35:34 (12 months ago)
- Location:
- XIOS3/trunk/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS3/trunk/src/event_scheduler.cpp
r2518 r2522 9 9 10 10 CEventScheduler::CEventScheduler(const MPI_Comm& comm) 11 { 12 schedulerLevel_=0 ; 13 parentScheduler_.reset(); 14 childScheduler_.reset(); 15 initialize(comm) ; 16 } 17 18 CEventScheduler::CEventScheduler(const MPI_Comm& comm, size_t schedulerLevel) 19 { 20 schedulerLevel_=schedulerLevel ; 21 parentScheduler_.reset(); 22 childScheduler_.reset(); 23 initialize(comm) ; 24 } 25 26 void CEventScheduler::initialize(const MPI_Comm& comm) 11 27 { 12 28 MPI_Comm_dup(comm, &communicator_) ; … … 72 88 while (!pendingSentParentRequest_.empty() || !pendingRecvParentRequest_.empty() || !pendingRecvChildRequest_.empty() || !pendingSentChildRequest_.empty()) 73 89 { 74 checkEvent () ;90 checkEvent_() ; 75 91 } 76 92 } 77 93 94 void CEventScheduler::splitScheduler(const MPI_Comm& splittedComm, shared_ptr<CEventScheduler>& parent, shared_ptr<CEventScheduler>& child) 95 { 96 int color ; 97 MPI_Comm newComm ; 98 child = make_shared<CEventScheduler>(splittedComm, schedulerLevel_+ 1) ; 99 if (child->isRoot()) color=1 ; 100 else color=0 ; 101 MPI_Comm_split(communicator_, color, mpiRank_, &newComm) ; 102 103 parent = make_shared<CEventScheduler>(newComm , schedulerLevel_) ; 104 child->setParentScheduler(parent) ; 105 parent->setChildScheduler(child) ; 106 if (parentScheduler_) 107 { 108 parentScheduler_->setChildScheduler(parent) ; 109 parent->setParentScheduler(parentScheduler_) ; 110 } 111 112 } 113 78 114 void CEventScheduler::registerEvent(const size_t timeLine, const size_t contextHashId) 79 115 { 80 registerEvent(timeLine, contextHashId, level_) ; 81 checkEvent() ; 82 } 83 84 void CEventScheduler::registerEvent(const size_t timeLine, const size_t contextHashId, const size_t lev) 116 getBaseScheduler()->registerEvent(timeLine, contextHashId, schedulerLevel_) ; 117 checkEvent_() ; 118 } 119 120 void CEventScheduler::registerEvent(const size_t timeLine, const size_t contextHashId, const size_t schedulerLevel) 121 { 122 registerEvent(timeLine, contextHashId, schedulerLevel, level_) ; 123 checkEvent_() ; 124 } 125 126 void CEventScheduler::registerEvent(const size_t timeLine, const size_t contextHashId, const size_t schedulerLevel, const size_t lev) 85 127 { 86 128 … … 89 131 sentRequest->buffer[0]=timeLine ; 90 132 sentRequest->buffer[1]=contextHashId ; 91 sentRequest->buffer[2]=lev-1 ; 133 sentRequest->buffer[2]=schedulerLevel ; 134 sentRequest->buffer[3]=lev-1 ; 92 135 93 136 pendingSentParentRequest_.push(sentRequest) ; 94 MPI_Isend(sentRequest->buffer,3, MPI_UNSIGNED_LONG, parent_[lev], 0, communicator_, &sentRequest->request) ; 137 // info(100)<<"CEventScheduler::registerEvent => send event to parent "<<parent_[lev]<<" of level" <<lev-1<<endl ; 138 MPI_Isend(sentRequest->buffer,4, MPI_UNSIGNED_LONG, parent_[lev], 0, communicator_, &sentRequest->request) ; 95 139 traceOn() ; 96 140 } 97 141 98 bool CEventScheduler::queryEvent(const size_t timeLine, const size_t contextHashId) 99 { 100 checkEvent() ; 142 143 bool CEventScheduler::queryEvent_(const size_t timeLine, const size_t contextHashId) 144 { 145 checkEvent_() ; 146 101 147 if (! eventStack_.empty() && eventStack_.front().first==timeLine && eventStack_.front().second==contextHashId) 102 148 { 103 //eventStack_.pop() ;104 149 return true ; 105 150 } … … 107 152 } 108 153 109 void CEventScheduler::checkEvent(void) 110 { 154 void CEventScheduler::checkEvent_(void) 155 { 156 157 if (parentScheduler_) parentScheduler_->checkEvent_() ; 111 158 traceOff() ; 112 159 checkChildRequest() ; … … 143 190 { 144 191 recvRequest=new SPendingRequest ; 145 MPI_Irecv(recvRequest->buffer, 3, MPI_UNSIGNED_LONG, MPI_ANY_SOURCE, 1, communicator_, &(recvRequest->request)) ;192 MPI_Irecv(recvRequest->buffer, 4, MPI_UNSIGNED_LONG, MPI_ANY_SOURCE, 1, communicator_, &(recvRequest->request)) ; 146 193 pendingRecvParentRequest_.push(recvRequest) ; 147 194 } … … 154 201 recvRequest=pendingRecvParentRequest_.front() ; 155 202 MPI_Test( &(recvRequest->request), &completed, &status) ; 203 156 204 if (completed) 157 205 { 158 206 size_t timeLine=recvRequest->buffer[0] ; 159 207 size_t hashId=recvRequest->buffer[1] ; 160 size_t lev=recvRequest->buffer[2] ; 208 size_t schedulerLevel=recvRequest->buffer[2] ; 209 size_t lev=recvRequest->buffer[3] ; 161 210 delete recvRequest ; 162 211 pendingRecvParentRequest_.pop() ; 163 164 if (lev==level_) eventStack_.push(pair<size_t,size_t>(timeLine,hashId)) ; 165 else bcastEvent(timeLine, hashId, lev) ; 212 213 // info(100)<<"CEventScheduler::checkParentRequest => receive event from parent "<< status.MPI_SOURCE<<"at level"<< lev<< endl ; 214 215 if (lev==level_) 216 { 217 if (childScheduler_) 218 { 219 // info(100)<<"CEventScheduler::checkParentRequest => bcast event to child scheduler "<<endl; 220 childScheduler_->bcastEvent(timeLine, hashId, schedulerLevel, 0) ; 221 } 222 else 223 { 224 // info(100)<<"CEventScheduler::checkParentRequest => put event to stack : timeLine : "<<timeLine<<" hashId : "<<hashId<<endl; 225 eventStack_.push(pair<size_t,size_t>(timeLine,hashId)) ; 226 } 227 } 228 else 229 { 230 // info(100)<<"CEventScheduler::checkParentRequest => bcast event to child process "<<endl; 231 bcastEvent(timeLine, hashId, schedulerLevel, lev) ; 232 } 166 233 } 167 234 } … … 185 252 { 186 253 recvRequest=new SPendingRequest ; 187 MPI_Irecv(recvRequest->buffer, 3, MPI_UNSIGNED_LONG, MPI_ANY_SOURCE, 0, communicator_, &recvRequest->request) ;254 MPI_Irecv(recvRequest->buffer, 4, MPI_UNSIGNED_LONG, MPI_ANY_SOURCE, 0, communicator_, &recvRequest->request) ; 188 255 pendingRecvChildRequest_.push_back(recvRequest) ; 189 256 } … … 199 266 size_t timeLine=(*it)->buffer[0] ; 200 267 size_t hashId=(*it)->buffer[1] ; 201 size_t lev=(*it)->buffer[2] ; 202 203 SEvent event={timeLine,hashId,lev} ; 268 size_t schedulerLevel=(*it)->buffer[2] ; 269 size_t lev=(*it)->buffer[3] ; 270 271 // info(100)<<"CEventScheduler::checkChildRequest => received event from child "<<status.MPI_SOURCE<<" at level "<<lev<<endl; 272 273 SEvent event={timeLine, hashId, schedulerLevel, lev} ; 204 274 delete *it ; // free mem 205 275 it=pendingRecvChildRequest_.erase(it) ; // get out of the list … … 216 286 if (lev==0) 217 287 { 218 bcastEvent(timeLine,hashId,lev) ; 288 if (schedulerLevel==schedulerLevel_) 289 { 290 // info(100)<<"CEventScheduler::checkChildRequest => bcastEvent to child"<<endl ; 291 bcastEvent(timeLine, hashId, schedulerLevel, lev) ; 292 } 293 else 294 { 295 // info(100)<<"CEventScheduler::checkChildRequest => register event to parent scheduler"<<endl ; 296 parentScheduler_->registerEvent(timeLine, hashId, schedulerLevel) ; 297 } 219 298 recvEvent_.erase(itEvent) ; 220 299 } 221 300 else 222 301 { 223 registerEvent( timeLine,hashId,lev) ; 302 // info(100)<<"CEventScheduler::checkChildRequest => register event to parent process"<<endl ; 303 registerEvent( timeLine,hashId, schedulerLevel, lev) ; 224 304 recvEvent_.erase(itEvent) ; 225 305 } … … 245 325 } 246 326 247 void CEventScheduler::bcastEvent(const size_t timeLine, const size_t contextHashId, const size_t lev)327 void CEventScheduler::bcastEvent(const size_t timeLine, const size_t contextHashId, const size_t schedulerLevel, const size_t lev) 248 328 { 249 329 SPendingRequest* sentRequest ; … … 255 335 sentRequest->buffer[0]=timeLine ; 256 336 sentRequest->buffer[1]=contextHashId ; 257 sentRequest->buffer[2]=lev+1 ; 258 MPI_Isend(sentRequest->buffer,3, MPI_UNSIGNED_LONG, child_[lev][i], 1, communicator_, & sentRequest->request) ; 337 sentRequest->buffer[2]=schedulerLevel ; 338 sentRequest->buffer[3]=lev+1 ; 339 MPI_Isend(sentRequest->buffer,4, MPI_UNSIGNED_LONG, child_[lev][i], 1, communicator_, & sentRequest->request) ; 259 340 pendingSentChildRequest_.push_back(sentRequest) ; 260 341 } -
XIOS3/trunk/src/event_scheduler.hpp
r2518 r2522 27 27 */ 28 28 CEventScheduler(const MPI_Comm& comm) ; 29 29 CEventScheduler(const MPI_Comm& comm, size_t schedulerLevel) ; 30 30 31 31 //! Destructor … … 40 40 */ 41 41 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();} 42 45 43 44 46 public: 45 47 //! public interface for query if the event defined by timeLine and hashId is sheduled next 46 48 /*! … … 51 53 * If the event is scheduled next, it is remove from the `eventStack` queue list 52 54 */ 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) ; 56 63 57 64 //! Public interface to give the hand to the instance to check pending or incoming message. … … 59 66 * Must be called periodicaly. Call `checkParentRequest` and `checkChildRequest` private method. 60 67 */ 61 void checkEvent(void) ; 68 void checkEvent(void) { getBaseScheduler()->checkEvent_(); } 69 void checkEvent_(void) ; 62 70 63 71 private: 64 65 72 void initialize(const MPI_Comm& comm) ; 73 66 74 //! Send an event to the parent of level `lev+1` 67 75 /*! … … 71 79 * The event is sent by an asynchrounous MPI_ISend 72 80 */ 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) ; 74 84 75 85 … … 108 118 * Asynchronus MPI_ISend is used. 109 119 */ 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) ; 111 121 112 122 … … 118 128 size_t timeLine ; /*!< Time line id of the event in the context */ 119 129 size_t hashId ; /*!< hassh id of the context */ 130 size_t schedulerLevel ; /*!< hierarchical level of scherduler */ 120 131 size_t level ; /*!<hierarchical level of the communication*/ 121 132 … … 127 138 bool operator==(const SEvent& e) const 128 139 { 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 ; 130 141 else return false ; 131 142 } ; … … 142 153 if (timeLine < e.timeLine) return true ; 143 154 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 ; 145 157 else return false ; 146 158 } ; 147 159 } ; 148 149 160 150 161 //! Pending request struture. It keep send or receive buffer from asynchronous communication while the request is not complete. 151 162 struct SPendingRequest 152 163 { 153 size_t buffer[ 3] ; /*!< communication buffer : timeLine, hashId, level */164 size_t buffer[4] ; /*!< communication buffer : timeLine, hashId, level */ 154 165 MPI_Request request ; /*!< pending MPI request */ 155 166 } ; … … 171 182 vector<vector<int> > child_ ; /*!< List of child rank for each level */ 172 183 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_ ; 173 189 174 190 } ;
Note: See TracChangeset
for help on using the changeset viewer.