source: XIOS/dev/dev_olga/src/cxios.cpp @ 1612

Last change on this file since 1612 was 1612, checked in by oabramkina, 5 years ago

Dev: adding exception handling.

To activate it, compilation flag -DXIOS_EXCEPTION should be added.

  • 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.4 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{
16  string CXios::rootFile="./iodef.xml" ;
17  string CXios::xiosCodeId="xios.x" ;
[499]18  string CXios::clientFile="./xios_client";
19  string CXios::serverFile="./xios_server";
[1021]20  string CXios::serverPrmFile="./xios_server1";
21  string CXios::serverSndFile="./xios_server2";
[490]22
[1612]23  bool CXios::xiosStack = true;
24  bool CXios::systemStack = false;
25
[300]26  bool CXios::isClient ;
27  bool CXios::isServer ;
28  MPI_Comm CXios::globalComm ;
29  bool CXios::usingOasis ;
[491]30  bool CXios::usingServer = false;
[1021]31  bool CXios::usingServer2 = false;
32  int CXios::ratioServer2 = 50;
[1243]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);
[1227]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;
[1375]41  double CXios::recvFieldTimeout = 300.0;
[1377]42  bool CXios::checkEventSync=false ;
[1376]43 
[512]44  //! Parse configuration file and create some objects from it
[300]45  void CXios::initialize()
46  {
[400]47    set_new_handler(noMemory);
[346]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) ;
[1021]60    usingServer2=getin<bool>("using_server2",false) ;
61    ratioServer2=getin<int>("ratio_server2",50);
[1519]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
[1612]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));
[1227]86    maxBufferSize = getin<int>("max_buffer_size", std::numeric_limits<int>::max());
[1376]87    recvFieldTimeout = getin<double>("recv_field_timeout", recvFieldTimeout);
[1158]88    if (recvFieldTimeout < 0.0)
89      ERROR("CXios::parseXiosConfig()", "recv_field_timeout cannot be negative.");
[718]90
[1377]91    checkEventSync = getin<bool>("check_event_sync", checkEventSync);
92
[300]93    globalComm=MPI_COMM_WORLD ;
94  }
95
[512]96  /*!
97  Initialize client
98  \param [in] codeId identity of context
99  \param [in] localComm local communicator
100  \param [in/out] returnComm communicator corresponding to group of client with same codeId
101  */
[300]102  void CXios::initClientSide(const string& codeId, MPI_Comm& localComm, MPI_Comm& returnComm)
[1612]103  TRY
[300]104  {
105    initialize() ;
[490]106
[956]107    isClient = true;
[491]108
109    CClient::initialize(codeId,localComm,returnComm) ;
[697]110    if (CClient::getRank()==0) globalRegistry = new CRegistry(returnComm) ;
[491]111
[956]112    // If there are no server processes then we are in attached mode
113    // and the clients are also servers
114    isServer = !usingServer;
[490]115
[523]116    if (printLogs2Files)
117    {
[499]118      CClient::openInfoStream(clientFile);
[523]119      CClient::openErrorStream(clientFile);
120    }
[490]121    else
[523]122    {
[490]123      CClient::openInfoStream();
[523]124      CClient::openErrorStream();
125    }
[490]126  }
[1612]127  CATCH
[300]128
129  void CXios::clientFinalize(void)
130  {
[490]131     CClient::finalize() ;
[697]132     if (CClient::getRank()==0)
133     {
134       info(80)<<"Write data base Registry"<<endl<<globalRegistry->toString()<<endl ;
135       globalRegistry->toFile("xios_registry.bin") ;
136       delete globalRegistry ;
137     }
[490]138
[401]139#ifdef XIOS_MEMTRACK
[1158]140
141#ifdef XIOS_MEMTRACK_LIGHT
142       report(10) << " Memory report : current memory used by XIOS : "<<  MemTrack::getCurrentMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
143       report(10) << " Memory report : maximum memory used by XIOS : "<<  MemTrack::getMaxMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
144#endif
145
146#ifdef XIOS_MEMTRACK_FULL
[401]147     MemTrack::TrackListMemoryUsage() ;
[490]148     MemTrack::TrackDumpBlocks();
[401]149#endif
[1158]150
151     CClient::closeInfoStream();
152
153#endif
[490]154  }
155
[512]156  //! Init server by parsing only xios part of config file
[509]157  void CXios::initServer()
158  {
159    set_new_handler(noMemory);
160    std::set<StdString> parseList;
161    parseList.insert("xios");
162    xml::CXMLParser::ParseFile(rootFile, parseList);
[511]163    parseXiosConfig();
[509]164  }
165
[512]166  //! Initialize server then put it into listening state
[1054]167  void CXios::initServerSide(void)
[300]168  {
[509]169    initServer();
[1158]170    isClient = false;
171    isServer = true;
[1021]172
173    // Initialize all aspects MPI
174    CServer::initialize();
[1330]175    if (CServer::getRank()==0 && CServer::serverLevel != 1) globalRegistry = new CRegistry(CServer::intraComm) ;
[697]176   
[523]177    if (printLogs2Files)
178    {
[1021]179      if (CServer::serverLevel == 0)
[983]180      {
181        CServer::openInfoStream(serverFile);
182        CServer::openErrorStream(serverFile);
183      }
[1021]184      else if (CServer::serverLevel == 1)
[983]185      {
[1021]186        CServer::openInfoStream(serverPrmFile);
187        CServer::openErrorStream(serverPrmFile);
[983]188      }
189      else
190      {
[1021]191        CServer::openInfoStream(serverSndFile);
192        CServer::openErrorStream(serverSndFile);
[983]193      }
[523]194    }
[490]195    else
[523]196    {
[490]197      CServer::openInfoStream();
[523]198      CServer::openErrorStream();
199    }
[490]200
[491]201    // Enter the loop to listen message from Client
[490]202    CServer::eventLoop();
203
[491]204    // Finalize
[1234]205    if (CServer::serverLevel == 0)
[1168]206    {
207      if (CServer::getRank()==0)
208      {
209        info(80)<<"Write data base Registry"<<endl<<globalRegistry->toString()<<endl ;
210        globalRegistry->toFile("xios_registry.bin") ;
211        delete globalRegistry ;
212      }
213    }
214    else
215    {
[1243]216      // If using two server levels:
217      // (1) merge registries on each pool
218      // (2) send merged registries to the first pool
219      // (3) merge received registries on the first pool
[1168]220      if (CServer::serverLevel == 2)
221      {
222        vector<int>& secondaryServerGlobalRanks = CServer::getSecondaryServerGlobalRanks();
223        int firstPoolGlobalRank = secondaryServerGlobalRanks[0];
224        int rankGlobal;
225        MPI_Comm_rank(globalComm, &rankGlobal);
226
[1243]227        // Merge registries defined on each pools
228        CRegistry globalRegistrySndServers (CServer::intraComm);
229
[1168]230        // All pools (except the first): send globalRegistry to the first pool
[1243]231        for (int i=1; i<secondaryServerGlobalRanks.size(); i++)
[1168]232        {
[1243]233          if (rankGlobal == secondaryServerGlobalRanks[i])
234          {
235            globalRegistrySndServers.mergeRegistry(*globalRegistry) ;
236            int registrySize = globalRegistrySndServers.size();
237            MPI_Send(&registrySize,1,MPI_LONG,firstPoolGlobalRank,15,CXios::globalComm) ;
238            CBufferOut buffer(registrySize) ;
239            globalRegistrySndServers.toBuffer(buffer) ;
240            MPI_Send(buffer.start(),registrySize,MPI_CHAR,firstPoolGlobalRank,15,CXios::globalComm) ;
241          }
[1168]242        }
243
244        // First pool: receive globalRegistry of all secondary server pools, merge and write the resultant registry
[1243]245        if (rankGlobal == firstPoolGlobalRank)
[1168]246        {
247          MPI_Status status;
248          char* recvBuff;
249
250          globalRegistrySndServers.mergeRegistry(*globalRegistry) ;
251
252          for (int i=1; i< secondaryServerGlobalRanks.size(); i++)
253          {
254            int rank = secondaryServerGlobalRanks[i];
255            int registrySize = 0;
256            MPI_Recv(&registrySize, 1, MPI_LONG, rank, 15, CXios::globalComm, &status);
257            recvBuff = new char[registrySize];
258            MPI_Recv(recvBuff, registrySize, MPI_CHAR, rank, 15, CXios::globalComm, &status);
259            CBufferIn buffer(recvBuff, registrySize) ;
260            CRegistry recvRegistry;
261            recvRegistry.fromBuffer(buffer) ;
262            globalRegistrySndServers.mergeRegistry(recvRegistry) ;
263            delete[] recvBuff;
264          }
265
266          info(80)<<"Write data base Registry"<<endl<<globalRegistrySndServers.toString()<<endl ;
267          globalRegistrySndServers.toFile("xios_registry.bin") ;
268
269        }
270      }
271      delete globalRegistry;
272    }
[490]273    CServer::finalize();
[1158]274
275#ifdef XIOS_MEMTRACK
276
277#ifdef XIOS_MEMTRACK_LIGHT
278       report(10) << " Memory report : current memory used by XIOS : "<<  MemTrack::getCurrentMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
279       report(10) << " Memory report : maximum memory used by XIOS : "<<  MemTrack::getMaxMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
280#endif
281
282#ifdef XIOS_MEMTRACK_FULL
283     MemTrack::TrackListMemoryUsage() ;
284     MemTrack::TrackDumpBlocks();
285#endif
286#endif
[490]287    CServer::closeInfoStream();
288  }
289
[512]290  //! Parse configuration file
[346]291  void CXios::parseFile(const string& filename)
292  {
[490]293    xml::CXMLParser::ParseFile(filename);
[346]294  }
[491]295
[512]296  //! Set using server
[491]297  void CXios::setUsingServer()
298  {
299    usingServer = true;
300  }
301
[512]302  //! Unset using server
[491]303  void CXios::setNotUsingServer()
304  {
305    usingServer = false;
306  }
[300]307}
Note: See TracBrowser for help on using the repository browser.