source: XIOS/dev/dev_ym/XIOS_COUPLING/src/manager/coupler_manager.cpp @ 1878

Last change on this file since 1878 was 1878, checked in by ymipsl, 4 years ago

Coupling Branch.
Implementing a coupler scheduler, to impose order for intercommunicator creation between several coupling context.
Two way coupling is now working.

YM

  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 4.3 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_->lockWindow(managerGlobalLeader_,0) ;
26      winRegistredCoupling_->updateToWindow(managerGlobalLeader_, this, &CCouplerManager::registredCouplingDumpOut) ;
27      winRegistredCoupling_->unlockWindow(managerGlobalLeader_,0) ;
28
29      winNextCoupling_->lockWindow(managerGlobalLeader_,0) ;
30      winNextCoupling_->updateToWindow(managerGlobalLeader_, this, &CCouplerManager::nextCouplingDumpOut) ;
31      winNextCoupling_->unlockWindow(managerGlobalLeader_,0) ;
32    }
33
34    MPI_Barrier(xiosComm_)  ;   
35  }
36
37  CCouplerManager::~CCouplerManager()
38  {
39    delete winRegistredCoupling_ ;
40    delete winNextCoupling_ ;
41  }
42 
43 
44  void CCouplerManager::registerCoupling(string srcCoupling, string dstCoupling)
45  {
46    hash<string> strHash ;
47    size_t key = strHash(getStrCoupling(srcCoupling,dstCoupling)) ;
48   
49    winRegistredCoupling_->lockWindow(managerGlobalLeader_,0) ;
50    winRegistredCoupling_->updateFromWindow(managerGlobalLeader_, this, &CCouplerManager::registredCouplingDumpIn) ;
51    if (registredCoupling_.count(key)==1)
52    {
53      registredCoupling_.erase(key) ;
54      winRegistredCoupling_->updateToWindow(managerGlobalLeader_, this, &CCouplerManager::registredCouplingDumpOut) ;
55      winNextCoupling_->lockWindow(managerGlobalLeader_,0) ;
56      winNextCoupling_->updateFromWindow(managerGlobalLeader_, this, &CCouplerManager::nextCouplingDumpIn) ;
57      nextCoupling_.push_back(pair<size_t,int>(key,2)) ;
58      winNextCoupling_->updateToWindow(managerGlobalLeader_, this, &CCouplerManager::nextCouplingDumpOut) ;
59      winNextCoupling_->unlockWindow(managerGlobalLeader_,0) ;
60    }
61    else 
62    {
63      registredCoupling_.insert(key) ;
64      winRegistredCoupling_->updateToWindow(managerGlobalLeader_, this, &CCouplerManager::registredCouplingDumpOut) ;
65    }
66    winRegistredCoupling_->unlockWindow(managerGlobalLeader_,0) ;
67  }
68
69  bool CCouplerManager::isNextCoupling(string srcCoupling, string dstCoupling)
70  {
71    bool ret ;
72    hash<string> strHash ;
73    size_t key = strHash(getStrCoupling(srcCoupling,dstCoupling)) ;
74
75    winNextCoupling_->lockWindow(managerGlobalLeader_,0) ;
76    winNextCoupling_->updateFromWindow(managerGlobalLeader_, this, &CCouplerManager::nextCouplingDumpIn) ;
77    if (nextCoupling_.front().first==key)
78    {
79      ret=true ;
80      if (nextCoupling_.front().second==1) nextCoupling_.pop_front() ;
81      else nextCoupling_.front().second=1 ;
82      winNextCoupling_->updateToWindow(managerGlobalLeader_, this, &CCouplerManager::nextCouplingDumpOut) ;
83    }
84    else ret=false ;
85    winNextCoupling_->unlockWindow(managerGlobalLeader_,0) ;
86    return ret ;
87  }
88  void CCouplerManager::registredCouplingDumpOut(CBufferOut& buffer)
89  {
90    buffer.realloc(maxBufferSize_) ;
91    buffer<<(int)registredCoupling_.size();
92   
93    for(auto hash : registredCoupling_) buffer << hash ;
94  } 
95
96  void CCouplerManager::registredCouplingDumpIn(CBufferIn& buffer)
97  {
98    registredCoupling_.clear() ;
99    size_t hash ;
100    int nbHash ;
101    buffer>>nbHash ;
102    for(int i=0;i<nbHash;i++) 
103    {
104      buffer>>hash ;
105      registredCoupling_.insert(hash) ;
106    }
107  }
108
109  void CCouplerManager::nextCouplingDumpOut(CBufferOut& buffer)
110  {
111    buffer.realloc(maxBufferSize_) ;
112    buffer<<(int)nextCoupling_.size();
113   
114    for(auto hash : nextCoupling_) buffer << hash.first<<hash.second ;
115  } 
116
117  void CCouplerManager::nextCouplingDumpIn(CBufferIn& buffer)
118  {
119    nextCoupling_.clear() ;
120    size_t hash ;
121    int count ;
122    int nbHash ;
123    buffer>>nbHash ;
124    for(int i=0;i<nbHash;i++) 
125    {
126      buffer>>hash>>count ;
127      nextCoupling_.push_back(pair<size_t,int>(hash,count)) ;
128    }
129  }
130
131}
Note: See TracBrowser for help on using the repository browser.