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

Last change on this file since 219 was 219, checked in by hozdoba, 13 years ago

Préparation nouvelle arborescence

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