source: XIOS/dev/branch_openmp/src/cxios.cpp @ 1642

Last change on this file since 1642 was 1642, checked in by yushan, 5 years ago

dev on ADA. add flag switch _usingEP/_usingMPI

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
  • Property svn:eol-style set to native
File size: 9.8 KB
Line 
1
2#include "xios_spl.hpp"
3#include "cxios.hpp"
4#include "client.hpp"
5#include "server.hpp"
6#include "xml_parser.hpp"
7#include <boost/functional/hash.hpp>
8#include "mpi.hpp"
9#include "memory.hpp"
10#include <new>
11#include "memtrack.hpp"
12#include "registry.hpp"
13
14namespace xios
15{
16  string CXios::rootFile="./iodef.xml" ;
17  string CXios::xiosCodeId="xios.x" ;
18  string CXios::clientFile="./xios_client";
19  string CXios::serverFile="./xios_server";
20  string CXios::serverPrmFile="./xios_server1";
21  string CXios::serverSndFile="./xios_server2";
22
23  bool CXios::xiosStack = true;
24  bool CXios::systemStack = false;
25
26  bool CXios::isClient ;
27  bool CXios::isServer ;
28  ep_lib::MPI_Comm CXios::globalComm ;
29  bool CXios::usingOasis ;
30  bool CXios::usingServer = false;
31  bool CXios::usingServer2 = false;
32  int CXios::ratioServer2 = 50;
33  int CXios::nbPoolsServer2 = 1;
34  double CXios::bufferSizeFactor = 1.0;
35  const double CXios::defaultBufferSizeFactor = 1.0;
36  StdSize CXios::minBufferSize = 1024 * sizeof(double);
37  StdSize CXios::maxBufferSize = std::numeric_limits<int>::max() ;
38  bool CXios::printLogs2Files;
39  bool CXios::isOptPerformance = true;
40  CRegistry* CXios::globalRegistry = 0;
41  double CXios::recvFieldTimeout = 300.0;
42  bool CXios::checkEventSync=false ;
43 
44  //! Parse configuration file and create some objects from it
45  void CXios::initialize()
46  {
47    set_new_handler(noMemory);
48    parseFile(rootFile);
49    parseXiosConfig();
50  }
51
52  /*!
53  \brief Parse xios part of configuration file (.iodef.xml)
54   Both client and server need information returned from this function
55  */
56  void CXios::parseXiosConfig()
57  {
58    usingOasis=getin<bool>("using_oasis",false) ;
59    usingServer=getin<bool>("using_server",false) ;
60    usingServer2=getin<bool>("using_server2",false) ;
61    ratioServer2=getin<int>("ratio_server2",50);
62    nbPoolsServer2=getin<int>("number_pools_server2",0);
63    info.setLevel(getin<int>("info_level",0)) ;
64    report.setLevel(getin<int>("info_level",50));
65    printLogs2Files=getin<bool>("print_file",false);
66
67    xiosStack=getin<bool>("xios_stack",true) ;
68    systemStack=getin<bool>("system_stack",false) ;
69    if (xiosStack && systemStack)
70    {
71      xiosStack = false;
72    }
73
74    StdString bufMemory("memory");
75    StdString bufPerformance("performance");
76    StdString bufOpt = getin<StdString>("optimal_buffer_size", bufPerformance);
77    std::transform(bufOpt.begin(), bufOpt.end(), bufOpt.begin(), ::tolower);
78    if (0 == bufOpt.compare(bufMemory)) isOptPerformance = false;
79    else if (0 != bufOpt.compare(bufPerformance))
80    {
81      ERROR("CXios::parseXiosConfig()", << "optimal_buffer_size must be memory or performance "<< endl );
82    }
83
84    bufferSizeFactor = getin<double>("buffer_size_factor", defaultBufferSizeFactor);
85    minBufferSize = getin<int>("min_buffer_size", 1024 * sizeof(double));
86    maxBufferSize = getin<int>("max_buffer_size", std::numeric_limits<int>::max());
87    recvFieldTimeout = getin<double>("recv_field_timeout", recvFieldTimeout);
88    if (recvFieldTimeout < 0.0)
89      ERROR("CXios::parseXiosConfig()", "recv_field_timeout cannot be negative.");
90
91    checkEventSync = getin<bool>("check_event_sync", checkEventSync);
92    #ifdef _usingMPI
93    globalComm=MPI_COMM_WORLD ;
94    #elif _usingEP
95    ep_lib::MPI_Comm *ep_comm;
96    ep_lib::MPI_Info info;
97    ep_lib::MPI_Comm_create_endpoints(EP_COMM_WORLD->mpi_comm, 1, info, ep_comm);
98    ep_lib::passage = ep_comm;
99    globalComm=ep_lib::passage[0] ;
100    #endif
101  }
102
103  /*!
104  Initialize client
105  \param [in] codeId identity of context
106  \param [in] localComm local communicator
107  \param [in/out] returnComm communicator corresponding to group of client with same codeId
108  */
109  void CXios::initClientSide(const string& codeId, ep_lib::MPI_Comm& localComm, ep_lib::MPI_Comm& returnComm)
110  TRY
111  {
112    isClient = true;
113    isServer = false;
114
115    initialize() ;
116
117
118    CClient::initialize(codeId,localComm,returnComm) ;
119    if (CClient::getRank()==0) globalRegistry = new CRegistry(returnComm) ;
120
121
122    // If there are no server processes then we are in attached mode
123    // and the clients are also servers
124    isServer = !usingServer;
125
126    if (printLogs2Files)
127    {
128      CClient::openInfoStream(clientFile);
129      CClient::openErrorStream(clientFile);
130    }
131    else
132    {
133      CClient::openInfoStream();
134      CClient::openErrorStream();
135    }
136  }
137  CATCH
138
139  void CXios::clientFinalize(void)
140  {
141     CClient::finalize() ;
142     if (CClient::getRank()==0)
143     {
144       info(80)<<"Write data base Registry"<<endl<<globalRegistry->toString()<<endl ;
145       globalRegistry->toFile("xios_registry.bin") ;
146       delete globalRegistry ;
147     }
148
149#ifdef XIOS_MEMTRACK
150
151#ifdef XIOS_MEMTRACK_LIGHT
152       report(10) << " Memory report : current memory used by XIOS : "<<  MemTrack::getCurrentMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
153       report(10) << " Memory report : maximum memory used by XIOS : "<<  MemTrack::getMaxMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
154#endif
155
156#ifdef XIOS_MEMTRACK_FULL
157     MemTrack::TrackListMemoryUsage() ;
158     MemTrack::TrackDumpBlocks();
159#endif
160
161     CClient::closeInfoStream();
162
163#endif
164  }
165
166  //! Init server by parsing only xios part of config file
167  void CXios::initServer()
168  {
169    set_new_handler(noMemory);
170    std::set<StdString> parseList;
171    parseList.insert("xios");
172    xml::CXMLParser::ParseFile(rootFile, parseList);
173    parseXiosConfig();
174  }
175
176  //! Initialize server then put it into listening state
177  void CXios::initServerSide(void)
178  {
179    isClient = false;
180    isServer = true;
181
182    initServer();
183    isClient = false;
184    isServer = true;
185    // Initialize all aspects MPI
186    CServer::initialize();
187    if (CServer::getRank()==0 && CServer::serverLevel != 1) globalRegistry = new CRegistry(CServer::intraComm) ;
188   
189    if (printLogs2Files)
190    {
191      if (CServer::serverLevel == 0)
192      {
193        CServer::openInfoStream(serverFile);
194        CServer::openErrorStream(serverFile);
195      }
196      else if (CServer::serverLevel == 1)
197      {
198        CServer::openInfoStream(serverPrmFile);
199        CServer::openErrorStream(serverPrmFile);
200      }
201      else
202      {
203        CServer::openInfoStream(serverSndFile);
204        CServer::openErrorStream(serverSndFile);
205      }
206    }
207    else
208    {
209      CServer::openInfoStream();
210      CServer::openErrorStream();
211    }
212
213    // Enter the loop to listen message from Client
214    CServer::eventLoop();
215
216    // Finalize
217    if (CServer::serverLevel == 0)
218    {
219      if (CServer::getRank()==0)
220      {
221        info(80)<<"Write data base Registry"<<endl<<globalRegistry->toString()<<endl ;
222        globalRegistry->toFile("xios_registry.bin") ;
223        delete globalRegistry ;
224      }
225    }
226    else
227    {
228      // If using two server levels:
229      // (1) merge registries on each pool
230      // (2) send merged registries to the first pool
231      // (3) merge received registries on the first pool
232      if (CServer::serverLevel == 2)
233      {
234        vector<int>& secondaryServerGlobalRanks = CServer::getSecondaryServerGlobalRanks();
235        int firstPoolGlobalRank = secondaryServerGlobalRanks[0];
236        int rankGlobal;
237        ep_lib::MPI_Comm_rank(globalComm, &rankGlobal);
238
239        // Merge registries defined on each pools
240        CRegistry globalRegistrySndServers (CServer::intraComm);
241
242        // All pools (except the first): send globalRegistry to the first pool
243        for (int i=1; i<secondaryServerGlobalRanks.size(); i++)
244        {
245          if (rankGlobal == secondaryServerGlobalRanks[i])
246          {
247            globalRegistrySndServers.mergeRegistry(*globalRegistry) ;
248            int registrySize = globalRegistrySndServers.size();
249            ep_lib::MPI_Send(&registrySize,1,EP_LONG,firstPoolGlobalRank,15,CXios::globalComm) ;
250            CBufferOut buffer(registrySize) ;
251            globalRegistrySndServers.toBuffer(buffer) ;
252            ep_lib::MPI_Send(buffer.start(),registrySize,EP_CHAR,firstPoolGlobalRank,15,CXios::globalComm) ;
253          }
254        }
255
256        // First pool: receive globalRegistry of all secondary server pools, merge and write the resultant registry
257        if (rankGlobal == firstPoolGlobalRank)
258        {
259          ep_lib::MPI_Status status;
260          char* recvBuff;
261
262          globalRegistrySndServers.mergeRegistry(*globalRegistry) ;
263
264          for (int i=1; i< secondaryServerGlobalRanks.size(); i++)
265          {
266            int rank = secondaryServerGlobalRanks[i];
267            int registrySize = 0;
268            ep_lib::MPI_Recv(&registrySize, 1, EP_LONG, rank, 15, CXios::globalComm, &status);
269            recvBuff = new char[registrySize];
270            ep_lib::MPI_Recv(recvBuff, registrySize, EP_CHAR, rank, 15, CXios::globalComm, &status);
271            CBufferIn buffer(recvBuff, registrySize) ;
272            CRegistry recvRegistry;
273            recvRegistry.fromBuffer(buffer) ;
274            globalRegistrySndServers.mergeRegistry(recvRegistry) ;
275            delete[] recvBuff;
276          }
277
278          info(80)<<"Write data base Registry"<<endl<<globalRegistrySndServers.toString()<<endl ;
279          globalRegistrySndServers.toFile("xios_registry.bin") ;
280
281        }
282      }
283      delete globalRegistry;
284    }
285    CServer::finalize();
286
287#ifdef XIOS_MEMTRACK
288
289#ifdef XIOS_MEMTRACK_LIGHT
290       report(10) << " Memory report : current memory used by XIOS : "<<  MemTrack::getCurrentMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
291       report(10) << " Memory report : maximum memory used by XIOS : "<<  MemTrack::getMaxMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
292#endif
293
294#ifdef XIOS_MEMTRACK_FULL
295     MemTrack::TrackListMemoryUsage() ;
296     MemTrack::TrackDumpBlocks();
297#endif
298#endif
299    CServer::closeInfoStream();
300  }
301
302  //! Parse configuration file
303  void CXios::parseFile(const string& filename)
304  {
305    xml::CXMLParser::ParseFile(filename);
306  }
307
308  //! Set using server
309  void CXios::setUsingServer()
310  {
311    usingServer = true;
312  }
313
314  //! Unset using server
315  void CXios::setNotUsingServer()
316  {
317    usingServer = false;
318  }
319}
Note: See TracBrowser for help on using the repository browser.