source: XMLIO_V2/dev/common/src/xmlio/manager/xios_manager.cpp @ 286

Last change on this file since 286 was 286, checked in by ymipsl, 13 years ago

reprise en main de la version de H. Ozdoba. Correction de différentes erreurs de conception et bug.
Version NEMO operationnel en client/server, interoperabilita avec OASIS, reconstition de fichiers via netcdf4/HDF5

YM

File size: 15.9 KB
Line 
1#include "xios_manager.hpp"
2
3#include "tree_manager.hpp"
4#include "data_treatment.hpp"
5#include "nc4_data_output.hpp"
6#include "attribute_template_impl.hpp"
7#include "group_template_impl.hpp"
8
9namespace xmlioserver
10{
11      /// ////////////////////// Définitions ////////////////////// ///
12     
13      void CXIOSManager::Initialise(XIOSType type, int * argc, char *** argv)
14      {
15         CXIOSManager::Type = type;
16         if (type != CLIENT)
17         {
18            // Initialisation de la biliothÚque MPI si nécessaire
19            comm::CMPIManager::InitialiseServer(argc, argv);
20            ExeName = StdString((*argv)[0]);
21            for (int i = 1; i < *argc; i++)
22               ExeOptions.push_back(StdString((*argv)[i]));
23         }
24      }
25
26      void CXIOSManager::Finalize(void)
27      {
28         if (CXIOSManager::Type != CLIENT)
29
30         {
31            // Finalisation de la biliothÚque MPI si nécessaire
32            comm::CMPIManager::Finalize();
33         }
34      }
35
36      ///-------------------------------------------------------------
37
38      StdString CXIOSManager::ExeName("unknown");
39      std::vector<StdString> CXIOSManager::ExeOptions;
40
41      CXIOSManager::XIOSType   CXIOSManager::Type    = CLIENT;
42      CXIOSManager::XIOSStatus CXIOSManager::Status  = LOC_UNUSED;
43
44      StdString     CXIOSManager::ClientName("unknown name");
45      MPI_Comm CXIOSManager::Comm_Client_Server = MPI_COMM_NULL;
46      MPI_Comm CXIOSManager::Comm_Server = MPI_COMM_NULL;
47
48      xios_map<StdString, CXIOSManager::XIOSClient> CXIOSManager::Clients;
49
50      ///--------------------------------------------------------------
51     
52      void CXIOSManager::RunServer
53         (StdString clientName, MPI_Comm comm_client_server, MPI_Comm comm_server)
54      {
55         using namespace comm;
56         CXIOSManager::Comm_Client_Server = comm_client_server;
57         CXIOSManager::Comm_Server        = comm_server;
58         CXIOSManager::Status             = LOC_SERVER;
59         
60         // Reconstruction de l'arborescence d'objet à l'aide des données envoyées par chacun des
61         // clients associés à ce serveur.
62         std::vector<boost::shared_ptr<CLinearBuffer> > clientBuffer;
63         for (int i = 1; i < CMPIManager::GetCommSize(comm_client_server); i++)
64         {
65            while (!CMPIManager::HasReceivedData(comm_client_server, i)){}
66            clientBuffer.push_back(CMPIManager::ReceiveLinearBuffer(comm_client_server, i));
67         }
68         
69         // La quasi-totalité de l'arborescence est obtenue depuis les informations
70         // fournies par le client 1 du sous-groupe.
71/*         StdString main_data_tree = clientBuffer[0]->getString(0);       
72         tree::CTreeManager::FromBinary(main_data_tree);
73         
74         // Obtention des sous-domaines clients.
75         for (StdSize j = 1; j < clientBuffer.size(); j++)
76         {
77            main_data_tree = clientBuffer[j]->getString(0);
78            tree::CTreeManager::DomainsFromBinary(main_data_tree);
79         }
80*/
81
82         // Obtention des sous-domaines clients.
83         for (StdSize j = 0; j < clientBuffer.size(); j++)
84         {
85             StdString main_data_tree = clientBuffer[j]->getString(0);
86            tree::CTreeManager::FromBinary(main_data_tree);
87         }
88
89         
90         StdOStringStream osss;
91         osss << StdString("./def_server_next.")
92              << CMPIManager::GetCommRank(CMPIManager::GetCommWorld());
93         CTreeManager::PrintTreeToFile(osss.str());
94
95         {  // Traitement de tous les contextes
96            StdString currentContextId = CObjectFactory::GetCurrentContextId();
97            std::vector<boost::shared_ptr<CContext> > def_vector =
98                                   CContext::GetContextGroup()->getChildList();
99            std::vector<boost::shared_ptr<CContext> >::iterator
100                               it = def_vector.begin(), end = def_vector.end();
101
102            //for (; it != end; it++ )
103            {
104               boost::shared_ptr<CContext> context = *it;
105               CTreeManager::SetCurrentContextId(context->getId());
106               boost::shared_ptr<data::CDataTreatment> dt(new data::CDataTreatment (context));
107               context->setDataTreatment(dt);
108               dt->createDataOutput<io::CNc4DataOutput>();
109            }
110            CTreeManager::SetCurrentContextId(currentContextId);
111         }
112       
113         StdOStringStream oss;
114         oss << StdString("./def_server_end.")
115             << CMPIManager::GetCommRank(CMPIManager::GetCommWorld());
116         CTreeManager::PrintTreeToFile(oss.str());     
117 
118      }
119     
120      //--------------------------------------------------------------
121     
122      void CXIOSManager::ShowInformation_CS(MPI_Comm comm_client_server)
123      {
124         using namespace comm;
125         typedef std::pair<StdString, XIOSClient> StdPairStrClient;
126         if (CMPIManager::IsMaster(comm_client_server))
127         {
128            std::cout << " *************************************** " << std::endl
129                      << " *     XmlIOServer (Client/Server)     * " << std::endl
130                      << " *************************************** " << std::endl;
131            std::cout << " > Nombre de processus : "
132                      << CMPIManager::GetCommSize(comm_client_server) << std::endl;
133            std::cout << " > Nombre de processus utilisés : "
134                      << (CXIOSManager::GetNbClient() + CXIOSManager::GetNbServer()) << std::endl;
135            std::cout << " > Nombre de clients : "
136                      << CXIOSManager::GetNbClient() << std::endl;
137            std::cout << " > Nombre de serveurs : "
138                      << CXIOSManager::GetNbServer() << std::endl;
139
140            xios_map<StdString, XIOSClient>::iterator
141               iit  = CXIOSManager::Clients.begin(),
142               eend = CXIOSManager::Clients.end();
143
144            for (;iit != eend; iit++)
145            {
146               const StdPairStrClient & elem = *iit;
147               std::cout << " - " << elem.first
148                         << " > nombre de clients : "             
149                         << elem.second.nbClient
150                         << " , nombre de clients par serveur : " 
151                         << elem.second.nbClientPServer
152                         << " , nombre de serveurs : "           
153                         << elem.second.nbClient/elem.second.nbClientPServer
154                         << std::endl;
155            }
156
157            std::cout << " *************************************** " << std::endl;
158         }
159
160         comm::CMPIManager::Barrier(comm_client_server);
161         
162      }
163     
164      //--------------------------------------------------------------
165     
166      void CXIOSManager::RunClientServer(MPI_Comm comm_client_server)
167      {
168         using namespace comm;
169         typedef std::pair<StdString, XIOSClient> StdPairStrClient;
170         CXIOSManager::Comm_Client_Server = comm_client_server;
171         CXIOSManager::Comm_Server        = comm_client_server;
172         
173         CXIOSManager::ShowInformation_CS(comm_client_server);
174         
175         xios_map<StdString, XIOSClient>::iterator
176               iit  = CXIOSManager::Clients.begin(),
177               eend = CXIOSManager::Clients.end();
178         
179         StdSize start = 0, end   = 0;
180         
181         bool isClient = true, isIncl = false, isIncl_ = false;
182         MPI_Comm comm_client = 0, comm_client_grp = 0; comm_client_server = 0;
183
184         for (;iit != eend; iit++)
185         {
186            const StdPairStrClient & elem = *iit;
187
188            std::vector<int> clieindex, servindex ;
189            StdSize   currentRank      = CMPIManager::GetCommRank();
190            StdString clientName       = elem.first;
191            StdSize   nbClient         = elem.second.nbClient;
192            StdSize   nbClientPServer  = elem.second.nbClientPServer;
193            StdSize   nbServer         = (elem.second.nbClient)/(elem.second.nbClientPServer);
194
195            for (StdSize i = 0; i<nbServer; i++)
196            {
197               end = start + nbClientPServer;
198               MPI_Comm comm_  =  CMPIManager::CreateComm
199                  (CMPIManager::CreateSubGroup(CMPIManager::GetGroupWorld(), start, end));
200               MPI_Comm comm__ =  CMPIManager::CreateComm
201                  (CMPIManager::CreateSubGroup(CMPIManager::GetGroupWorld(), start+1, end));
202                 
203               servindex.push_back(start);
204               for (StdSize j = start+1; j <= end; j++)
205                  clieindex.push_back(j);
206                               
207               if ((currentRank >= start) && (currentRank <= end))
208               {
209                  comm_client_server = comm_;
210                  comm_client_grp    = comm__;
211                  isIncl = true;
212                  CXIOSManager::ClientName = clientName;
213                  CXIOSManager::Status = LOC_CLIENT;
214               }
215               if (currentRank == start)
216               {
217                  isClient = false; isIncl_  = true;
218                  CXIOSManager::Comm_Client_Server = comm_;
219                  CXIOSManager::Status = LOC_SERVER;
220               }               
221               if (clieindex.size() == nbClient)
222               {
223                  MPI_Comm comm___ = CMPIManager::CreateComm
224                  (CMPIManager::CreateSubGroup(CMPIManager::GetGroupWorld(), clieindex));
225                  if (isIncl) comm_client = comm___;
226                  clieindex.clear();
227                  isIncl = false;
228               }
229               
230               start = start + nbClientPServer + 1;
231            }
232            MPI_Comm comm____ = CMPIManager::CreateComm
233               (CMPIManager::CreateSubGroup(CMPIManager::GetGroupWorld(), servindex));
234            if (isIncl_) CXIOSManager::Comm_Server = comm____;               
235            servindex.clear();
236            isIncl_ = false;           
237         }
238         
239         if (isClient && (CXIOSManager::Clients.find(CXIOSManager::ClientName) !=
240                          CXIOSManager::Clients.end()))
241         {
242            CXIOSManager::Clients[CXIOSManager::ClientName].entry
243               (comm_client, comm_client_grp, comm_client_server);
244         }
245         else if(CXIOSManager::Clients.find(CXIOSManager::ClientName) !=
246                 CXIOSManager::Clients.end())
247         {
248            CXIOSManager::RunServer(CXIOSManager::ClientName, 
249                                    CXIOSManager::Comm_Client_Server,
250                                    CXIOSManager::Comm_Server);
251         }
252      }
253     
254      //---------------------------------------------------------------
255     
256      void CXIOSManager::RunClient(bool launch, MPI_Comm comm_client)
257      {
258         if (launch)
259         {
260            CXIOSManager::Status       = LOC_CLIENT_SERVER;   
261            CXIOSManager::Comm_Server  = comm_client;   
262            (CXIOSManager::Clients.begin()->second.entry)
263               (comm_client, comm_client, comm_client);
264         }
265         else
266         {
267            CXIOSManager::Status  = LOC_CLIENT;
268         }
269      }
270
271      //---------------------------------------------------------------
272
273      void CXIOSManager::AddClient(StdString clientName, StdSize nbClient, StdSize nbClientPServer,
274                                   void (*entry_point)(MPI_Comm, MPI_Comm, MPI_Comm))
275      {
276         StdSize nbprocess  = comm::CMPIManager::GetCommSize(comm::CMPIManager::GetCommWorld());
277         StdSize nbprocess_used = CXIOSManager::GetNbClient() + CXIOSManager::GetNbServer();
278
279         if (nbClient < nbClientPServer)
280            ERROR("CXIOSManager::AddClient(...)", 
281                  << "nbClient < nbClientPServer");
282                 
283         if ((nbClient % nbClientPServer) != 0)
284            ERROR("CXIOSManager::AddClient(...)",
285                  << " (nbClient % nbClientPServer) != 0 !");
286                 
287         if ((nbprocess-nbprocess_used) < (nbClient + nbClient/nbClientPServer))
288            ERROR("CXIOSManager::AddClient(...)",
289                  << " Pas assez de processus disponibles !");
290                 
291         if (CXIOSManager::Clients.find(clientName) != CXIOSManager::Clients.end())
292            ERROR("CXIOSManager::AddClient(...)",
293                  << " Un client portant le même nom existe déjà !");
294
295         XIOSClient client = {nbClient, nbClientPServer, entry_point };
296         CXIOSManager::Clients[clientName] = client;
297      }
298
299      //---------------------------------------------------------------
300
301      StdSize CXIOSManager::GetNbClient(void)
302      {
303         switch (CXIOSManager::Type)
304         {
305            case (CLIENT_SERVER):
306            {
307               StdSize retvalue = 0;
308               typedef std::pair<StdString, XIOSClient> StdPairStrClient;
309               xios_map<StdString, XIOSClient>::iterator
310                  iit  = CXIOSManager::Clients.begin(),
311                  eend = CXIOSManager::Clients.end();
312
313               for (;iit != eend; iit++)
314               {
315                  const StdPairStrClient & elem = *iit;
316                  retvalue += CXIOSManager::GetNbLocClient(elem.first);
317               }
318               
319               return (retvalue);
320            }
321            case (CLIENT):
322               return (comm::CMPIManager::GetCommSize(CXIOSManager::Comm_Server));
323            case (SERVER):
324               return (comm::CMPIManager::GetCommSize(CXIOSManager::Comm_Client_Server) - 1);
325            default:
326               return (0);
327         }
328      }
329     
330      //---------------------------------------------------------------
331
332      StdSize CXIOSManager::GetNbLocClient(const StdString & clientName)
333      {
334         switch (CXIOSManager::Type)
335         {
336            case (CLIENT_SERVER):
337               return (CXIOSManager::Clients[clientName].nbClient);
338            case (CLIENT):
339            case (SERVER):
340               return (CXIOSManager::GetNbClient());
341            default:
342               return (0);
343         }
344      }
345
346      //---------------------------------------------------------------
347
348      StdSize CXIOSManager::GetNbServer(void)
349      {
350         switch (CXIOSManager::Type)
351         {
352            case (CLIENT_SERVER):
353            {
354               StdSize retvalue = 0;
355               typedef std::pair<StdString, XIOSClient> StdPairStrClient;             
356
357               xios_map<StdString, XIOSClient>::iterator
358                  iit  = CXIOSManager::Clients.begin(),
359                  eend = CXIOSManager::Clients.end();
360
361               for (;iit != eend; iit++)
362               {
363                  const StdPairStrClient & elem = *iit;
364                  retvalue += CXIOSManager::GetNbLocServer(elem.first);
365               }                 
366                 
367               return (retvalue);
368            }
369            case (CLIENT):
370               return (comm::CMPIManager::GetCommSize(CXIOSManager::Comm_Server));
371            case (SERVER):
372               return (1);
373            default:
374               return (0);
375         }
376      }
377
378      //---------------------------------------------------------------
379
380      StdSize CXIOSManager::GetNbLocServer(const StdString & clientName)
381      {
382         switch (CXIOSManager::Type)
383         {
384            case (CLIENT_SERVER):
385               return (CXIOSManager::Clients[clientName].nbClient /
386                       CXIOSManager::Clients[clientName].nbClientPServer);
387            case (CLIENT):
388            case (SERVER):
389               return (CXIOSManager::GetNbServer());
390            default:
391               return (0);
392         }
393      }
394     
395      //---------------------------------------------------------------
396     
397      CXIOSManager::XIOSType   CXIOSManager::GetType(void)
398      {
399         return (CXIOSManager::Type);
400      }
401     
402      //---------------------------------------------------------------
403     
404      CXIOSManager::XIOSStatus CXIOSManager::GetStatus(void)
405      {
406         return (CXIOSManager::Status);
407      }
408     
409      //---------------------------------------------------------------
410     
411      StdString  CXIOSManager::GetClientName(void)
412      {
413         return (CXIOSManager::ClientName);
414      }
415
416      ///--------------------------------------------------------------
417
418} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.