source: XIOS/dev/dev_ym/XIOS_COUPLING/src/manager/servers_ressource.cpp @ 2220

Last change on this file since 2220 was 2220, checked in by ymipsl, 3 years ago

Add synchronisation at service and manager creation, not sure it needed, but better to have it.
YM

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