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

Last change on this file since 2358 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
RevLine 
[300]1
[591]2#include "xios_spl.hpp"
[300]3#include "cxios.hpp"
[342]4#include "client.hpp"
5#include "server.hpp"
[346]6#include "xml_parser.hpp"
[300]7#include <boost/functional/hash.hpp>
[382]8#include "mpi.hpp"
[400]9#include "memory.hpp"
10#include <new>
[401]11#include "memtrack.hpp"
[697]12#include "registry.hpp"
[300]13
[335]14namespace xios
[300]15{
[1642]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";
[490]22
[1642]23  bool CXios::xiosStack = true;
24  bool CXios::systemStack = false;
25
[300]26  bool CXios::isClient ;
27  bool CXios::isServer ;
[1642]28  ep_lib::MPI_Comm CXios::globalComm ;
[300]29  bool CXios::usingOasis ;
[491]30  bool CXios::usingServer = false;
[1460]31  bool CXios::usingServer2 = false;
32  int CXios::ratioServer2 = 50;
33  int CXios::nbPoolsServer2 = 1;
[718]34  double CXios::bufferSizeFactor = 1.0;
35  const double CXios::defaultBufferSizeFactor = 1.0;
[719]36  StdSize CXios::minBufferSize = 1024 * sizeof(double);
[1460]37  StdSize CXios::maxBufferSize = std::numeric_limits<int>::max() ;
[523]38  bool CXios::printLogs2Files;
[511]39  bool CXios::isOptPerformance = true;
[697]40  CRegistry* CXios::globalRegistry = 0;
[1460]41  double CXios::recvFieldTimeout = 300.0;
42  bool CXios::checkEventSync=false ;
43 
[512]44  //! Parse configuration file and create some objects from it
[300]45  void CXios::initialize()
46  {
[400]47    set_new_handler(noMemory);
[1642]48    parseFile(rootFile);
[511]49    parseXiosConfig();
50  }
51
[512]52  /*!
53  \brief Parse xios part of configuration file (.iodef.xml)
54   Both client and server need information returned from this function
55  */
[511]56  void CXios::parseXiosConfig()
57  {
[311]58    usingOasis=getin<bool>("using_oasis",false) ;
[506]59    usingServer=getin<bool>("using_server",false) ;
[1460]60    usingServer2=getin<bool>("using_server2",false) ;
61    ratioServer2=getin<int>("ratio_server2",50);
[1545]62    nbPoolsServer2=getin<int>("number_pools_server2",0);
[311]63    info.setLevel(getin<int>("info_level",0)) ;
[512]64    report.setLevel(getin<int>("info_level",50));
[523]65    printLogs2Files=getin<bool>("print_file",false);
[512]66
[1642]67    xiosStack=getin<bool>("xios_stack",true) ;
68    systemStack=getin<bool>("system_stack",false) ;
69    if (xiosStack && systemStack)
70    {
71      xiosStack = false;
72    }
73
[511]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
[718]84    bufferSizeFactor = getin<double>("buffer_size_factor", defaultBufferSizeFactor);
[719]85    minBufferSize = getin<int>("min_buffer_size", 1024 * sizeof(double));
[1460]86    maxBufferSize = getin<int>("max_buffer_size", std::numeric_limits<int>::max());
87    recvFieldTimeout = getin<double>("recv_field_timeout", recvFieldTimeout);
[1029]88    if (recvFieldTimeout < 0.0)
89      ERROR("CXios::parseXiosConfig()", "recv_field_timeout cannot be negative.");
[718]90
[1460]91    checkEventSync = getin<bool>("check_event_sync", checkEventSync);
[1642]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
[300]101  }
102
[512]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  */
[1642]109  void CXios::initClientSide(const string& codeId, ep_lib::MPI_Comm& localComm, ep_lib::MPI_Comm& returnComm)
110  TRY
[300]111  {
[1134]112    isClient = true;
[1556]113    isServer = false;
[1460]114
[300]115    initialize() ;
[490]116
[1642]117
[1134]118    CClient::initialize(codeId,localComm,returnComm) ;
[697]119    if (CClient::getRank()==0) globalRegistry = new CRegistry(returnComm) ;
[491]120
[1642]121
[956]122    // If there are no server processes then we are in attached mode
123    // and the clients are also servers
124    isServer = !usingServer;
[490]125
[523]126    if (printLogs2Files)
127    {
[499]128      CClient::openInfoStream(clientFile);
[523]129      CClient::openErrorStream(clientFile);
130    }
[490]131    else
[523]132    {
[490]133      CClient::openInfoStream();
[523]134      CClient::openErrorStream();
135    }
[490]136  }
[1642]137  CATCH
[300]138
139  void CXios::clientFinalize(void)
140  {
[490]141     CClient::finalize() ;
[697]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     }
[1160]148
[401]149#ifdef XIOS_MEMTRACK
[1156]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
[401]157     MemTrack::TrackListMemoryUsage() ;
[490]158     MemTrack::TrackDumpBlocks();
[401]159#endif
[1161]160
[1205]161     CClient::closeInfoStream();
162
[1161]163#endif
[490]164  }
165
[512]166  //! Init server by parsing only xios part of config file
[509]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);
[511]173    parseXiosConfig();
[509]174  }
175
[512]176  //! Initialize server then put it into listening state
[300]177  void CXios::initServerSide(void)
178  {
[956]179    isClient = false;
180    isServer = true;
[1460]181
[1134]182    initServer();
[1642]183    isClient = false;
184    isServer = true;
[491]185    // Initialize all aspects MPI
[490]186    CServer::initialize();
[1460]187    if (CServer::getRank()==0 && CServer::serverLevel != 1) globalRegistry = new CRegistry(CServer::intraComm) ;
[697]188   
[523]189    if (printLogs2Files)
190    {
[1460]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      }
[523]206    }
[490]207    else
[523]208    {
[490]209      CServer::openInfoStream();
[523]210      CServer::openErrorStream();
211    }
[490]212
[491]213    // Enter the loop to listen message from Client
[490]214    CServer::eventLoop();
215
[491]216    // Finalize
[1460]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;
[1642]237        ep_lib::MPI_Comm_rank(globalComm, &rankGlobal);
[1460]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();
[1642]249            ep_lib::MPI_Send(&registrySize,1,EP_LONG,firstPoolGlobalRank,15,CXios::globalComm) ;
[1460]250            CBufferOut buffer(registrySize) ;
251            globalRegistrySndServers.toBuffer(buffer) ;
[1642]252            ep_lib::MPI_Send(buffer.start(),registrySize,EP_CHAR,firstPoolGlobalRank,15,CXios::globalComm) ;
[1460]253          }
254        }
255
256        // First pool: receive globalRegistry of all secondary server pools, merge and write the resultant registry
257        if (rankGlobal == firstPoolGlobalRank)
258        {
[1642]259          ep_lib::MPI_Status status;
[1460]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;
[1642]268            ep_lib::MPI_Recv(&registrySize, 1, EP_LONG, rank, 15, CXios::globalComm, &status);
[1460]269            recvBuff = new char[registrySize];
[1642]270            ep_lib::MPI_Recv(recvBuff, registrySize, EP_CHAR, rank, 15, CXios::globalComm, &status);
[1460]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    }
[1205]285    CServer::finalize();
[1134]286
[1205]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
[490]299    CServer::closeInfoStream();
300  }
301
[512]302  //! Parse configuration file
[346]303  void CXios::parseFile(const string& filename)
304  {
[490]305    xml::CXMLParser::ParseFile(filename);
[346]306  }
[491]307
[512]308  //! Set using server
[491]309  void CXios::setUsingServer()
310  {
311    usingServer = true;
312  }
313
[512]314  //! Unset using server
[491]315  void CXios::setNotUsingServer()
316  {
317    usingServer = false;
318  }
[300]319}
Note: See TracBrowser for help on using the repository browser.