source: XIOS3/trunk/src/manager/coupler_manager.cpp @ 2517

Last change on this file since 2517 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: 4.1 KB
Line 
1#include "coupler_manager.hpp"
2#include "cxios.hpp"
3#include <functional>
4#include <string>
5
6
7
8namespace xios
9{
10  CCouplerManager::CCouplerManager(bool isXiosServer)
11  {
12    auto xiosComm_ = CXios::getXiosComm()  ;
13   
14    int commRank ; 
15    MPI_Comm_rank(xiosComm_, &commRank) ;
16    if (commRank==0 && isXiosServer) MPI_Comm_rank(xiosComm_, &commRank) ; 
17    else commRank=0 ;
18    MPI_Allreduce(&commRank, &managerGlobalLeader_, 1, MPI_INT, MPI_SUM, xiosComm_) ;
19    MPI_Comm_rank(xiosComm_, &commRank) ;
20   
21    winRegistredCoupling_ = new CWindowManager(xiosComm_, maxBufferSize_) ;
22    winNextCoupling_ = new CWindowManager(xiosComm_, maxBufferSize_) ;
23    if (commRank==managerGlobalLeader_)
24    {
25      winRegistredCoupling_->updateToExclusiveWindow(managerGlobalLeader_, this, &CCouplerManager::registredCouplingDumpOut) ;
26      winNextCoupling_->updateToExclusiveWindow(managerGlobalLeader_, this, &CCouplerManager::nextCouplingDumpOut) ;
27    }
28
29    MPI_Barrier(xiosComm_)  ;   
30  }
31
32  CCouplerManager::~CCouplerManager()
33  {
34    delete winRegistredCoupling_ ;
35    delete winNextCoupling_ ;
36  }
37 
38 
39  void CCouplerManager::registerCoupling(string srcCoupling, string dstCoupling)
40  {
41    hash<string> strHash ;
42    size_t key = strHash(getStrCoupling(srcCoupling,dstCoupling)) ;
43   
44    winRegistredCoupling_->lockWindowExclusive(managerGlobalLeader_) ;
45    winRegistredCoupling_->updateFromLockedWindow(managerGlobalLeader_, this, &CCouplerManager::registredCouplingDumpIn) ;
46    if (registredCoupling_.count(key)==1)
47    {
48      registredCoupling_.erase(key) ;
49      winRegistredCoupling_->updateToLockedWindow(managerGlobalLeader_, this, &CCouplerManager::registredCouplingDumpOut) ;
50      winNextCoupling_->lockWindowExclusive(managerGlobalLeader_) ;
51      winNextCoupling_->updateFromLockedWindow(managerGlobalLeader_, this, &CCouplerManager::nextCouplingDumpIn) ;
52      nextCoupling_.push_back(pair<size_t,int>(key,2)) ;
53      winNextCoupling_->updateToLockedWindow(managerGlobalLeader_, this, &CCouplerManager::nextCouplingDumpOut) ;
54      winNextCoupling_->unlockWindowExclusive(managerGlobalLeader_) ;
55    }
56    else 
57    {
58      registredCoupling_.insert(key) ;
59      winRegistredCoupling_->updateToLockedWindow(managerGlobalLeader_, this, &CCouplerManager::registredCouplingDumpOut) ;
60    }
61    winRegistredCoupling_->unlockWindowExclusive(managerGlobalLeader_) ;
62  }
63
64  bool CCouplerManager::isNextCoupling(string srcCoupling, string dstCoupling)
65  {
66    bool ret ;
67    hash<string> strHash ;
68    size_t key = strHash(getStrCoupling(srcCoupling,dstCoupling)) ;
69
70    winNextCoupling_->lockWindowExclusive(managerGlobalLeader_) ;
71    winNextCoupling_->updateFromLockedWindow(managerGlobalLeader_, this, &CCouplerManager::nextCouplingDumpIn) ;
72    if (nextCoupling_.front().first==key)
73    {
74      ret=true ;
75      if (nextCoupling_.front().second==1) nextCoupling_.pop_front() ;
76      else nextCoupling_.front().second=1 ;
77      winNextCoupling_->updateToLockedWindow(managerGlobalLeader_, this, &CCouplerManager::nextCouplingDumpOut) ;
78    }
79    else ret=false ;
80    winNextCoupling_->unlockWindowExclusive(managerGlobalLeader_) ;
81    return ret ;
82  }
83  void CCouplerManager::registredCouplingDumpOut(CBufferOut& buffer)
84  {
85    buffer.realloc(maxBufferSize_) ;
86    buffer<<(int)registredCoupling_.size();
87   
88    for(auto hash : registredCoupling_) buffer << hash ;
89  } 
90
91  void CCouplerManager::registredCouplingDumpIn(CBufferIn& buffer)
92  {
93    registredCoupling_.clear() ;
94    size_t hash ;
95    int nbHash ;
96    buffer>>nbHash ;
97    for(int i=0;i<nbHash;i++) 
98    {
99      buffer>>hash ;
100      registredCoupling_.insert(hash) ;
101    }
102  }
103
104  void CCouplerManager::nextCouplingDumpOut(CBufferOut& buffer)
105  {
106    buffer.realloc(maxBufferSize_) ;
107    buffer<<(int)nextCoupling_.size();
108   
109    for(auto hash : nextCoupling_) buffer << hash.first<<hash.second ;
110  } 
111
112  void CCouplerManager::nextCouplingDumpIn(CBufferIn& buffer)
113  {
114    nextCoupling_.clear() ;
115    size_t hash ;
116    int count ;
117    int nbHash ;
118    buffer>>nbHash ;
119    for(int i=0;i<nbHash;i++) 
120    {
121      buffer>>hash>>count ;
122      nextCoupling_.push_back(pair<size_t,int>(hash,count)) ;
123    }
124  }
125
126}
Note: See TracBrowser for help on using the repository browser.