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

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

Préparation nouvelle arborescence

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