source: XIOS3/trunk/src/manager/servers_ressource.cpp @ 2523

Last change on this file since 2523 was 2523, checked in by ymipsl, 12 months ago

Adaptation to new hyper event scheduler.
YM

  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 5.4 KB
Line 
1#include "servers_ressource.hpp"
2#include "window_manager.hpp"
3#include "ressources_manager.hpp"
4#include "pool_ressource.hpp"
5#include "event_scheduler.hpp"
6#include "cxios.hpp"
7#include "mpi.hpp"
8#include "timer.hpp"
9#include <vector>
10#include <string>
11
12
13
14
15
16namespace xios
17{
18  using namespace std ;
19
20  CServersRessource::CServersRessource(MPI_Comm serverComm) : poolRessource_(nullptr), finalizeSignal_(false)
21  {
22
23    MPI_Comm_dup(serverComm, &serverComm_) ;
24    MPI_Comm xiosComm=CXios::getXiosComm() ;
25 
26    int localRank, globalRank ;
27    MPI_Comm_rank(xiosComm,&globalRank) ;
28    MPI_Comm_rank(serverComm_,&localRank) ;
29   
30    winNotify_ = new CWindowManager(serverComm_, maxBufferSize_) ;
31    MPI_Barrier(serverComm_) ;
32    if (localRank==localLeader_) 
33    {
34      int commSize ;
35      MPI_Comm_size(serverComm_,&commSize) ;
36      CXios::getRessourcesManager()->registerServerLeader(globalRank) ;
37      CXios::getRessourcesManager()->registerRessourcesSize(commSize) ;
38      freeRessourcesRank_.resize(commSize) ;
39      for(int i=0;i<commSize;i++) freeRessourcesRank_[i]=i ;
40    }
41
42    MPI_Comm_dup(serverComm_, &freeRessourcesComm_) ; 
43    eventScheduler_ = make_shared<CEventScheduler>(freeRessourcesComm_) ;
44    freeRessourceEventScheduler_ = eventScheduler_ ;
45  }
46
47  void CServersRessource::createPool(const string& poolId, const int size)
48  {
49    int commSize ;
50    MPI_Comm_size(serverComm_,&commSize) ;
51    vector<int> newFreeRessourcesRank(freeRessourcesRank_.size()-size) ;
52
53    bool isPartOf ;
54
55    for(int i=0, j=0; i<freeRessourcesRank_.size();i++) 
56    {
57       if (i<size) isPartOf=true ;
58       else 
59       {
60         isPartOf=false ;
61         newFreeRessourcesRank[j]=freeRessourcesRank_[i] ;
62         j++ ;
63       }
64       
65       notifyOutType_=NOTIFY_CREATE_POOL ;
66       notifyOutCreatePool_ = make_tuple(poolId, isPartOf) ;
67       sendNotification(freeRessourcesRank_[i]) ;
68    }
69    freeRessourcesRank_ = std::move(newFreeRessourcesRank) ;
70  }
71
72  void CServersRessource::finalize(void)
73  {
74    int commSize ;
75    MPI_Comm_size(serverComm_,&commSize) ;
76
77    for(int rank=0; rank<commSize;rank++)
78    { 
79      notifyOutType_=NOTIFY_FINALIZE ;
80      sendNotification(rank) ;
81    }
82  }
83
84  void CServersRessource::sendNotification(int rank)
85  {
86    winNotify_->pushToExclusiveWindow(rank, this, &CServersRessource::notificationsDumpOut) ;
87  }
88
89
90  void CServersRessource::notificationsDumpOut(CBufferOut& buffer)
91  {
92   
93    buffer.realloc(maxBufferSize_) ;
94   
95    if (notifyOutType_==NOTIFY_CREATE_POOL)
96    {
97      auto& arg=notifyOutCreatePool_ ;
98      buffer << notifyOutType_ << std::get<0>(arg) << std::get<1>(arg) ;
99    }
100    else if (notifyOutType_==NOTIFY_FINALIZE) buffer << notifyOutType_ ;
101  }
102
103  void CServersRessource::notificationsDumpIn(CBufferIn& buffer)
104  {
105    if (buffer.bufferSize() == 0) notifyInType_= NOTIFY_NOTHING ;
106    else
107    {
108      buffer>>notifyInType_;
109      if (notifyInType_==NOTIFY_CREATE_POOL)
110      {
111        auto& arg=notifyInCreatePool_ ;
112        buffer >> std::get<0>(arg) >> std::get<1>(arg)  ;
113      }
114      else if (notifyInType_==NOTIFY_FINALIZE) { /*nothing to do*/}
115    }
116  }
117
118  bool CServersRessource::eventLoop(bool serviceOnly)
119  {
120    CTimer::get("CServersRessource::eventLoop").resume();
121    double time=MPI_Wtime() ;
122    int flag ;
123    MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, MPI_STATUS_IGNORE);
124
125    if (time-lastEventLoop_ > eventLoopLatency_) 
126    {
127      checkNotifications() ;
128      lastEventLoop_=time ;
129    }
130
131    if (poolRessource_!=nullptr) 
132    {
133      if (poolRessource_->eventLoop(serviceOnly))
134      {
135        delete poolRessource_ ;
136        poolRessource_=nullptr ;
137        // don't forget to free pool ressource later
138      } 
139    }
140    CTimer::get("CServersRessource::eventLoop").suspend();
141    if (poolRessource_==nullptr && finalizeSignal_) return true ;
142    else return false ;
143  }
144
145  void CServersRessource::checkNotifications(void)
146  {
147    int commRank ;
148    MPI_Comm_rank(serverComm_, &commRank) ;
149    winNotify_->popFromExclusiveWindow(commRank, this, &CServersRessource::notificationsDumpIn) ;
150    if (notifyInType_==NOTIFY_CREATE_POOL) createPool() ;
151    else if (notifyInType_==NOTIFY_FINALIZE) finalizeSignal() ;
152  }
153
154  void CServersRessource::createPool(void)
155  {
156    auto& arg=notifyInCreatePool_ ;
157    string poolId=get<0>(arg) ;
158    bool isPartOf=get<1>(arg) ;
159   
160    int commRank ;
161    MPI_Comm poolComm ;
162    MPI_Comm_rank(freeRessourcesComm_,&commRank) ;
163    MPI_Comm_split(freeRessourcesComm_, isPartOf, commRank, &poolComm) ;
164   
165    shared_ptr<CEventScheduler> parentScheduler, childScheduler ;
166    freeRessourceEventScheduler_->splitScheduler(poolComm, parentScheduler, childScheduler) ;
167   
168    if (isFirstSplit_) eventScheduler_ = parentScheduler ; 
169    isFirstSplit_ = false ;
170
171    if (isPartOf)
172    { 
173      poolRessource_ = new CPoolRessource(poolComm, childScheduler, poolId, true) ;
174      MPI_Comm_free(&poolComm) ;
175    }
176    else 
177    {
178      freeRessourceEventScheduler_ = childScheduler ;
179      MPI_Comm_free(&freeRessourcesComm_) ;
180      freeRessourcesComm_=poolComm ;
181    }
182
183  }
184 
185  void CServersRessource::finalizeSignal(void)
186  {
187    finalizeSignal_=true ;
188    if (poolRessource_!=nullptr) poolRessource_->finalizeSignal() ;
189  }
190
191  bool CServersRessource::isServerLeader(void)
192  {
193    int commRank ;
194    MPI_Comm_rank(serverComm_,&commRank) ;
195    if (commRank==localLeader_) return true ;
196    else return false ;
197  }
198
199  CServersRessource::~CServersRessource()
200  {
201    delete winNotify_ ;
202  }
203}
Note: See TracBrowser for help on using the repository browser.