source: XIOS/trunk/src/client.cpp @ 347

Last change on this file since 347 was 347, checked in by ymipsl, 12 years ago
  • Supress lot of shared_ptr
  • instrument code for vampir-trace and timer diagnostic

YM

  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1#include "xmlioserver_spl.hpp"
2#include "cxios.hpp"
3#include "client.hpp"
4#include <boost/functional/hash.hpp>
5#include "type.hpp"
6#include "context.hpp"
7#include "context_client.hpp"
8#include "oasis_cinterface.hpp"
9#include <mpi.h>
10#include "timer.hpp"
11
12namespace xios
13{                     
14
15    MPI_Comm CClient::intraComm ;
16    MPI_Comm CClient::interComm ;
17    int CClient::serverLeader ;
18    bool CClient::is_MPI_Initialized ;
19   
20   
21    void CClient::initialize(const string& codeId,MPI_Comm& localComm,MPI_Comm& returnComm)
22    {
23      int initialized ;
24      MPI_Initialized(&initialized) ;
25      if (initialized) is_MPI_Initialized=true ;
26      else is_MPI_Initialized=false ;
27     
28// don't use OASIS
29      if (!CXios::usingOasis)
30      {
31// localComm doesn't given
32        if (localComm == MPI_COMM_NULL)
33        {
34          if (!is_MPI_Initialized) 
35          {
36            int argc=0;
37            char** argv=NULL;
38            MPI_Init(&argc,&argv) ;
39          }
40          boost::hash<string> hashString ;   
41   
42          unsigned long hashClient=hashString(codeId) ;
43          unsigned long hashServer=hashString(CXios::xiosCodeId) ;
44          unsigned long* hashAll ;
45          int rank ;
46          int size ;
47          int myColor ;
48          int i,c ;
49          MPI_Comm newComm ;
50     
51          MPI_Comm_size(CXios::globalComm,&size) ;
52          MPI_Comm_rank(CXios::globalComm,&rank);
53          hashAll=new unsigned long[size] ;
54     
55          MPI_Allgather(&hashClient,1,MPI_LONG,hashAll,1,MPI_LONG,CXios::globalComm) ;
56
57          map<unsigned long, int> colors ;
58          map<unsigned long, int> leaders ;
59     
60          for(i=0,c=0;i<size;i++)
61          {
62            if (colors.find(hashAll[i])==colors.end())
63            {
64              colors[hashAll[i]] =c ;
65              leaders[hashAll[i]]=i ;
66              c++ ;
67            }
68          }
69     
70          myColor=colors[hashClient] ;
71     
72          MPI_Comm_split(CXios::globalComm,myColor,rank,&intraComm) ;
73
74          if (CXios::usingServer)
75          {     
76            int clientLeader=leaders[hashClient] ;
77            serverLeader=leaders[hashServer] ;
78            MPI_Intercomm_create(intraComm,0,CXios::globalComm,serverLeader,0,&interComm) ;
79          }
80          else
81          {
82            MPI_Comm_dup(intraComm,&interComm) ;
83          }
84          delete [] hashAll ;
85        }
86        // localComm argument is given
87        else 
88        {
89          if (CXios::usingServer)
90          {         
91            //ERROR("void CClient::initialize(const string& codeId,MPI_Comm& localComm,MPI_Comm& returnComm)", << " giving a local communictor is not compatible with using server mode") ;
92          }
93          else
94          {
95            MPI_Comm_dup(localComm,&intraComm) ;
96            MPI_Comm_dup(intraComm,&interComm) ;
97          }
98        }
99      }
100      // using OASIS
101      else
102      {
103        // localComm doesn't given
104        if (localComm == MPI_COMM_NULL)
105        {
106          if (!is_MPI_Initialized) oasis_init(codeId) ;
107          oasis_get_localcomm(intraComm) ;
108        }
109        else MPI_Comm_dup(localComm,&intraComm) ;
110 
111        if (CXios::usingServer) 
112        {
113          MPI_Status status ;
114          int rank ;
115          MPI_Comm_rank(intraComm,&rank) ;
116
117          oasis_get_intercomm(interComm,CXios::xiosCodeId) ;
118          if (rank==0) MPI_Recv(&serverLeader,1, MPI_INT, 0, 0, interComm, &status) ;
119          MPI_Bcast(&serverLeader,1,MPI_INT,0,intraComm) ;
120           
121        }
122        else MPI_Comm_dup(intraComm,&interComm) ;
123      }
124         
125      MPI_Comm_dup(intraComm,&returnComm) ;
126    }
127   
128   
129    void CClient::registerContext(const string& id,MPI_Comm contextComm)
130    {
131      CContext::setCurrent(id) ;
132      CContext* context=CContext::create(id) ;
133       
134      if (!CXios::isServer)
135      {
136        int size,rank,globalRank ;
137        size_t message_size ;
138        int leaderRank ;
139        MPI_Comm contextInterComm ;
140     
141        MPI_Comm_size(contextComm,&size) ;
142        MPI_Comm_rank(contextComm,&rank) ;
143        MPI_Comm_rank(CXios::globalComm,&globalRank) ;
144        if (rank!=0) globalRank=0 ;
145     
146   
147        CMessage msg ;
148        msg<<id<<size<<globalRank ;
149
150        int messageSize=msg.size() ;
151        void * buff = new char[messageSize] ;
152        CBufferOut buffer(buff,messageSize) ;
153        buffer<<msg ;
154     
155        MPI_Send(buff,buffer.count(),MPI_CHAR,serverLeader,1,CXios::globalComm) ;
156        delete [] buff ;
157     
158        MPI_Intercomm_create(contextComm,0,CXios::globalComm,serverLeader,10+globalRank,&contextInterComm) ;
159        info(10)<<"Register new Context : "<<id<<endl ;
160 
161        MPI_Comm inter ;
162        MPI_Intercomm_merge(contextInterComm,0,&inter) ;
163        MPI_Barrier(inter) ;
164
165        context->initClient(contextComm,contextInterComm) ;
166      }
167      else
168      {
169        MPI_Comm contextInterComm ;
170        MPI_Comm_dup(contextComm,&contextInterComm) ;
171        context->initClient(contextComm,contextInterComm) ;
172        context->initServer(contextComm,contextInterComm) ;
173      }
174    }
175   
176    void CClient::finalize(void)
177    {
178      int rank ;
179      int msg=0 ;
180      if (!CXios::isServer)
181      {
182        MPI_Comm_rank(intraComm,&rank) ; 
183        if (rank==0) 
184        {
185          MPI_Send(&msg,1,MPI_INT,0,0,interComm) ;
186        }
187      }
188     
189      if (!is_MPI_Initialized)
190      {
191        if (CXios::usingOasis) oasis_finalize();
192        else MPI_Finalize() ;
193      }
194      info(20) << "Client side context is finalized"<<endl ;
195      report(0) <<" Performance report : total time spent for XIOS : "<< CTimer::get("XIOS").getCumulatedTime()<<" s"<<endl ; 
196      report(0)<< " Performance report : time spent for waiting free buffer : "<< CTimer::get("Blocking time").getCumulatedTime()<<" s"<<endl ;
197      report(0)<< " Performance report : Ratio : "<< CTimer::get("Blocking time").getCumulatedTime()/CTimer::get("XIOS").getCumulatedTime()*100.<<" %"<<endl ;
198      report(0)<< " Performance report : This ratio must be close to zero. Otherwise it may be usefull to increase buffer size or numbers of server"<<endl ;
199    }
200}
Note: See TracBrowser for help on using the repository browser.