source: XIOS/dev/common/src/context_client.cpp @ 1512

Last change on this file since 1512 was 300, checked in by ymipsl, 12 years ago

nouvelle version de developpement de xios

  • nouvelle interface fortran
  • recodage complet de la couche de communication
  • et bien d'autres choses...

YM

  • Property svn:eol-style set to native
File size: 5.3 KB
Line 
1#include "xmlioserver_spl.hpp"
2#include "context_client.hpp"
3#include "context_server.hpp"
4#include "event_client.hpp"
5#include "buffer_out.hpp"
6#include "buffer_client.hpp"
7#include "type.hpp"
8#include "message.hpp"
9#include "event_client.hpp"
10#include "transfert_parameters.hpp"
11#include "context.hpp"
12#include <mpi.h>
13
14namespace xmlioserver
15{
16
17
18    CContextClient::CContextClient(tree::CContext* parent,MPI_Comm intraComm_, MPI_Comm interComm_)
19    {
20      context=parent ;
21      intraComm=intraComm_ ;
22      interComm=interComm_ ;
23      MPI_Comm_rank(intraComm,&clientRank) ;
24      MPI_Comm_size(intraComm,&clientSize) ;
25     
26      int flag ;
27      MPI_Comm_test_inter(interComm,&flag) ;
28      if (flag) MPI_Comm_remote_size(interComm,&serverSize);
29      else  MPI_Comm_size(interComm,&serverSize) ;
30     
31      timeLine=0 ;
32
33    }
34
35
36    void CContextClient::sendEvent(CEventClient& event)
37    {
38      list<int>::iterator itServer ;
39      list<int> ranks ;
40      list<int> sizes ; 
41      list<int>::iterator itSize ;
42     
43      ranks=event.getRanks() ;
44      if (! event.isEmpty())
45      {
46        sizes=event.getSizes() ;
47        CMessage msg ;
48
49        msg<<*(sizes.begin())<<timeLine ;
50        for(list<int>::iterator it=sizes.begin();it!=sizes.end();it++) *it+=msg.size() ;
51        list<CBufferOut*> buffList=getBuffers(ranks,sizes) ;
52     
53        list<CBufferOut*>::iterator it ;     
54        for(it=buffList.begin(),itSize=sizes.begin();it!=buffList.end();++it,++itSize)
55        {
56          **it<<*itSize<<timeLine ;
57        }
58        event.send(buffList) ;
59        checkBuffers(ranks) ;
60      }
61
62      if (context->hasServer) waitEvent(ranks) ;
63      timeLine++ ;
64    }
65     
66    void CContextClient::waitEvent(list<int>& ranks)
67    {
68      context->server->setPendingEvent() ;
69      while(checkBuffers(ranks) || context->server->hasPendingEvent())
70      {
71        context->server->eventLoop() ;
72      }
73    }
74
75    list<CBufferOut*> CContextClient::getBuffers(list<int>& serverList, list<int>& sizeList)
76    {
77      list<int>::iterator itServer,itSize ;
78      list<CClientBuffer*> bufferList ; 
79      map<int,CClientBuffer*>::iterator it ; 
80      list<CClientBuffer*>::iterator itBuffer ; 
81      list<CBufferOut*>  retBuffer ;
82      bool free ;
83
84      for(itServer=serverList.begin();itServer!=serverList.end();itServer++) 
85      {
86        it=buffers.find(*itServer) ;
87        if (it==buffers.end()) 
88        {
89          newBuffer(*itServer) ;
90          it=buffers.find(*itServer) ;
91        }         
92        bufferList.push_back(it->second) ;
93      }
94      free=false ;
95      while(!free)
96      {
97        free=true ;
98        for(itBuffer=bufferList.begin(),itSize=sizeList.begin(); itBuffer!=bufferList.end();itBuffer++,itSize++)
99        {
100          (*itBuffer)->checkBuffer() ;
101         free&=(*itBuffer)->isBufferFree(*itSize) ;
102        }
103      }
104      for(itBuffer=bufferList.begin(),itSize=sizeList.begin(); itBuffer!=bufferList.end();itBuffer++,itSize++)
105      {
106        retBuffer.push_back((*itBuffer)->getBuffer(*itSize)) ;
107      }
108      return retBuffer ;             
109   
110   }
111     
112   void CContextClient::newBuffer(int rank)
113   {
114      buffers[rank]=new CClientBuffer(interComm,rank) ;
115   } 
116
117   bool CContextClient::checkBuffers(void)
118   {
119      map<int,CClientBuffer*>::iterator itBuff ;
120      bool pending=false ;
121      for(itBuff=buffers.begin();itBuff!=buffers.end();itBuff++) pending|=itBuff->second->checkBuffer() ;
122      return pending ;
123   } 
124
125   void CContextClient::releaseBuffers(void)
126   {
127      map<int,CClientBuffer*>::iterator itBuff ;
128      for(itBuff=buffers.begin();itBuff!=buffers.end();itBuff++) delete itBuff->second ;
129   } 
130
131   bool CContextClient::checkBuffers(list<int>& ranks)
132   {
133      list<int>::iterator it ;
134      bool pending=false ;
135      for(it=ranks.begin();it!=ranks.end();it++) pending|=buffers[*it]->checkBuffer() ;
136      return pending ;
137   } 
138
139   int CContextClient::getServerLeader(void)
140   {
141     int clientByServer=clientSize/serverSize ;
142     int remain=clientSize%serverSize ;
143     
144     if (clientRank<(clientByServer+1)*remain)
145     {
146       return clientRank/(clientByServer+1) ;
147     }
148     else
149     {
150       int rank=clientRank-(clientByServer+1)*remain ;
151       int nbServer=serverSize-remain ;
152       return remain+rank/clientByServer ;
153     }
154   }     
155
156   bool CContextClient::isServerLeader(void)
157   {
158     int clientByServer=clientSize/serverSize ;
159     int remain=clientSize%serverSize ;
160     
161     if (clientRank<(clientByServer+1)*remain)
162     {
163       if (clientRank%(clientByServer+1)==0) return true ;
164       else return false ;
165     }
166     else
167     {
168       int rank=clientRank-(clientByServer+1)*remain ;
169       int nbServer=serverSize-remain ;
170       if  (rank%clientByServer==0) return true ;
171       else return false ;
172     } 
173   }
174     
175   void CContextClient::finalize(void)
176   {
177     
178     map<int,CClientBuffer*>::iterator itBuff ;
179     bool stop=true ;
180
181     CEventClient event(CContext::GetType(),CContext::EVENT_ID_CONTEXT_FINALIZE) ;   
182     if (isServerLeader())
183     {
184       CMessage msg ;
185       event.push(getServerLeader(),1,msg) ;
186     }
187     sendEvent(event) ;
188       
189     while(stop)
190     {
191       checkBuffers() ;
192       stop=false ;
193       for(itBuff=buffers.begin();itBuff!=buffers.end();itBuff++) stop|=itBuff->second->hasPendingRequest() ;
194     }
195         
196     releaseBuffers() ;
197   }
198}     
Note: See TracBrowser for help on using the repository browser.