Salome HOME
Changed year in copyrights
[tools/libbatch.git] / src / LSF / Batch_Job_LSF.cxx
1 //  Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 /*
23  * Job_LSF.cxx : 
24  *
25  * Auteur : Ivan DUTKA-MALEN - EDF R&D
26  * Mail   : mailto:ivan.dutka-malen@der.edf.fr
27  * Date   : Fri Nov 14 11:00:39 2003
28  * Projet : Salome 2
29  *
30  */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <string>
36 #include <vector>
37
38 #include "Batch_Constants.hxx"
39 #include "Batch_Job_LSF.hxx"
40
41 using namespace std;
42
43 namespace Batch {
44
45
46   // Constructeur
47   Job_LSF::Job_LSF(const Job & job) : _p_submit(0)
48   {
49     Parametre P = job.getParametre();
50     _p_submit = ParametreToSubmitStruct(P);
51   }
52
53
54   // Destructeur
55   Job_LSF::~Job_LSF()
56   {
57     if (_p_submit) {
58       if (_p_submit->jobName)     delete [] _p_submit->jobName;
59       if (_p_submit->queue)       delete [] _p_submit->queue;
60       if (_p_submit->askedHosts) {
61         delete [] *(_p_submit->askedHosts);
62         delete [] _p_submit->askedHosts;
63       }
64       if (_p_submit->resReq)      delete [] _p_submit->resReq;
65       if (_p_submit->hostSpec)    delete [] _p_submit->hostSpec;
66       if (_p_submit->dependCond)  delete [] _p_submit->dependCond;
67       if (_p_submit->timeEvent)   delete [] _p_submit->timeEvent;
68       if (_p_submit->inFile)      delete [] _p_submit->inFile;
69       if (_p_submit->outFile)     delete [] _p_submit->outFile;
70       if (_p_submit->errFile)     delete [] _p_submit->errFile;
71       if (_p_submit->command)     delete [] _p_submit->command;
72       if (_p_submit->newCommand)  delete [] _p_submit->newCommand;
73       if (_p_submit->chkpntDir)   delete [] _p_submit->chkpntDir;
74       if (_p_submit->xf)          delete [] _p_submit->xf;
75       if (_p_submit->preExecCmd)  delete [] _p_submit->preExecCmd;
76       if (_p_submit->mailUser)    delete [] _p_submit->mailUser;
77       if (_p_submit->projectName) delete [] _p_submit->projectName;
78       if (_p_submit->loginShell)  delete [] _p_submit->loginShell;
79       if (_p_submit->exceptList)  delete [] _p_submit->exceptList;
80       delete _p_submit;
81     }
82   }
83
84
85   // Accesseur
86   struct submit * Job_LSF::getSubmitStruct()
87   {
88     return _p_submit;
89   }
90
91
92   char * Job_LSF::string2char(const string & s)
93   {
94     char * ch = new char [s.size() + 1];
95     memset(ch, 0, s.size() + 1);
96     strncat(ch, s.c_str(), s.size());
97     return ch;
98   }
99
100
101   struct submit * Job_LSF::ParametreToSubmitStruct(const Parametre & P)
102   {
103     if (! _p_submit) _p_submit = new struct submit;
104
105     memset( (void *) _p_submit, 0, sizeof(struct submit));
106
107     struct submit & sub = * _p_submit;
108     sub.options  = 0;
109     sub.options2 = 0;
110
111     sub.beginTime = 0; // job can run as soon as possible (default)
112     sub.termTime  = 0; // job can run as long as it wishes (default)
113
114     sub.numProcessors    = 1; // job can run on one single processor (default)
115     sub.maxNumProcessors = 1; // job can run on one single processor (default)
116
117     for(int i = 0; i< LSF_RLIM_NLIMITS; i++) sub.rLimits[i] = DEFAULT_RLIMIT;
118
119     typedef std::vector< struct xFile > XFTAB;
120     XFTAB xf_tab;
121
122     string st_second;
123     for(Parametre::const_iterator it = P.begin(); it != P.end(); it++) {
124       if ( (*it).first == ACCOUNT ) {
125         sub.options |= SUB_PROJECT_NAME;
126         st_second = (*it).second.str();
127         sub.projectName = string2char(st_second);
128
129       } else if ( (*it).first == CHECKPOINT ) {
130         if (static_cast< long >((*it).second))
131           sub.options |= SUB_CHKPNT_PERIOD;
132         else
133           sub.options &= ~ SUB_CHKPNT_PERIOD;
134
135       } else if ( (*it).first == CKPTINTERVAL ) {
136         sub.chkpntPeriod = static_cast< long >((*it).second);
137
138       } else if ( (*it).first == EXECUTABLE ) {
139         st_second = (*it).second.str();
140         sub.command = string2char(st_second);
141
142       } else if ( (*it).first == EXECUTIONHOST ) {
143         sub.options |= SUB_HOST;
144         if (! sub.numAskedHosts) {
145           sub.numAskedHosts = 1;
146           sub.askedHosts = new char* [1];
147         }
148         st_second = (*it).second.str();
149         sub.askedHosts[0] = string2char(st_second);
150
151       } else if ( (*it).first == HOLD ) {
152         if (static_cast< long >((*it).second))
153           sub.options2 |= SUB2_HOLD;
154         else
155           sub.options2 &= ~ SUB2_HOLD;
156
157       } else if ( (*it).first == INFILE ) {
158         Versatile V = (*it).second;
159         Versatile::iterator Vit;
160
161         for(Vit=V.begin(); Vit!=V.end(); Vit++) {
162           CoupleType cpt  = *static_cast< CoupleType * >(*Vit);
163           Couple cp       = cpt;
164           string local    = cp.getLocal();
165           string remote   = cp.getRemote();
166                                         
167           // ATTENTION : les notions de fichier "local" ou "remote" sont inverses de celle de PBS qui a un point de vue serveur et non pas utilisateur
168           if (remote == "stdin"){
169             sub.options |= SUB_IN_FILE;
170             sub.inFile = string2char(local);
171
172           } else {
173             struct xFile xf;
174             strncpy(xf.subFn,  local.c_str(),  MAXFILENAMELEN - 1); xf.subFn[MAXFILENAMELEN - 1]  = 0;
175             strncpy(xf.execFn, remote.c_str(), MAXFILENAMELEN - 1); xf.execFn[MAXFILENAMELEN - 1] = 0;
176             xf.options = XF_OP_SUB2EXEC;
177             xf_tab.push_back(xf);
178           }
179         }
180
181       } else if ( (*it).first == MAIL ) {
182         sub.options |= SUB_MAIL_USER;
183         st_second = (*it).second.str();
184         sub.mailUser = string2char(st_second);
185
186       } else if ( (*it).first == MAXCPUTIME ) {
187         sub.rLimits[LSF_RLIMIT_CPU] = static_cast< long >((*it).second);
188
189       } else if ( (*it).first == MAXDISKSIZE ) {
190         sub.rLimits[LSF_RLIMIT_FSIZE] = static_cast< long >((*it).second);
191
192       } else if ( (*it).first == MAXRAMSIZE ) {
193         sub.rLimits[LSF_RLIMIT_SWAP] = static_cast< long >((*it).second);
194
195       } else if ( (*it).first == MAXWALLTIME ) {
196         sub.rLimits[LSF_RLIMIT_RUN] = static_cast< long >((*it).second);
197
198       } else if ( (*it).first == NAME ) {
199         sub.options |= SUB_JOB_NAME;
200         st_second = (*it).second.str();
201         sub.jobName = string2char(st_second);
202
203       } else if ( (*it).first == NBPROC ) {
204         sub.numProcessors    = static_cast< long >((*it).second);
205         sub.maxNumProcessors = static_cast< long >((*it).second);
206
207       } else if ( (*it).first == OUTFILE ) {
208         Versatile V = (*it).second;
209         Versatile::iterator Vit;
210
211         for(Vit=V.begin(); Vit!=V.end(); Vit++) {
212           CoupleType cpt  = *static_cast< CoupleType * >(*Vit);
213           Couple cp       = cpt;
214           string local    = cp.getLocal();
215           string remote   = cp.getRemote();
216                                         
217           // ATTENTION : les notions de fichier "local" ou "remote" sont inverses de celle de PBS qui a un point de vue serveur et non pas utilisateur
218           if (remote == "stdout"){
219             sub.options |= SUB_OUT_FILE;
220             sub.outFile = string2char(local);
221
222           } else if (remote == "stderr"){
223             sub.options |= SUB_ERR_FILE;
224             sub.errFile = string2char(local);
225
226           } else {
227             struct xFile xf;
228             strncpy(xf.subFn,  local.c_str(),  MAXFILENAMELEN - 1); xf.subFn[MAXFILENAMELEN - 1]  = 0;
229             strncpy(xf.execFn, remote.c_str(), MAXFILENAMELEN - 1); xf.execFn[MAXFILENAMELEN - 1] = 0;
230             xf.options = XF_OP_EXEC2SUB;
231             xf_tab.push_back(xf);
232           }
233         }
234
235
236       } else if ( (*it).first == QUEUE ) {
237         sub.options |= SUB_QUEUE;
238         st_second = (*it).second.str();
239         sub.queue = string2char(st_second);
240
241       } else if ( (*it).first == STARTTIME ) {
242         sub.beginTime = static_cast< long >((*it).second);
243
244       } else if ( (*it).first == TMPDIR ) {
245         // TODO
246
247       } else if ( (*it).first == USER ) {
248         // TODO
249
250       }
251     }
252
253
254     // Transfert de fichiers en entree et sortie
255     sub.options |= SUB_OTHER_FILES;
256     sub.nxf = xf_tab.size();
257     sub.xf = new struct xFile [sub.nxf];
258     int ixf = 0;
259     for(XFTAB::const_iterator it_xf=xf_tab.begin(); it_xf != xf_tab.end(); it_xf++, ixf++)
260       sub.xf[ixf] = *it_xf; // *it_xf == xf_tab[ixf]
261         
262
263     return _p_submit;
264   }
265
266 }