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

Last change on this file since 2518 was 2517, checked in by ymipsl, 13 months ago

New way to manage locks in window manager. Windows is locked with MPI_Win_lock_all at creation (shared mode), and lock is manage by software way in the class (using MPI_swap_and_compare and MPI_Fetch_op). We get in this case a better control of lock, with controled latency between each attemp of lock.

YM

  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 5.0 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 "timer.hpp"
8#include <vector>
9#include <string>
10
11
12
13
14namespace xios
15{
16  using namespace std ;
17
18  CServersRessource::CServersRessource(MPI_Comm serverComm) : poolRessource_(nullptr), finalizeSignal_(false)
19  {
20
21    MPI_Comm_dup(serverComm, &serverComm_) ;
22    MPI_Comm xiosComm=CXios::getXiosComm() ;
23 
24    int localRank, globalRank ;
25    MPI_Comm_rank(xiosComm,&globalRank) ;
26    MPI_Comm_rank(serverComm_,&localRank) ;
27   
28    winNotify_ = new CWindowManager(serverComm_, maxBufferSize_) ;
29    MPI_Barrier(serverComm_) ;
30    if (localRank==localLeader_) 
31    {
32      int commSize ;
33      MPI_Comm_size(serverComm_,&commSize) ;
34      CXios::getRessourcesManager()->registerServerLeader(globalRank) ;
35      CXios::getRessourcesManager()->registerRessourcesSize(commSize) ;
36      freeRessourcesRank_.resize(commSize) ;
37      for(int i=0;i<commSize;i++) freeRessourcesRank_[i]=i ;
38    }
39
40    MPI_Comm_dup(serverComm_, &freeRessourcesComm_) ; 
41
42  }
43
44  void CServersRessource::createPool(const string& poolId, const int size)
45  {
46    int commSize ;
47    MPI_Comm_size(serverComm_,&commSize) ;
48    vector<int> newFreeRessourcesRank(freeRessourcesRank_.size()-size) ;
49
50    bool isPartOf ;
51
52    for(int i=0, j=0; i<freeRessourcesRank_.size();i++) 
53    {
54       if (i<size) isPartOf=true ;
55       else 
56       {
57         isPartOf=false ;
58         newFreeRessourcesRank[j]=freeRessourcesRank_[i] ;
59         j++ ;
60       }
61       
62       notifyOutType_=NOTIFY_CREATE_POOL ;
63       notifyOutCreatePool_ = make_tuple(poolId, isPartOf) ;
64       sendNotification(freeRessourcesRank_[i]) ;
65    }
66    freeRessourcesRank_ = std::move(newFreeRessourcesRank) ;
67  }
68
69  void CServersRessource::finalize(void)
70  {
71    int commSize ;
72    MPI_Comm_size(serverComm_,&commSize) ;
73
74    for(int rank=0; rank<commSize;rank++)
75    { 
76      notifyOutType_=NOTIFY_FINALIZE ;
77      sendNotification(rank) ;
78    }
79  }
80
81  void CServersRessource::sendNotification(int rank)
82  {
83    winNotify_->pushToExclusiveWindow(rank, this, &CServersRessource::notificationsDumpOut) ;
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    CTimer::get("CServersRessource::eventLoop").resume();
118    double time=MPI_Wtime() ;
119    int flag ;
120    MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, MPI_STATUS_IGNORE);
121
122    if (time-lastEventLoop_ > eventLoopLatency_) 
123    {
124      checkNotifications() ;
125      lastEventLoop_=time ;
126    }
127
128    if (poolRessource_!=nullptr) 
129    {
130      if (poolRessource_->eventLoop(serviceOnly))
131      {
132        delete poolRessource_ ;
133        poolRessource_=nullptr ;
134        // don't forget to free pool ressource later
135      } 
136    }
137    CTimer::get("CServersRessource::eventLoop").suspend();
138    if (poolRessource_==nullptr && finalizeSignal_) return true ;
139    else return false ;
140  }
141
142  void CServersRessource::checkNotifications(void)
143  {
144    int commRank ;
145    MPI_Comm_rank(serverComm_, &commRank) ;
146    winNotify_->popFromExclusiveWindow(commRank, this, &CServersRessource::notificationsDumpIn) ;
147    if (notifyInType_==NOTIFY_CREATE_POOL) createPool() ;
148    else if (notifyInType_==NOTIFY_FINALIZE) finalizeSignal() ;
149  }
150
151  void CServersRessource::createPool(void)
152  {
153    auto& arg=notifyInCreatePool_ ;
154    string poolId=get<0>(arg) ;
155    bool isPartOf=get<1>(arg) ;
156   
157    int commRank ;
158    MPI_Comm poolComm ;
159    MPI_Comm_rank(freeRessourcesComm_,&commRank) ;
160    MPI_Comm_split(freeRessourcesComm_, isPartOf, commRank, &poolComm) ;
161   
162    if (isPartOf)
163    { 
164      poolRessource_ = new CPoolRessource(poolComm, poolId, true) ;
165      MPI_Comm_free(&poolComm) ;
166    }
167    else 
168    {
169      MPI_Comm_free(&freeRessourcesComm_) ;
170      freeRessourcesComm_=poolComm ;
171    }
172
173  }
174 
175  void CServersRessource::finalizeSignal(void)
176  {
177    finalizeSignal_=true ;
178    if (poolRessource_!=nullptr) poolRessource_->finalizeSignal() ;
179  }
180
181  bool CServersRessource::isServerLeader(void)
182  {
183    int commRank ;
184    MPI_Comm_rank(serverComm_,&commRank) ;
185    if (commRank==localLeader_) return true ;
186    else return false ;
187  }
188
189  CServersRessource::~CServersRessource()
190  {
191    delete winNotify_ ;
192  }
193}
Note: See TracBrowser for help on using the repository browser.