Salome HOME
A patch from Paul RASCLE for: kernel documentation with doxygen, modification on...
[modules/kernel.git] / src / Batch / BatchLight_BatchManager.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 /*
21  * BatchManager.cxx : 
22  *
23  * Auteur : Bernard SECHER - CEA/DEN
24  * Date   : Juillet 2007
25  * Projet : SALOME
26  *
27  */
28
29 #include <iostream>
30 #include <sstream>
31 #include <string>
32 #include <netdb.h>
33 #include "BatchLight_Job.hxx"
34 #include "BatchLight_BatchManager.hxx"
35 #include "Batch_Date.hxx"
36 using namespace std;
37
38 namespace BatchLight {
39
40   // Constructeur
41   BatchManager::BatchManager(const batchParams& p) throw(SALOME_Exception) : _params(p)
42   {
43     SCRUTE(_params.hostname);
44     SCRUTE(_params.protocol);
45     SCRUTE(_params.username);
46     // On verifie que le hostname est correct
47     if (!gethostbyname(_params.hostname.c_str())) { // hostname unknown from network
48       string msg = "hostname \"";
49       msg += _params.hostname;
50       msg += "\" unknown from the network";
51       throw SALOME_Exception(msg.c_str());
52     }
53     _mpiImpl = NULL;
54   }
55
56   // Destructeur
57   BatchManager::~BatchManager()
58   {
59     MESSAGE("BatchManager destructor "<<_params.hostname);
60     std::map < int, const BatchLight::Job * >::const_iterator it;
61     for(it=_jobmap.begin();it!=_jobmap.end();it++)
62       delete it->second; 
63     if(_mpiImpl) delete _mpiImpl;
64   }
65
66   // Methode pour le controle des jobs : soumet un job au gestionnaire
67   const int BatchManager::submitJob(Job* job)
68   {
69     BEGIN_OF("BatchManager::submitJob");
70     int id;
71
72     // temporary directory on cluster to put input files for job
73     setDirForTmpFiles();
74     SCRUTE(_dirForTmpFiles);
75
76     // export input files on cluster
77     exportInputFiles(job->getFileToExecute(),job->getFilesToExportList());
78
79     // build salome coupling script for job
80     buildSalomeCouplingScript(job->getFileToExecute());
81
82     // build batch script for job
83     buildSalomeBatchScript(job->getNbProc());
84
85     // submit job on cluster
86     id = submit();
87
88     // register job on map
89     _jobmap[id] = job;
90     END_OF("BatchManager::submitJob");
91     return id;
92   }
93
94   void BatchManager::setDirForTmpFiles()
95   {
96     int i;
97
98     _dirForTmpFiles = string("Batch/");
99     Batch::Date date = Batch::Date(time(0)) ;
100     std::string thedate = date.str() ;
101     int lend = thedate.size() ;
102     i = 0 ;
103     while ( i < lend ) {
104       if ( thedate[i] == '/' || thedate[i] == '-' || thedate[i] == ':' ) {
105         thedate[i] = '_' ;
106       }
107       i++ ;
108     }
109     _dirForTmpFiles += thedate ;
110   }
111
112   void BatchManager::exportInputFiles(const char *fileToExecute, const Engines::FilesList filesToExportList) throw(SALOME_Exception)
113   {
114     BEGIN_OF("BatchManager::exportInFiles");
115     string command = _params.protocol;
116     int status;
117
118     command += " ";
119
120     if (_params.username != ""){
121       command += _params.username;
122       command += "@";
123     }
124
125     command += _params.hostname;
126     command += " \"mkdir -p ";
127     command += _dirForTmpFiles ;
128     command += "\"" ;
129     SCRUTE(command.c_str());
130     status = system(command.c_str());
131     if(status)
132       throw SALOME_Exception("Error of connection on remote host");    
133
134     if( _params.protocol == "rsh" )
135       command = "rcp ";
136     else if( _params.protocol == "ssh" )
137       command = "scp ";
138     else
139       throw SALOME_Exception("Unknown protocol");
140
141     command += fileToExecute;
142     command += " ";
143
144     if (_params.username != ""){
145       command += _params.username;
146       command += "@";
147     }
148
149     command += _params.hostname;
150     command += ":";
151     command += _dirForTmpFiles ;
152     SCRUTE(command.c_str());
153     status = system(command.c_str());
154     if(status)
155       throw SALOME_Exception("Error of connection on remote host");    
156     
157     int i ;
158     for ( i = 0 ; i < filesToExportList.length() ; i++ ) {
159       if( _params.protocol == "rsh" )
160         command = "rcp ";
161       else if( _params.protocol == "ssh" )
162         command = "scp ";
163       else
164         throw SALOME_Exception("Unknown protocol");
165       command += filesToExportList[i] ;
166       command += " ";
167       if (_params.username != ""){
168         command += _params.username;
169         command += "@";
170       }
171       command += _params.hostname;
172       command += ":";
173       command += _dirForTmpFiles ;
174       SCRUTE(command.c_str());
175       status = system(command.c_str());
176       if(status)
177         throw SALOME_Exception("Error of connection on remote host");    
178     }
179
180     END_OF("BatchManager::exportInFiles");
181   }
182
183   void BatchManager::importOutputFiles( const char *directory, const CORBA::Long jobId ) throw(SALOME_Exception)
184   {
185     BEGIN_OF("BatchManager::importOutputFiles");
186     string command;
187     int status;
188
189     const BatchLight::Job* myJob = _jobmap[jobId];
190     Engines::FilesList filesToImportList = myJob->getFilesToImportList();
191
192     for ( int i = 0 ; i < filesToImportList.length() ; i++ ) {
193       if( _params.protocol == "rsh" )
194         command = "rcp ";
195       else if( _params.protocol == "ssh" )
196         command = "scp ";
197       else
198         throw SALOME_Exception("Unknown protocol");
199       if (_params.username != ""){
200         command += _params.username;
201         command += "@";
202       }
203       command += _params.hostname;
204       command += ":";
205       command += filesToImportList[i] ;
206       command += " ";
207       command += directory;
208       SCRUTE(command.c_str());
209       status = system(command.c_str());
210       if(status)
211         throw SALOME_Exception("Error of connection on remote host");    
212     }
213
214     END_OF("BatchManager::importOutputFiles");
215   }
216
217   string BatchManager::BuildTemporaryFileName() const
218   {
219     //build more complex file name to support multiple salome session
220     char *temp = new char[19];
221     strcpy(temp, "/tmp/command");
222     strcat(temp, "XXXXXX");
223 #ifndef WNT
224
225     mkstemp(temp);
226 #else
227
228     char aPID[80];
229     itoa(getpid(), aPID, 10);
230     strcat(temp, aPID);
231 #endif
232
233     string command(temp);
234     delete [] temp;
235     command += ".sh";
236     return command;
237   }
238
239   void BatchManager::RmTmpFile()
240   {
241     if (_TmpFileName != ""){
242       string command = "rm ";
243       command += _TmpFileName;
244       char *temp = strdup(command.c_str());
245       int lgthTemp = strlen(temp);
246       temp[lgthTemp - 3] = '*';
247       temp[lgthTemp - 2] = '\0';
248       system(temp);
249       free(temp);
250     }
251   }
252
253   MpiImpl *BatchManager::FactoryMpiImpl(string mpiImpl) throw(SALOME_Exception)
254   {
255     if(mpiImpl == "lam")
256       return new MpiImpl_LAM();
257     else if(mpiImpl == "mpich1")
258       return new MpiImpl_MPICH1();
259     else if(mpiImpl == "mpich2")
260       return new MpiImpl_MPICH2();
261     else if(mpiImpl == "openmpi")
262       return new MpiImpl_OPENMPI();
263     else if(mpiImpl == "indif")
264       throw SALOME_Exception("you must specify a mpi implementation in CatalogResources.xml file");
265     else{
266       ostringstream oss;
267       oss << mpiImpl << " : not yet implemented";
268       throw SALOME_Exception(oss.str().c_str());
269     }
270   }
271
272 }