Salome HOME
PR: mergefrom_BSEC_br1_14Mar04
[modules/kernel.git] / src / MPILifeCycleCORBA / SALOME_MPILifeCycleCORBA.cxx
1 //=============================================================================
2 // File      : SALOME_MPILifeCycleCORBA.cxx
3 // Created   : mar jui 03 14:55:50 CEST 2003
4 // Author    : Bernard SECHER CEA
5 // Project   : SALOME
6 // Copyright : CEA 2003
7 // $Header$
8 //=============================================================================
9
10 #include <iostream>
11 #include <fstream>
12 #include <strstream>
13 #include <iomanip>
14 #include <stdio.h>
15 #include <string.h>
16
17 #include "OpUtil.hxx"
18 #include "utilities.h"
19
20 #include <ServiceUnreachable.hxx>
21
22 #include "SALOME_MPILifeCycleCORBA.hxx"
23 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
24 #include "SALOME_NamingService.hxx"
25 using namespace std;
26
27 SALOME_MPILifeCycleCORBA::SALOME_MPILifeCycleCORBA() : 
28   SALOME_LifeCycleCORBA()
29 {
30   _MPIFactoryServer = NULL;
31 }
32
33 SALOME_MPILifeCycleCORBA::SALOME_MPILifeCycleCORBA(SALOME_NamingService *ns) :
34   SALOME_LifeCycleCORBA(ns)
35 {
36   _MPIFactoryServer = NULL;
37 }
38
39 SALOME_MPILifeCycleCORBA::~SALOME_MPILifeCycleCORBA()
40 {
41 }
42
43 Engines::MPIContainer_var SALOME_MPILifeCycleCORBA::FindOrStartMPIContainer(
44                                               const string theComputer ,
45                                               const string theMPIContainerRoot,
46                                               const int nbproc)
47 {
48   char nbp[1024];
49
50   sprintf(nbp,"_%d",nbproc);
51   string theMPIContainer = theMPIContainerRoot + nbp; 
52   string aComputerContainer = theComputer + "/" + theMPIContainer;
53
54   SCRUTE( aComputerContainer ) ;
55   SCRUTE( theComputer ) ;
56   SCRUTE( theMPIContainer ) ;
57
58   // On recherche si le containe rest deja lance
59   Engines::MPIContainer_var aMPIContainer = Engines::MPIContainer::_narrow(FindContainer(aComputerContainer.c_str()));
60
61   //On a trouve le container: on renvoie une poigne dessus
62   if ( !CORBA::is_nil( aMPIContainer ) ) {
63     MESSAGE("MPIContainer " << aComputerContainer << " found!!!");
64     return aMPIContainer ;
65   }
66   // On a pas trouve le container
67   else {
68     MESSAGE("MPIContainer " << aComputerContainer << " not found!!!");
69     // On recherche un container generique
70     bool pyCont = false ;
71     int len = theMPIContainer.length() ;
72     if ( !strcmp( &theMPIContainerRoot.c_str()[len-2] , "Py" ) ) {
73       pyCont = true ;
74     }
75     string MPIFactoryServer = theComputer ;
76     if ( pyCont ) {
77       MPIFactoryServer += "/MPIFactoryServerPy" ;
78     }
79     else {
80       MPIFactoryServer += "/MPIFactoryServer" ;
81     }
82     MPIFactoryServer += nbp;
83     Engines::MPIContainer_var aMPIFactoryServer = Engines::MPIContainer::_narrow(FindContainer( MPIFactoryServer.c_str()));
84
85     // On n'a pas trouve le container generique: on lance le container demande
86     if ( CORBA::is_nil( aMPIFactoryServer ) ) {
87 // rsh -n ikkyo /export/home/rahuel/SALOME_ROOT/bin/runSession SALOME_Container -ORBInitRef NameService=corbaname::dm2s0017:1515 &
88       string rsh( "" ) ;
89       if ( theComputer!= GetHostname() ) {
90         rsh += "rsh -n " ;
91         rsh += theComputer ;
92         rsh += " " ;
93       }
94       string path = ComputerPath( theComputer.c_str() ) ;
95       SCRUTE( path ) ;
96       //      rsh += "runSession " ;
97       if ( pyCont ) {
98         MESSAGE("MPI python container not implemented");
99         return Engines::MPIContainer::_nil();
100 //         rsh += "SALOME_MPIContainerPy.py " ;
101 //         rsh += "MPIFactoryServerPy -" ;
102       }
103       else {
104         sprintf(nbp,"mpirun -np %d %sSALOME_MPIContainer ",nbproc,path.c_str());
105         rsh += nbp;
106         rsh += theMPIContainer +" -" ;
107       }
108       string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ;
109       ifstream omniORBfile( omniORBcfg.c_str() ) ;
110       char ORBInitRef[12] ;
111       char nameservice[132] ;
112       omniORBfile >> ORBInitRef ;
113       rsh += ORBInitRef ;
114       rsh += " " ;
115       omniORBfile >> nameservice ;
116       omniORBfile.close() ;
117       char * bsn = strchr( nameservice , '\n' ) ;
118       if ( bsn ) {
119         bsn[ 0 ] = '\0' ;
120       }
121       rsh += nameservice ;
122       if ( pyCont ) {
123         rsh += " > /tmp/MPIFactoryServerPy_" ;
124       }
125       else {
126         rsh += " > /tmp/MPIFactoryServer_" ;
127       }
128       sprintf(nbp,"%d_",nbproc);
129       rsh += nbp;
130       rsh += theComputer ;
131       rsh += ".log 2>&1 &" ;
132       SCRUTE( rsh );
133       int status = system( rsh.c_str() ) ;
134       if (status == -1) {
135         INFOS("SALOME_MPILifeCycleCORBA::FindOrStartMPIContainer rsh failed (system command status -1)") ;
136       }
137       else if (status == 217) {
138         INFOS("SALOME_MPILifeCycleCORBA::FindOrStartContainer rsh failed (system command status 217)") ;
139       }
140       else {
141         int count = 21 ;
142         while ( CORBA::is_nil( aMPIFactoryServer ) && count ) {
143           sleep( 1 ) ;
144           count-- ;
145           if ( count != 10 )
146             MESSAGE( count << ". Waiting for FactoryServer on " << theComputer)
147           aMPIFactoryServer = Engines::MPIContainer::_narrow(FindContainer( MPIFactoryServer.c_str()));
148         }
149         if ( CORBA::is_nil( aMPIFactoryServer ) ) {
150           INFOS("SALOME_MPILifeCycleCORBA::FindOrStartMPIContainer rsh failed") ;
151         }
152         else if ( strcmp( theComputer.c_str() , GetHostname().c_str() ) ) {
153           _MPIFactoryServer = aMPIFactoryServer ;
154         }
155       }
156     }
157     // On a trouve le container generique distant: on se sert de lui
158     // pour lancer un nouveau container MPI
159     // a revoir...
160     if ( !CORBA::is_nil( aMPIFactoryServer ) ) {
161       if ( strcmp( theMPIContainer.c_str() , "MPIFactoryServer" ) ||
162            strcmp( theMPIContainer.c_str() , "MPIFactoryServerPy" ) ) {
163         MESSAGE("MPI Container not found ! trying to start " << aComputerContainer);
164         Engines::MPIContainer_var myMPIContainer = aMPIFactoryServer->start_MPIimpl( theMPIContainer.c_str(), nbproc ) ;
165         if ( !CORBA::is_nil( myMPIContainer ) ) {
166           MESSAGE("MPIContainer " << aComputerContainer << " started");
167           return myMPIContainer ;
168         }
169         else {
170           MESSAGE("MPIContainer " << aComputerContainer << " NOT started");
171         }
172       }
173       else {
174         MESSAGE("MPIContainer " << aComputerContainer << " started");
175         return aMPIFactoryServer ;
176       }
177     }
178   }
179   return Engines::MPIContainer::_nil();
180 }
181
182 // Engines::Component_var SALOME_MPILifeCycleCORBA::FindOrLoad_MPIComponent
183 //                                    (const char *MPIcontainerName,
184 //                                  const char *MPIcomponentName,
185 //                                  const char *implementation,
186 //                                  const int nbproc)
187 // {
188 //   BEGIN_OF("FindOrLoad_MPIComponent(1)");
189 //   ASSERT(_NS != NULL);
190 //   string theComputer ;
191 //   string theMPIContainer ;
192 //   string theComputerContainer = ContainerName( MPIcontainerName ,
193 //                                                &theComputer ,
194 //                                                &theMPIContainer ) ;
195 //   Engines::MPIContainer_var cont = FindOrStartMPIContainer( theComputerContainer ,
196 //                                                          theComputer ,
197 //                                                          theMPIContainer,
198 //                                                          nbproc) ;
199 // //  ASSERT(!CORBA::is_nil(cont));
200
201 //   string path( theComputerContainer );
202 //   path = path + "/";
203 //   path = path + MPIcomponentName;
204 //   SCRUTE(path);
205 //   try
206 //     {
207 //       CORBA::Object_var obj = _NS->Resolve(path.c_str());
208 //       if (CORBA::is_nil(obj))
209 //      {
210 //        MESSAGE("MPIComponent not found ! trying to load " << path);
211 //        Engines::Component_var compo 
212 //          = cont->load_impl(MPIcomponentName, implementation);
213 // //     ASSERT(!CORBA::is_nil(compo));
214 //        MESSAGE("MPIComponent launched !" << path);
215 //        return compo;
216 //      }
217 //       else
218 //      {
219 //        MESSAGE("MPIComponent found !" << path);
220 //        Engines::Component_var compo = Engines::Component::_narrow(obj);
221 // //     ASSERT(!CORBA::is_nil(compo));
222 //        try
223 //          {
224 //            compo->ping(); 
225 //          }
226 //        catch (CORBA::COMM_FAILURE&)
227 //          {
228 //            INFOS("Caught CORBA::SystemException CommFailure. Engine "
229 //                  << path << "does not respond" );
230 //          }
231 //        return compo;
232 //      }
233 //     }
234 //   catch (ServiceUnreachable&)
235 //     {
236 //       INFOS("Caught exception: Naming Service Unreachable");
237 //     }
238 //   catch (...)
239 //     {
240 //       INFOS("Caught unknown exception.");
241 //     }
242 //   return Engines::Component::_nil();
243 // }
244
245 Engines::Component_var SALOME_MPILifeCycleCORBA::FindOrLoad_MPIComponent
246                                   (const char *MPIcontainerName,
247                                    const char *MPIcomponentName,
248                                    const int nbproc)
249 {
250
251   char nbp[1024];
252
253   sprintf(nbp,"_%d",nbproc);
254 //  BEGIN_OF("FindOrLoad_Component(2)");
255   ASSERT(_NS != NULL);
256   string theComputer ;
257   string theMPIContainerRoot ;
258   string theMPIContainer;
259   string theComputerContainer = ContainerName( MPIcontainerName ,
260                                                &theComputer ,
261                                                &theMPIContainerRoot ) ;
262   theMPIContainer = theMPIContainerRoot + nbp;
263   Engines::MPIContainer_var cont = FindOrStartMPIContainer( theComputer ,
264                                                             theMPIContainerRoot,
265                                                             nbproc ) ;
266
267   if ( CORBA::is_nil( cont ) ) {
268     MESSAGE("MPIContainer not found ! " << theComputerContainer );
269     return Engines::Component::_nil();
270   }
271
272 //  char * machine = cont->machineName() ;
273   const char * machine = theComputer.c_str() ;
274
275   string path( theComputerContainer );
276   path += nbp;
277   path += "/";
278   path += MPIcomponentName;
279   SCRUTE(path);
280
281   try {
282     CORBA::Object_var obj = _NS->Resolve(path.c_str());
283     if ( CORBA::is_nil( obj ) ) {
284       MESSAGE("MPIComponent not found ! trying to load " << path);
285       CORBA::Object_var obj2 = _NS->Resolve("/Kernel/ModulCatalog");
286       SALOME_ModuleCatalog::ModuleCatalog_var Catalog = 
287         SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj2);
288
289       SALOME_ModuleCatalog::Acomponent_ptr compoInfo = 
290         Catalog->GetComponent(MPIcomponentName);
291       if (CORBA::is_nil (compoInfo)) 
292         {
293           INFOS("Catalog Error : Component not found in the catalog")
294             return Engines::Component::_nil();
295 //              exit (-1);
296         }
297       
298       string  path;
299       try
300         {
301           path = compoInfo->GetPathPrefix( machine ) ;
302           path += "/" ;
303         }
304       catch (SALOME_ModuleCatalog::NotFound&)
305         {
306           MESSAGE("GetPathPrefix(" << machine << ") not found!"
307                   << "trying localhost");
308           try {
309             path = compoInfo->GetPathPrefix("localhost") ;
310             path += "/" ;
311           }
312           catch (SALOME_ModuleCatalog::NotFound&) {
313             MESSAGE("GetPathPrefix(localhost) not found!") ;
314             path = "" ;
315           }
316         }
317       
318       SCRUTE(path); 
319       string implementation(path);
320       implementation += "lib";
321       implementation += MPIcomponentName;
322       implementation += "Engine.so";
323       
324       Engines::Component_var compo 
325         = cont->load_impl(MPIcomponentName, implementation.c_str());
326       
327 //        ASSERT(!CORBA::is_nil(compo));
328 //        MESSAGE("Component launched !" << path);
329       return compo;
330     }
331     else
332       {
333         MESSAGE("MPIComponent found !" << path);
334         Engines::Component_var compo = Engines::Component::_narrow(obj);
335         //        ASSERT(!CORBA::is_nil(compo));
336         try
337           {
338             string instanceName = compo->instanceName(); 
339           }
340         catch (CORBA::COMM_FAILURE&)
341           {
342             INFOS("Caught CORBA::SystemException CommFailure. Engine "
343                   << path << "does not respond" );
344           }
345         return compo;
346       }
347   }
348   catch (ServiceUnreachable&)
349     {
350       INFOS("Caught exception: Naming Service Unreachable");
351     }
352   catch (...)
353     {
354       INFOS("Caught unknown exception.");
355     }
356   return Engines::Component::_nil();
357 }