source: XIOS/dev/XIOS_DEV_CMIP6/src/cxios.cpp @ 1519

Last change on this file since 1519 was 1519, checked in by oabramkina, 2 years ago

Activating an option for setting different number of processes per secondary-server pool via parameter number_pools_server2.

  • 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.1 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::isClient ;
24  bool CXios::isServer ;
25  MPI_Comm CXios::globalComm ;
26  bool CXios::usingOasis ;
27  bool CXios::usingServer = false;
28  bool CXios::usingServer2 = false;
29  int CXios::ratioServer2 = 50;
30  int CXios::nbPoolsServer2 = 1;
31  double CXios::bufferSizeFactor = 1.0;
32  const double CXios::defaultBufferSizeFactor = 1.0;
33  StdSize CXios::minBufferSize = 1024 * sizeof(double);
34  StdSize CXios::maxBufferSize = std::numeric_limits<int>::max() ;
35  bool CXios::printLogs2Files;
36  bool CXios::isOptPerformance = true;
37  CRegistry* CXios::globalRegistry = 0;
38  double CXios::recvFieldTimeout = 300.0;
39  bool CXios::checkEventSync=false ;
40 
41  //! Parse configuration file and create some objects from it
42  void CXios::initialize()
43  {
44    set_new_handler(noMemory);
45    parseFile(rootFile);
46    parseXiosConfig();
47  }
48
49  /*!
50  \brief Parse xios part of configuration file (.iodef.xml)
51   Both client and server need information returned from this function
52  */
53  void CXios::parseXiosConfig()
54  {
55    usingOasis=getin<bool>("using_oasis",false) ;
56    usingServer=getin<bool>("using_server",false) ;
57    usingServer2=getin<bool>("using_server2",false) ;
58    ratioServer2=getin<int>("ratio_server2",50);
59    nbPoolsServer2=getin<int>("number_pools_server2",0);
60    info.setLevel(getin<int>("info_level",0)) ;
61    report.setLevel(getin<int>("info_level",50));
62    printLogs2Files=getin<bool>("print_file",false);
63
64    StdString bufMemory("memory");
65    StdString bufPerformance("performance");
66    StdString bufOpt = getin<StdString>("optimal_buffer_size", bufPerformance);
67    std::transform(bufOpt.begin(), bufOpt.end(), bufOpt.begin(), ::tolower);
68    if (0 == bufOpt.compare(bufMemory)) isOptPerformance = false;
69    else if (0 != bufOpt.compare(bufPerformance))
70    {
71      ERROR("CXios::parseXiosConfig()", << "optimal_buffer_size must be memory or performance "<< endl );
72    }
73
74    bufferSizeFactor = getin<double>("buffer_size_factor", defaultBufferSizeFactor);
75    minBufferSize = getin<int>("min_buffer_size", 1024 * sizeof(double));
76    maxBufferSize = getin<int>("max_buffer_size", std::numeric_limits<int>::max());
77    recvFieldTimeout = getin<double>("recv_field_timeout", recvFieldTimeout);
78    if (recvFieldTimeout < 0.0)
79      ERROR("CXios::parseXiosConfig()", "recv_field_timeout cannot be negative.");
80
81    checkEventSync = getin<bool>("check_event_sync", checkEventSync);
82
83    globalComm=MPI_COMM_WORLD ;
84  }
85
86  /*!
87  Initialize client
88  \param [in] codeId identity of context
89  \param [in] localComm local communicator
90  \param [in/out] returnComm communicator corresponding to group of client with same codeId
91  */
92  void CXios::initClientSide(const string& codeId, MPI_Comm& localComm, MPI_Comm& returnComm)
93  {
94    initialize() ;
95
96    isClient = true;
97
98    CClient::initialize(codeId,localComm,returnComm) ;
99    if (CClient::getRank()==0) globalRegistry = new CRegistry(returnComm) ;
100
101    // If there are no server processes then we are in attached mode
102    // and the clients are also servers
103    isServer = !usingServer;
104
105    if (printLogs2Files)
106    {
107      CClient::openInfoStream(clientFile);
108      CClient::openErrorStream(clientFile);
109    }
110    else
111    {
112      CClient::openInfoStream();
113      CClient::openErrorStream();
114    }
115  }
116
117  void CXios::clientFinalize(void)
118  {
119     CClient::finalize() ;
120     if (CClient::getRank()==0)
121     {
122       info(80)<<"Write data base Registry"<<endl<<globalRegistry->toString()<<endl ;
123       globalRegistry->toFile("xios_registry.bin") ;
124       delete globalRegistry ;
125     }
126
127#ifdef XIOS_MEMTRACK
128
129#ifdef XIOS_MEMTRACK_LIGHT
130       report(10) << " Memory report : current memory used by XIOS : "<<  MemTrack::getCurrentMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
131       report(10) << " Memory report : maximum memory used by XIOS : "<<  MemTrack::getMaxMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
132#endif
133
134#ifdef XIOS_MEMTRACK_FULL
135     MemTrack::TrackListMemoryUsage() ;
136     MemTrack::TrackDumpBlocks();
137#endif
138
139     CClient::closeInfoStream();
140
141#endif
142  }
143
144  //! Init server by parsing only xios part of config file
145  void CXios::initServer()
146  {
147    set_new_handler(noMemory);
148    std::set<StdString> parseList;
149    parseList.insert("xios");
150    xml::CXMLParser::ParseFile(rootFile, parseList);
151    parseXiosConfig();
152  }
153
154  //! Initialize server then put it into listening state
155  void CXios::initServerSide(void)
156  {
157    initServer();
158    isClient = false;
159    isServer = true;
160
161    // Initialize all aspects MPI
162    CServer::initialize();
163    if (CServer::getRank()==0 && CServer::serverLevel != 1) globalRegistry = new CRegistry(CServer::intraComm) ;
164   
165    if (printLogs2Files)
166    {
167      if (CServer::serverLevel == 0)
168      {
169        CServer::openInfoStream(serverFile);
170        CServer::openErrorStream(serverFile);
171      }
172      else if (CServer::serverLevel == 1)
173      {
174        CServer::openInfoStream(serverPrmFile);
175        CServer::openErrorStream(serverPrmFile);
176      }
177      else
178      {
179        CServer::openInfoStream(serverSndFile);
180        CServer::openErrorStream(serverSndFile);
181      }
182    }
183    else
184    {
185      CServer::openInfoStream();
186      CServer::openErrorStream();
187    }
188
189    // Enter the loop to listen message from Client
190    CServer::eventLoop();
191
192    // Finalize
193    if (CServer::serverLevel == 0)
194    {
195      if (CServer::getRank()==0)
196      {
197        info(80)<<"Write data base Registry"<<endl<<globalRegistry->toString()<<endl ;
198        globalRegistry->toFile("xios_registry.bin") ;
199        delete globalRegistry ;
200      }
201    }
202    else
203    {
204      // If using two server levels:
205      // (1) merge registries on each pool
206      // (2) send merged registries to the first pool
207      // (3) merge received registries on the first pool
208      if (CServer::serverLevel == 2)
209      {
210        vector<int>& secondaryServerGlobalRanks = CServer::getSecondaryServerGlobalRanks();
211        int firstPoolGlobalRank = secondaryServerGlobalRanks[0];
212        int rankGlobal;
213        MPI_Comm_rank(globalComm, &rankGlobal);
214
215        // Merge registries defined on each pools
216        CRegistry globalRegistrySndServers (CServer::intraComm);
217
218        // All pools (except the first): send globalRegistry to the first pool
219        for (int i=1; i<secondaryServerGlobalRanks.size(); i++)
220        {
221          if (rankGlobal == secondaryServerGlobalRanks[i])
222          {
223            globalRegistrySndServers.mergeRegistry(*globalRegistry) ;
224            int registrySize = globalRegistrySndServers.size();
225            MPI_Send(&registrySize,1,MPI_LONG,firstPoolGlobalRank,15,CXios::globalComm) ;
226            CBufferOut buffer(registrySize) ;
227            globalRegistrySndServers.toBuffer(buffer) ;
228            MPI_Send(buffer.start(),registrySize,MPI_CHAR,firstPoolGlobalRank,15,CXios::globalComm) ;
229          }
230        }
231
232        // First pool: receive globalRegistry of all secondary server pools, merge and write the resultant registry
233        if (rankGlobal == firstPoolGlobalRank)
234        {
235          MPI_Status status;
236          char* recvBuff;
237
238          globalRegistrySndServers.mergeRegistry(*globalRegistry) ;
239
240          for (int i=1; i< secondaryServerGlobalRanks.size(); i++)
241          {
242            int rank = secondaryServerGlobalRanks[i];
243            int registrySize = 0;
244            MPI_Recv(&registrySize, 1, MPI_LONG, rank, 15, CXios::globalComm, &status);
245            recvBuff = new char[registrySize];
246            MPI_Recv(recvBuff, registrySize, MPI_CHAR, rank, 15, CXios::globalComm, &status);
247            CBufferIn buffer(recvBuff, registrySize) ;
248            CRegistry recvRegistry;
249            recvRegistry.fromBuffer(buffer) ;
250            globalRegistrySndServers.mergeRegistry(recvRegistry) ;
251            delete[] recvBuff;
252          }
253
254          info(80)<<"Write data base Registry"<<endl<<globalRegistrySndServers.toString()<<endl ;
255          globalRegistrySndServers.toFile("xios_registry.bin") ;
256
257        }
258      }
259      delete globalRegistry;
260    }
261    CServer::finalize();
262
263#ifdef XIOS_MEMTRACK
264
265#ifdef XIOS_MEMTRACK_LIGHT
266       report(10) << " Memory report : current memory used by XIOS : "<<  MemTrack::getCurrentMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
267       report(10) << " Memory report : maximum memory used by XIOS : "<<  MemTrack::getMaxMemorySize()*1.0/(1024*1024)<<" Mbyte" << endl ;
268#endif
269
270#ifdef XIOS_MEMTRACK_FULL
271     MemTrack::TrackListMemoryUsage() ;
272     MemTrack::TrackDumpBlocks();
273#endif
274#endif
275    CServer::closeInfoStream();
276  }
277
278  //! Parse configuration file
279  void CXios::parseFile(const string& filename)
280  {
281    xml::CXMLParser::ParseFile(filename);
282  }
283
284  //! Set using server
285  void CXios::setUsingServer()
286  {
287    usingServer = true;
288  }
289
290  //! Unset using server
291  void CXios::setNotUsingServer()
292  {
293    usingServer = false;
294  }
295}
Note: See TracBrowser for help on using the repository browser.