source: XIOS/dev/common/src/client_ym.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: 6.8 KB
Line 
1#include "xmlioserver_spl.hpp"
2#include "cxios.hpp"
3#include "client_ym.hpp"
4#include <boost/functional/hash.hpp>
5#include "type.hpp"
6#include "buffer.hpp"
7#include "context.hpp"
8#include "context_client.hpp"
9#include "tree_manager.hpp"
10#include "oasis_cinterface.hpp"
11#include <mpi.h>
12
13namespace xmlioserver
14{                     
15  namespace ym
16  {
17
18    MPI_Comm CClient::intraComm ;
19    MPI_Comm CClient::interComm ;
20    int CClient::serverLeader ;
21    bool CClient::is_MPI_Initialized ;
22   
23   
24    void CClient::initialize(const string& codeId,MPI_Comm& localComm,MPI_Comm& returnComm)
25    {
26      int initialized ;
27      MPI_Initialized(&initialized) ;
28      if (initialized) is_MPI_Initialized=true ;
29      else is_MPI_Initialized=false ;
30     
31// don't use OASIS
32      if (!CXios::usingOasis)
33      {
34// localComm doesn't given
35        if (localComm == MPI_COMM_NULL)
36        {
37          if (!is_MPI_Initialized) 
38          {
39            int argc=0;
40            char** argv=NULL;
41            MPI_Init(&argc,&argv) ;
42          }
43          boost::hash<string> hashString ;   
44   
45          unsigned long hashClient=hashString(codeId) ;
46          unsigned long hashServer=hashString(CXios::xiosCodeId) ;
47          unsigned long* hashAll ;
48          int rank ;
49          int size ;
50          int myColor ;
51          int i,c ;
52          MPI_Comm newComm ;
53     
54          MPI_Comm_size(CXios::globalComm,&size) ;
55          MPI_Comm_rank(CXios::globalComm,&rank);
56          hashAll=new unsigned long[size] ;
57     
58          MPI_Allgather(&hashClient,1,MPI_LONG,hashAll,1,MPI_LONG,CXios::globalComm) ;
59
60          map<unsigned long, int> colors ;
61          map<unsigned long, int> leaders ;
62     
63          for(i=0,c=0;i<size;i++)
64          {
65            if (colors.find(hashAll[i])==colors.end())
66            {
67              colors[hashAll[i]] =c ;
68              leaders[hashAll[i]]=i ;
69              c++ ;
70            }
71          }
72     
73          myColor=colors[hashClient] ;
74     
75          MPI_Comm_split(CXios::globalComm,myColor,rank,&intraComm) ;
76
77          if (CXios::usingServer)
78          {     
79            int clientLeader=leaders[hashClient] ;
80            serverLeader=leaders[hashServer] ;
81            MPI_Intercomm_create(intraComm,0,CXios::globalComm,serverLeader,0,&interComm) ;
82          }
83          else
84          {
85            MPI_Comm_dup(intraComm,&interComm) ;
86          }
87          delete [] hashAll ;
88        }
89        // localComm argument is given
90        else 
91        {
92          if (CXios::usingServer)
93          {         
94            //ERROR("void CClient::initialize(const string& codeId,MPI_Comm& localComm,MPI_Comm& returnComm)", << " giving a local communictor is not compatible with using server mode") ;
95          }
96          else
97          {
98            MPI_Comm_dup(localComm,&intraComm) ;
99            MPI_Comm_dup(intraComm,&interComm) ;
100          }
101        }
102      }
103      // using OASIS
104      else
105      {
106        // localComm doesn't given
107        if (localComm == MPI_COMM_NULL)
108        {
109          if (!is_MPI_Initialized) oasis_init(codeId) ;
110          oasis_get_localcomm(intraComm) ;
111        }
112        else MPI_Comm_dup(localComm,&intraComm) ;
113 
114        if (CXios::usingServer) 
115        {
116          MPI_Status status ;
117          int rank ;
118          MPI_Comm_rank(intraComm,&rank) ;
119
120          oasis_get_intercomm(interComm,CXios::xiosCodeId) ;
121          if (rank==0) MPI_Recv(&serverLeader,1, MPI_INT, 0, 0, interComm, &status) ;
122          MPI_Bcast(&serverLeader,1,MPI_INT,0,intraComm) ;
123           
124        }
125        else MPI_Comm_dup(intraComm,&interComm) ;
126      }
127         
128      MPI_Comm_dup(intraComm,&returnComm) ;
129    }
130   
131   
132   
133   
134/*   
135    void CClient::initialize(const string& codeId,MPI_Comm& localComm,MPI_Comm& returnComm)
136    {
137      boost::hash<string> hashString ;   
138   
139      unsigned long hashClient=hashString(codeId) ;
140      unsigned long hashServer=hashString(CXios::xiosCodeId) ;
141      unsigned long* hashAll ;
142      int rank ;
143      int size ;
144      int myColor ;
145      int i,c ;
146      MPI_Comm newComm ;
147     
148      MPI_Comm_size(CXios::globalComm,&size) ;
149      MPI_Comm_rank(CXios::globalComm,&rank);
150      hashAll=new unsigned long[size] ;
151     
152      MPI_Allgather(&hashClient,1,MPI_LONG,hashAll,1,MPI_LONG,CXios::globalComm) ;
153
154      map<unsigned long, int> colors ;
155      map<unsigned long, int> leaders ;
156     
157      for(i=0,c=0;i<size;i++)
158      {
159        if (colors.find(hashAll[i])==colors.end())
160        {
161          colors[hashAll[i]] =c ;
162          leaders[hashAll[i]]=i ;
163          c++ ;
164        }
165       
166      }
167     
168      myColor=colors[hashClient] ;
169     
170      MPI_Comm_split(CXios::globalComm,myColor,rank,&intraComm) ;
171
172      if (!CXios::isServer)
173      {     
174        int clientLeader=leaders[hashClient] ;
175        serverLeader=leaders[hashServer] ;
176        MPI_Intercomm_create(intraComm,0,CXios::globalComm,serverLeader,0,&interComm) ;
177      }
178      else
179      {
180        MPI_Comm_dup(intraComm,&interComm) ;
181      }
182
183      delete [] hashAll ;
184    }
185  */
186   
187    void CClient::registerContext(const string& id,MPI_Comm contextComm)
188    {
189      CObjectFactory::SetCurrentContextId(id);
190      shared_ptr<CContext> context=tree::CTreeManager::CreateContext(id) ;
191       
192      if (!CXios::isServer)
193      {
194        int size,rank,globalRank ;
195        size_t message_size ;
196        int leaderRank ;
197        MPI_Comm contextInterComm ;
198     
199        MPI_Comm_size(contextComm,&size) ;
200        MPI_Comm_rank(contextComm,&rank) ;
201        MPI_Comm_rank(CXios::globalComm,&globalRank) ;
202        if (rank!=0) globalRank=0 ;
203     
204   
205        CMessage msg ;
206        msg<<id<<size<<globalRank ;
207
208        int messageSize=msg.size() ;
209        void * buff = new char[messageSize] ;
210        CBufferOut buffer(buff,messageSize) ;
211        buffer<<msg ;
212     
213        MPI_Send(buff,buffer.count(),MPI_CHAR,serverLeader,1,CXios::globalComm) ;
214        delete [] buff ;
215     
216        MPI_Intercomm_create(contextComm,0,CXios::globalComm,serverLeader,10+globalRank,&contextInterComm) ;
217        info(10)<<"Register new Context : "<<id<<endl ;
218 
219        MPI_Comm inter ;
220        MPI_Intercomm_merge(contextInterComm,0,&inter) ;
221        MPI_Barrier(inter) ;
222
223        context->initClient(contextComm,contextInterComm) ;
224      }
225      else
226      {
227        MPI_Comm contextInterComm ;
228        MPI_Comm_dup(contextComm,&contextInterComm) ;
229        context->initClient(contextComm,contextInterComm) ;
230        context->initServer(contextComm,contextInterComm) ;
231      }
232    }
233   
234    void CClient::finalize(void)
235    {
236      int rank ;
237      int msg=0 ;
238      MPI_Comm_rank(intraComm,&rank) ; 
239      if (rank==0) 
240      {
241        MPI_Send(&msg,1,MPI_INT,0,0,interComm) ;
242      }
243     
244      if (!is_MPI_Initialized)
245      {
246        if (CXios::usingOasis) oasis_finalize();
247        else MPI_Finalize() ;
248      }
249      info(20) << "Client side context is finalized"<<endl ;
250    }
251  }
252}
Note: See TracBrowser for help on using the repository browser.