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

Last change on this file since 1612 was 1612, checked in by oabramkina, 21 months 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
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  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
93    globalComm=MPI_COMM_WORLD ;
94  }
95
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  */
102  void CXios::initClientSide(const string& codeId, MPI_Comm& localComm, MPI_Comm& returnComm)
103  TRY
104  {
105    initialize() ;
106
107    isClient = true;
108
109    CClient::initialize(codeId,localComm,returnComm) ;
110    if (CClient::getRank()==0) globalRegistry = new CRegistry(returnComm) ;
111
112    // If there are no server processes then we are in attached mode
113    // and the clients are also servers
114    isServer = !usingServer;
115
116    if (printLogs2Files)
117    {
118      CClient::openInfoStream(clientFile);
119      CClient::openErrorStream(clientFile);
120    }
121    else
122    {
123      CClient::openInfoStream();
124      CClient::openErrorStream();
125    }
126  }
127  CATCH
128
129  void CXios::clientFinalize(void)
130  {
131     CClient::finalize() ;
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     }
138
139#ifdef XIOS_MEMTRACK
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
147     MemTrack::TrackListMemoryUsage() ;
148     MemTrack::TrackDumpBlocks();
149#endif
150
151     CClient::closeInfoStream();
152
153#endif
154  }
155
156  //! Init server by parsing only xios part of config file
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);
163    parseXiosConfig();
164  }
165
166  //! Initialize server then put it into listening state
167  void CXios::initServerSide(void)
168  {
169    initServer();
170    isClient = false;
171    isServer = true;
172
173    // Initialize all aspects MPI
174    CServer::initialize();
175    if (CServer::getRank()==0 && CServer::serverLevel != 1) globalRegistry = new CRegistry(CServer::intraComm) ;
176   
177    if (printLogs2Files)
178    {
179      if (CServer::serverLevel == 0)
180      {
181        CServer::openInfoStream(serverFile);
182        CServer::openErrorStream(serverFile);
183      }
184      else if (CServer::serverLevel == 1)
185      {
186        CServer::openInfoStream(serverPrmFile);
187        CServer::openErrorStream(serverPrmFile);
188      }
189      else
190      {
191        CServer::openInfoStream(serverSndFile);
192        CServer::openErrorStream(serverSndFile);
193      }
194    }
195    else
196    {
197      CServer::openInfoStream();
198      CServer::openErrorStream();
199    }
200
201    // Enter the loop to listen message from Client
202    CServer::eventLoop();
203
204    // Finalize
205    if (CServer::serverLevel == 0)
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    {
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
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
227        // Merge registries defined on each pools
228        CRegistry globalRegistrySndServers (CServer::intraComm);
229
230        // All pools (except the first): send globalRegistry to the first pool
231        for (int i=1; i<secondaryServerGlobalRanks.size(); i++)
232        {
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          }
242        }
243
244        // First pool: receive globalRegistry of all secondary server pools, merge and write the resultant registry
245        if (rankGlobal == firstPoolGlobalRank)
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    }
273    CServer::finalize();
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
287    CServer::closeInfoStream();
288  }
289
290  //! Parse configuration file
291  void CXios::parseFile(const string& filename)
292  {
293    xml::CXMLParser::ParseFile(filename);
294  }
295
296  //! Set using server
297  void CXios::setUsingServer()
298  {
299    usingServer = true;
300  }
301
302  //! Unset using server
303  void CXios::setNotUsingServer()
304  {
305    usingServer = false;
306  }
307}
Note: See TracBrowser for help on using the repository browser.