]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
Add LSF Batch Manager support to Batch subsystem
authordutka <dutka>
Thu, 13 Jan 2005 14:38:12 +0000 (14:38 +0000)
committerdutka <dutka>
Thu, 13 Jan 2005 14:38:12 +0000 (14:38 +0000)
src/Batch/Batch_BatchManager_LSF.cxx [new file with mode: 0644]
src/Batch/Batch_BatchManager_LSF.hxx [new file with mode: 0644]
src/Batch/Batch_FactBatchManager_LSF.cxx [new file with mode: 0644]
src/Batch/Batch_FactBatchManager_LSF.hxx [new file with mode: 0644]
src/Batch/Batch_JobInfo_LSF.cxx [new file with mode: 0644]
src/Batch/Batch_JobInfo_LSF.hxx [new file with mode: 0644]
src/Batch/Batch_Job_LSF.cxx [new file with mode: 0644]
src/Batch/Batch_Job_LSF.hxx [new file with mode: 0644]
src/Batch/Makefile.in

diff --git a/src/Batch/Batch_BatchManager_LSF.cxx b/src/Batch/Batch_BatchManager_LSF.cxx
new file mode 100644 (file)
index 0000000..76f9074
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * BatchManager_LSF.cxx : 
+ *
+ * Auteur : Ivan DUTKA-MALEN - EDF R&D
+ * Mail   : mailto:ivan.dutka-malen@der.edf.fr
+ * Date   : Thu Nov  6 10:17:22 2003
+ * Projet : Salome 2
+ *
+ */
+
+extern "C" {
+#include <lsf/lsf.h>
+#include <lsf/lsbatch.h>
+}
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "Batch_BatchManager_LSF.hxx"
+
+namespace Batch {
+
+  BatchManager_LSF::BatchManager_LSF(const FactBatchManager * parent, const char * host) throw(InvalidArgumentException,ConnexionFailureException) : BatchManager(parent, host)
+  {
+    // On se connecte au serveur LSF
+    _connect = lsb_init("Salome2 Batch library");
+    if (_connect < 0) { // si erreur
+      char * errmsg = lsb_sysmsg();
+      string msg = "LSF Server on host \"";
+      msg += _hostname;
+      msg += "\" : ";
+      msg += errmsg ? errmsg : "Reason unknown";
+      throw ConnexionFailureException(msg.c_str());
+    }
+  }
+
+  // Destructeur
+  BatchManager_LSF::~BatchManager_LSF()
+  {
+    // Nothing to do
+  }
+
+  // Methode pour le controle des jobs : soumet un job au gestionnaire
+  const JobId BatchManager_LSF::submitJob(const Job & job)
+  {
+    Job_LSF joblsf = job;
+    struct submitReply reply;
+    int ref = lsb_submit(joblsf.getSubmitStruct(),
+                        &reply);
+    if (ref < 0) { // si erreur
+      char * msg = lsb_sysmsg();
+      if (!msg) msg = "unknown";
+      throw APIInternalFailureException(string("LSF submit error. Reason : ") + msg);
+    }
+
+    ostringstream oss;
+    oss << ref;
+    JobId id(this, oss.str());
+    return id;
+  }
+
+  // Methode pour le controle des jobs : retire un job du gestionnaire
+  void BatchManager_LSF::deleteJob(const JobId & jobid)
+  {
+    int ref;
+    istringstream iss(jobid.getReference());
+    iss >> ref;
+    int rc = lsb_deletejob(ref, 0, 0);
+    if (rc < 0) { // si erreur
+      char * msg = lsb_sysmsg();
+      if (!msg) msg = "unknown";
+      throw APIInternalFailureException(string("LSF deljob error. Reason : ") + msg);
+    }
+  }
+   
+  // Methode pour le controle des jobs : suspend un job en file d'attente
+  void BatchManager_LSF::holdJob(const JobId & jobid)
+  {
+   int ref;
+    istringstream iss(jobid.getReference());
+    iss >> ref;
+    int rc = lsb_signaljob(ref, SIGSTOP);
+    if (rc < 0) { // si erreur
+      char * msg = lsb_sysmsg();
+      if (!msg) msg = "unknown";
+      throw APIInternalFailureException(string("LSF signaljob error. Reason : ") + msg);
+    }
+  }
+
+  // Methode pour le controle des jobs : relache un job suspendu
+  void BatchManager_LSF::releaseJob(const JobId & jobid)
+  {
+    int ref;
+    istringstream iss(jobid.getReference());
+    iss >> ref;
+    int rc = lsb_signaljob(ref, SIGCONT);
+    if (rc < 0) { // si erreur
+      char * msg = lsb_sysmsg();
+      if (!msg) msg = "unknown";
+      throw APIInternalFailureException(string("LSF signaljob error. Reason : ") + msg);
+    }
+  }
+
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_LSF::alterJob(const JobId & jobid, const Parametre & param, const Environnement & env)
+  {
+    int ref;
+    istringstream iss(jobid.getReference());
+    iss >> ref;
+
+    Job_LSF joblsf = Job(param, env);
+    struct submitReply reply;
+    ref = lsb_modify(joblsf.getSubmitStruct(),
+                    &reply,
+                    ref);
+    if (ref < 0) { // si erreur
+      ostringstream msg_sst;
+      char * msg = lsb_sysmsg();
+      if (!msg) msg = "unknown";
+      msg_sst << msg << endl;
+//       msg_sst << "BadJobId   = " << (long) reply.badJobId   << endl
+//           << "BadJobName = " << reply.badJobName << endl
+//           << "BadReqIndx = " << reply.badReqIndx << endl;
+      throw APIInternalFailureException(string("LSF modify error. Reason : ") + msg_sst.str());
+    }
+  }
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_LSF::alterJob(const JobId & jobid, const Parametre & param)
+  {
+    alterJob(jobid, param, Environnement());
+  }
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_LSF::alterJob(const JobId & jobid, const Environnement & env)
+  {
+    alterJob(jobid, Parametre(), env);
+  }
+
+
+
+  // Methode pour le controle des jobs : renvoie l'etat du job
+  JobInfo BatchManager_LSF::queryJob(const JobId & jobid)
+  {
+    int id;
+    istringstream iss(jobid.getReference());
+    iss >> id;
+
+    JobInfo_LSF ji = JobInfo_LSF(id);
+
+    return ji;
+  }
+
+
+
+  // Methode pour le controle des jobs : teste si un job est present en machine
+  bool BatchManager_LSF::isRunning(const JobId & jobid)
+  {
+    int id;
+    istringstream iss(jobid.getReference());
+    iss >> id;
+
+    JobInfo_LSF ji = JobInfo_LSF(id);
+
+    return ji.isRunning();
+  }
+
+
+
+}
diff --git a/src/Batch/Batch_BatchManager_LSF.hxx b/src/Batch/Batch_BatchManager_LSF.hxx
new file mode 100644 (file)
index 0000000..9b93c66
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * BatchManager_LSF.hxx : 
+ *
+ * Auteur : Ivan DUTKA-MALEN - EDF R&D
+ * Mail   : mailto:ivan.dutka-malen@der.edf.fr
+ * Date   : Thu Nov  6 10:17:22 2003
+ * Projet : Salome 2
+ *
+ */
+
+#ifndef _BATCHMANAGER_LSF_H_
+#define _BATCHMANAGER_LSF_H_
+
+
+#include "Batch_Job.hxx"
+#include "Batch_Job.hxx"
+#include "Batch_JobId.hxx"
+#include "Batch_JobInfo.hxx"
+#include "Batch_JobInfo_LSF.hxx"
+#include "Batch_Job_LSF.hxx"
+#include "Batch_InvalidArgumentException.hxx"
+#include "Batch_ConnexionFailureException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_NotYetImplementedException.hxx"
+#include "Batch_BatchManager.hxx"
+
+namespace Batch {
+
+  class Job;
+  class JobId;
+  class JobInfo;
+  class FactBatchManager;
+
+  class BatchManager_LSF : public BatchManager
+  {
+  public:
+    // Constructeur et destructeur
+    BatchManager_LSF(const FactBatchManager * parent, const char * host="localhost") throw(InvalidArgumentException,ConnexionFailureException); // connexion a la machine host
+    virtual ~BatchManager_LSF();
+
+    // Recupere le nom du serveur par defaut
+    // static string BatchManager_LSF::getDefaultServer();
+
+    // Methodes pour le controle des jobs
+    virtual const JobId submitJob(const Job & job); // soumet un job au gestionnaire
+    virtual void deleteJob(const JobId & jobid); // retire un job du gestionnaire
+    virtual void holdJob(const JobId & jobid); // suspend un job en file d'attente
+    virtual void releaseJob(const JobId & jobid); // relache un job suspendu
+    virtual void alterJob(const JobId & jobid, const Parametre & param, const Environnement & env); // modifie un job en file d'attente
+    virtual void alterJob(const JobId & jobid, const Parametre & param); // modifie un job en file d'attente
+    virtual void alterJob(const JobId & jobid, const Environnement & env); // modifie un job en file d'attente
+    virtual JobInfo queryJob(const JobId & jobid); // renvoie l'etat du job
+    virtual bool isRunning(const JobId & jobid); // teste si un job est present en machine
+
+    virtual void setParametre(const JobId & jobid, const Parametre & param) { return alterJob(jobid, param); } // modifie un job en file d'attente
+    virtual void setEnvironnement(const JobId & jobid, const Environnement & env) { return alterJob(jobid, env); } // modifie un job en file d'attente
+
+
+  protected:
+    int _connect; // LSF connect id
+
+  private:
+
+#ifdef SWIG
+  public:
+    // Recupere le l'identifiant d'un job deja soumis au BatchManager
+    //virtual const JobId getJobIdByReference(const string & ref) { return BatchManager::getJobIdByReference(ref); }
+    virtual const JobId getJobIdByReference(const char * ref) { return BatchManager::getJobIdByReference(ref); }
+#endif
+
+  };
+
+}
+
+#endif
diff --git a/src/Batch/Batch_FactBatchManager_LSF.cxx b/src/Batch/Batch_FactBatchManager_LSF.cxx
new file mode 100644 (file)
index 0000000..6dada01
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * FactBatchManager_LSF.cxx : 
+ *
+ * Auteur : Ivan DUTKA-MALEN - EDF R&D
+ * Date   : Septembre 2004
+ * Projet : SALOME 2
+ *
+ */
+
+#include <string>
+#include "Batch_BatchManager_LSF.hxx"
+#include "Batch_FactBatchManager_LSF.hxx"
+//#include "utilities.h"
+
+namespace Batch {
+
+  static FactBatchManager_LSF sFBM_LSF;
+
+  // Constructeur
+  FactBatchManager_LSF::FactBatchManager_LSF() : FactBatchManager("LSF")
+  {
+    // Nothing to do
+  }
+
+  // Destructeur
+  FactBatchManager_LSF::~FactBatchManager_LSF()
+  {
+    // Nothing to do
+  }
+
+  // Functor
+  BatchManager * FactBatchManager_LSF::operator() (const char * hostname) const
+  {
+    // MESSAGE("Building new BatchManager_LSF on host '" << hostname << "'");
+    return new BatchManager_LSF(this, hostname);
+  }
+
+
+}
diff --git a/src/Batch/Batch_FactBatchManager_LSF.hxx b/src/Batch/Batch_FactBatchManager_LSF.hxx
new file mode 100644 (file)
index 0000000..de59dba
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * FactBatchManager_LSF.hxx : 
+ *
+ * Auteur : Ivan DUTKA-MALEN - EDF R&D
+ * Date   : Septembre 2004
+ * Projet : SALOME 2
+ *
+ */
+
+#ifndef _FACTBATCHMANAGER_LSF_H_
+#define _FACTBATCHMANAGER_LSF_H_
+
+using namespace std;
+#include <string>
+#include <map>
+#include "Batch_FactBatchManager.hxx"
+
+namespace Batch {
+  
+  class BatchManager_LSF;
+
+  class FactBatchManager_LSF : public FactBatchManager
+  {
+  public:
+    // Constructeur et destructeur
+    FactBatchManager_LSF();
+    virtual ~FactBatchManager_LSF();
+
+    virtual BatchManager * operator() (const char * hostname) const;
+
+  protected:
+
+  private:
+
+  };
+
+}
+
+#endif
diff --git a/src/Batch/Batch_JobInfo_LSF.cxx b/src/Batch/Batch_JobInfo_LSF.cxx
new file mode 100644 (file)
index 0000000..acb1f4b
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * JobInfo_LSF.cxx : 
+ *
+ * Auteur : Ivan DUTKA-MALEN - EDF R&D
+ * Mail   : mailto:ivan.dutka-malen@der.edf.fr
+ * Date   : Fri Nov 21 09:42:06 2003
+ * Projet : Salome 2
+ *
+ */
+
+#include <cstdio>
+#include <sstream>
+#include "Batch_Parametre.hxx"
+#include "Batch_Environnement.hxx"
+#include "Batch_RunTimeException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_JobInfo_LSF.hxx"
+
+namespace Batch {
+
+
+
+  // Constructeurs
+  JobInfo_LSF::JobInfo_LSF(int id) : JobInfo()
+  {
+    struct loadIndexLog * p_ld        = new struct loadIndexLog;
+    struct jobInfoHead  * p_jInfoHead = lsb_openjobinfo_a(id, NULL, NULL, NULL, NULL, ALL_JOB);
+
+    int more = p_jInfoHead->numJobs;
+    if (more != 1) {
+      char * msg = lsb_sysmsg();
+      if (!msg) msg = "unknown";
+      throw APIInternalFailureException(string("LSF lsb_openjobinfo error. Reason : ") + msg);     
+    }
+
+    // on remplit une structure contenant <more> elements
+    struct jobInfoEnt & jobInfo = * lsb_readjobinfo(&more);
+
+
+    // On remplit les membres _param et _env
+    _param[ACCOUNT]          = jobInfo.submit.projectName;
+    _param[CHECKPOINT]       = jobInfo.submit.chkpntPeriod != 0;
+    _param[CKPTINTERVAL]     = jobInfo.submit.chkpntPeriod;
+    _param[CREATIONTIME]     = jobInfo.submitTime;
+    // _param[EGROUP]           = jobInfo.;
+    _param[ELIGIBLETIME]     = jobInfo.reserveTime;
+    _param[ENDTIME]          = jobInfo.endTime;
+    _param[EUSER]            = jobInfo.execUsername;
+    _param[EXECUTABLE]       = jobInfo.submit.command;
+    _param[EXITCODE]         = jobInfo.exitStatus;
+    _param[HOLD]             = jobInfo.status & (JOB_STAT_PSUSP | JOB_STAT_SSUSP | JOB_STAT_USUSP);
+    _param[MAIL]             = jobInfo.submit.mailUser;
+    _param[MAXCPUTIME]       = jobInfo.submit.rLimits[LSF_RLIMIT_CPU];
+    _param[MAXDISKSIZE]      = jobInfo.submit.rLimits[LSF_RLIMIT_FSIZE];
+    _param[MAXRAMSIZE]       = jobInfo.submit.rLimits[LSF_RLIMIT_SWAP];
+    _param[MAXWALLTIME]      = jobInfo.submit.rLimits[LSF_RLIMIT_RUN];
+    _param[MODIFICATIONTIME] = jobInfo.lastEvent;
+    _param[NAME]             = jobInfo.jName;
+    _param[NBPROC]           = jobInfo.submit.numProcessors;
+    _param[PID]              = jobInfo.jobPid;
+    _param[QUEUE]            = jobInfo.submit.queue;
+    _param[QUEUEDTIME]       = jobInfo.submitTime;
+    // _param[SERVER]           = jobInfo.;
+    _param[STARTTIME]        = jobInfo.startTime;
+    _param[TEXT]             = jobInfo.numReasons ? lsb_pendreason(jobInfo.numReasons,
+                                                                  jobInfo.reasonTb, 
+                                                                  p_jInfoHead,
+                                                                  p_ld) : "";
+    // _param[TMPDIR]           = jobInfo.;
+    _param[USEDCPUTIME]      = static_cast<long>(jobInfo.cpuTime);
+    // _param[USEDDISKSIZE]     = jobInfo.;
+    _param[USEDRAMSIZE]      = jobInfo.runRusage.mem;
+    _param[USEDWALLTIME]     = jobInfo.duration * 60L;
+    _param[USER]             = jobInfo.user;
+
+
+    ostringstream oss;
+    int jobid = jobInfo.jobId;
+    oss << jobid;
+    _param[ID] = oss.str();
+
+
+    string hosts, sep;
+    for(int i=0; i < jobInfo.numExHosts; i++, sep="+") {
+      hosts += jobInfo.exHosts[i];
+      hosts += sep;
+    }
+    _param[EXECUTIONHOST]    = hosts;
+
+    ostringstream status;
+
+    if (IS_PEND(jobInfo.status))
+      status << " Job is pending;";
+    if (IS_START(jobInfo.status))
+      status << " Job is started;";
+    if (IS_FINISH(jobInfo.status))
+      status << " Job is finished;";
+    if (IS_SUSP(jobInfo.status))
+      status << " Job is suspended;";
+    if (IS_POST_DONE(jobInfo.status))
+      status << " Job is post-done;";
+    if (IS_POST_ERR(jobInfo.status))
+      status << " Job is post-error;";
+
+    _param[STATE] = status.str();
+    _running = IS_FINISH(jobInfo.status) ? false : true;
+
+
+    if (strlen(jobInfo.submit.inFile))
+      _param[INFILE]  += Couple(jobInfo.submit.inFile, "stdin");
+    if (strlen(jobInfo.submit.outFile))
+      _param[OUTFILE]  += Couple(jobInfo.submit.outFile, "stdout");
+    if (strlen(jobInfo.submit.errFile))
+      _param[OUTFILE]  += Couple(jobInfo.submit.errFile, "stderr");
+
+    for(int i=0; i < jobInfo.submit.nxf; i++) {
+      switch (jobInfo.submit.xf[i].options) {
+      case XF_OP_SUB2EXEC:
+       _param[INFILE]  += Couple(jobInfo.submit.xf[i].subFn, jobInfo.submit.xf[i].execFn);
+       break;
+
+      case XF_OP_EXEC2SUB:
+       _param[OUTFILE] += Couple(jobInfo.submit.xf[i].subFn, jobInfo.submit.xf[i].execFn);
+       break;
+
+      default:
+       break;
+      }
+    }
+
+
+    lsb_closejobinfo();
+    delete p_ld;
+  }
+
+
+
+    // Teste si un job est present en machine
+  bool JobInfo_LSF::isRunning() const
+  {
+    return _running;
+  }
+
+
+  // Destructeur
+  JobInfo_LSF::~JobInfo_LSF()
+  {
+    // Nothing to do
+  }
+
+
+  
+  // Convertit une date HH:MM:SS en secondes
+  long JobInfo_LSF::HMStoLong(const string & s)
+  {
+    long hour, min, sec;
+
+    sscanf( s.c_str(), "%ld:%ld:%ld", &hour, &min, &sec);
+    return ( ( ( hour * 60L ) + min ) * 60L ) + sec;
+  }
+
+  // Methode pour l'interfacage avec Python (SWIG) : affichage en Python
+  string JobInfo_LSF::__str__() const
+  {
+    ostringstream sst;
+    sst << "<JobInfo_LSF (" << this << ") :" << endl;
+    sst << " ID = " <<_param[ID] << endl;
+
+    sst << "  + Parametre :" << endl;
+    Parametre::const_iterator itp;
+    for(itp=_param.begin(); itp!=_param.end(); itp++) {
+      if ( (*itp).first != ID ) {
+       sst << "    * " << (*itp).first << " = " << (*itp).second << endl;
+      }
+    }
+    return sst.str();
+  }
+
+
+}
diff --git a/src/Batch/Batch_JobInfo_LSF.hxx b/src/Batch/Batch_JobInfo_LSF.hxx
new file mode 100644 (file)
index 0000000..60fa05f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * JobInfo_LSF.hxx : 
+ *
+ * Auteur : Ivan DUTKA-MALEN - EDF R&D
+ * Mail   : mailto:ivan.dutka-malen@der.edf.fr
+ * Date   : Fri Nov 21 09:42:05 2003
+ * Projet : Salome 2
+ *
+ */
+
+#ifndef _JOBINFO_LSF_H_
+#define _JOBINFO_LSF_H_
+
+extern "C" {
+
+#include <lsf/lsf.h>
+#include <lsf/lsbatch.h>
+}
+#include <string>
+#include "Batch_RunTimeException.hxx"
+#include "Batch_JobInfo.hxx"
+
+namespace Batch {
+
+  class JobInfo_LSF : public JobInfo
+  {
+  public:
+    // Constructeurs et destructeur
+    JobInfo_LSF() : _running(false) {};
+    JobInfo_LSF(int id);
+    virtual ~JobInfo_LSF();
+
+    // Constructeur par recopie
+    JobInfo_LSF(const JobInfo_LSF & jinfo) : JobInfo(jinfo) {};
+
+    // Teste si un job est present en machine
+    virtual bool isRunning() const;
+
+    // Methodes pour l'interfacage avec Python (SWIG)
+    // TODO : supprimer ces methodes et transferer leur definitions dans SWIG
+    string  __str__() const; // SWIG : affichage en Python
+    string  __repr__() const { return __str__(); }; // SWIG : affichage en Python
+
+  protected:
+    bool _running; // etat du job en machine
+
+  private:
+    // Convertit une date HH:MM:SS en secondes
+    long HMStoLong(const string &);
+
+  };
+
+}
+
+#endif
diff --git a/src/Batch/Batch_Job_LSF.cxx b/src/Batch/Batch_Job_LSF.cxx
new file mode 100644 (file)
index 0000000..9146614
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Job_LSF.cxx : 
+ *
+ * Auteur : Ivan DUTKA-MALEN - EDF R&D
+ * Mail   : mailto:ivan.dutka-malen@der.edf.fr
+ * Date   : Fri Nov 14 11:00:39 2003
+ * Projet : Salome 2
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <vector>
+#include "Batch_Job_LSF.hxx"
+
+namespace Batch {
+
+
+  // Constructeur
+  Job_LSF::Job_LSF(const Job & job) : _p_submit(0)
+  {
+    Parametre P = job.getParametre();
+    _p_submit = ParametreToSubmitStruct(P);
+  }
+
+
+  // Destructeur
+  Job_LSF::~Job_LSF()
+  {
+    if (_p_submit) {
+      if (_p_submit->jobName)     delete [] _p_submit->jobName;
+      if (_p_submit->queue)       delete [] _p_submit->queue;
+      if (_p_submit->askedHosts) {
+       delete [] *(_p_submit->askedHosts);
+       delete [] _p_submit->askedHosts;
+      }
+      if (_p_submit->resReq)      delete [] _p_submit->resReq;
+      if (_p_submit->hostSpec)    delete [] _p_submit->hostSpec;
+      if (_p_submit->dependCond)  delete [] _p_submit->dependCond;
+      if (_p_submit->timeEvent)   delete [] _p_submit->timeEvent;
+      if (_p_submit->inFile)      delete [] _p_submit->inFile;
+      if (_p_submit->outFile)     delete [] _p_submit->outFile;
+      if (_p_submit->errFile)     delete [] _p_submit->errFile;
+      if (_p_submit->command)     delete [] _p_submit->command;
+      if (_p_submit->newCommand)  delete [] _p_submit->newCommand;
+      if (_p_submit->chkpntDir)   delete [] _p_submit->chkpntDir;
+      if (_p_submit->xf)          delete [] _p_submit->xf;
+      if (_p_submit->preExecCmd)  delete [] _p_submit->preExecCmd;
+      if (_p_submit->mailUser)    delete [] _p_submit->mailUser;
+      if (_p_submit->projectName) delete [] _p_submit->projectName;
+      if (_p_submit->loginShell)  delete [] _p_submit->loginShell;
+      if (_p_submit->exceptList)  delete [] _p_submit->exceptList;
+      delete _p_submit;
+    }
+  }
+
+
+  // Accesseur
+  struct submit * Job_LSF::getSubmitStruct()
+  {
+    return _p_submit;
+  }
+
+
+  char * Job_LSF::string2char(const string & s)
+  {
+    char * ch = new char [s.size() + 1];
+    memset(ch, 0, s.size() + 1);
+    strncat(ch, s.c_str(), s.size());
+    return ch;
+  }
+
+
+  struct submit * Job_LSF::ParametreToSubmitStruct(const Parametre & P)
+  {
+    if (! _p_submit) _p_submit = new struct submit;
+
+    memset( (void *) _p_submit, 0, sizeof(struct submit));
+
+    struct submit & sub = * _p_submit;
+    sub.options  = 0;
+    sub.options2 = 0;
+
+    sub.beginTime = 0; // job can run as soon as possible (default)
+    sub.termTime  = 0; // job can run as long as it wishes (default)
+
+    sub.numProcessors    = 1; // job can run on one single processor (default)
+    sub.maxNumProcessors = 1; // job can run on one single processor (default)
+
+    for(int i = 0; i< LSF_RLIM_NLIMITS; i++) sub.rLimits[i] = DEFAULT_RLIMIT;
+
+    typedef std::vector< struct xFile > XFTAB;
+    XFTAB xf_tab;
+
+    string st_second;
+    for(Parametre::const_iterator it = P.begin(); it != P.end(); it++) {
+      if ( (*it).first == ACCOUNT ) {
+       sub.options |= SUB_PROJECT_NAME;
+       st_second = (*it).second.str();
+       sub.projectName = string2char(st_second);
+
+      } else if ( (*it).first == CHECKPOINT ) {
+       if (static_cast< long >((*it).second))
+         sub.options |= SUB_CHKPNT_PERIOD;
+       else
+         sub.options &= ~ SUB_CHKPNT_PERIOD;
+
+      } else if ( (*it).first == CKPTINTERVAL ) {
+       sub.chkpntPeriod = static_cast< long >((*it).second);
+
+      } else if ( (*it).first == EXECUTABLE ) {
+       st_second = (*it).second.str();
+       sub.command = string2char(st_second);
+
+      } else if ( (*it).first == EXECUTIONHOST ) {
+       sub.options |= SUB_HOST;
+       if (! sub.numAskedHosts) {
+         sub.numAskedHosts = 1;
+         sub.askedHosts = new char* [1];
+       }
+       st_second = (*it).second.str();
+       sub.askedHosts[0] = string2char(st_second);
+
+      } else if ( (*it).first == HOLD ) {
+       if (static_cast< long >((*it).second))
+         sub.options2 |= SUB2_HOLD;
+       else
+         sub.options2 &= ~ SUB2_HOLD;
+
+      } else if ( (*it).first == INFILE ) {
+       Versatile V = (*it).second;
+       Versatile::iterator Vit;
+
+       for(Vit=V.begin(); Vit!=V.end(); Vit++) {
+         CoupleType cpt  = *static_cast< CoupleType * >(*Vit);
+         Couple cp       = cpt;
+         string local    = cp.getLocal();
+         string remote   = cp.getRemote();
+                                       
+         // 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
+         if (remote == "stdin"){
+           sub.options |= SUB_IN_FILE;
+           sub.inFile = string2char(local);
+
+         } else {
+           struct xFile xf;
+           strncpy(xf.subFn,  local.c_str(),  MAXFILENAMELEN); xf.subFn[MAXFILENAMELEN]  = 0;
+           strncpy(xf.execFn, remote.c_str(), MAXFILENAMELEN); xf.execFn[MAXFILENAMELEN] = 0;
+           xf.options = XF_OP_SUB2EXEC;
+           xf_tab.push_back(xf);
+         }
+       }
+
+      } else if ( (*it).first == MAIL ) {
+       sub.options |= SUB_MAIL_USER;
+       st_second = (*it).second.str();
+       sub.mailUser = string2char(st_second);
+
+      } else if ( (*it).first == MAXCPUTIME ) {
+       sub.rLimits[LSF_RLIMIT_CPU] = static_cast< long >((*it).second);
+
+      } else if ( (*it).first == MAXDISKSIZE ) {
+       sub.rLimits[LSF_RLIMIT_FSIZE] = static_cast< long >((*it).second);
+
+      } else if ( (*it).first == MAXRAMSIZE ) {
+       sub.rLimits[LSF_RLIMIT_SWAP] = static_cast< long >((*it).second);
+
+      } else if ( (*it).first == MAXWALLTIME ) {
+       sub.rLimits[LSF_RLIMIT_RUN] = static_cast< long >((*it).second);
+
+      } else if ( (*it).first == NAME ) {
+       sub.options |= SUB_JOB_NAME;
+       st_second = (*it).second.str();
+       sub.jobName = string2char(st_second);
+
+      } else if ( (*it).first == NBPROC ) {
+       sub.numProcessors    = static_cast< long >((*it).second);
+       sub.maxNumProcessors = static_cast< long >((*it).second);
+
+      } else if ( (*it).first == OUTFILE ) {
+       Versatile V = (*it).second;
+       Versatile::iterator Vit;
+
+       for(Vit=V.begin(); Vit!=V.end(); Vit++) {
+         CoupleType cpt  = *static_cast< CoupleType * >(*Vit);
+         Couple cp       = cpt;
+         string local    = cp.getLocal();
+         string remote   = cp.getRemote();
+                                       
+         // 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
+         if (remote == "stdout"){
+           sub.options |= SUB_OUT_FILE;
+           sub.outFile = string2char(local);
+
+         } else if (remote == "stderr"){
+           sub.options |= SUB_ERR_FILE;
+           sub.errFile = string2char(local);
+
+         } else {
+           struct xFile xf;
+           strncpy(xf.subFn,  local.c_str(),  MAXFILENAMELEN); xf.subFn[MAXFILENAMELEN]  = 0;
+           strncpy(xf.execFn, remote.c_str(), MAXFILENAMELEN); xf.execFn[MAXFILENAMELEN] = 0;
+           xf.options = XF_OP_EXEC2SUB;
+           xf_tab.push_back(xf);
+         }
+       }
+
+
+      } else if ( (*it).first == QUEUE ) {
+       sub.options |= SUB_QUEUE;
+       st_second = (*it).second.str();
+       sub.queue = string2char(st_second);
+
+      } else if ( (*it).first == STARTTIME ) {
+       sub.beginTime = static_cast< long >((*it).second);
+
+      } else if ( (*it).first == TMPDIR ) {
+       // TODO
+
+      } else if ( (*it).first == USER ) {
+       // TODO
+
+      }
+    }
+
+
+    // Transfert de fichiers en entree et sortie
+    sub.options |= SUB_OTHER_FILES;
+    sub.nxf = xf_tab.size();
+    sub.xf = new struct xFile [sub.nxf];
+    int ixf = 0;
+    for(XFTAB::const_iterator it_xf=xf_tab.begin(); it_xf != xf_tab.end(); it_xf++, ixf++)
+      sub.xf[ixf] = *it_xf; // *it_xf == xf_tab[ixf]
+       
+
+    return _p_submit;
+  }
+
+}
diff --git a/src/Batch/Batch_Job_LSF.hxx b/src/Batch/Batch_Job_LSF.hxx
new file mode 100644 (file)
index 0000000..d10d7f2
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Job_LSF.hxx : 
+ *
+ * Auteur : Ivan DUTKA-MALEN - EDF R&D
+ * Mail   : mailto:ivan.dutka-malen@der.edf.fr
+ * Date   : Fri Nov 14 11:00:39 2003
+ * Projet : Salome 2
+ *
+ */
+
+#ifndef _JOB_LSF_H_
+#define _JOB_LSF_H_
+
+extern "C" {
+
+#include <lsf/lsf.h>
+#include <lsf/lsbatch.h>
+}
+#include "Batch_Job.hxx"
+
+namespace Batch {
+
+  class Job_LSF
+  {
+  public:
+    // Constructeur et destructeur
+    Job_LSF(const Job & job);
+    virtual ~Job_LSF();
+
+    // Accesseurs
+    struct submit * getSubmitStruct();
+
+  protected:
+    struct submit * _p_submit; // structure pour soumettre les jobs
+
+  private:
+    struct submit * ParametreToSubmitStruct(const Parametre & P);
+    char * string2char(const string &);
+  };
+
+}
+
+#endif
index 703e6c7e15fae87e857bcbeb60b230454a4c796b..6b83960e3c7b60ae5c244e2514997ec3b166752a 100644 (file)
@@ -66,13 +66,6 @@ EXPORT_HEADERS = \
        Batch_TypeMismatchException.hxx \
        Batch_Versatile.hxx
 
-# Specialisation pour OpenPBS
-EXPORT_HEADERS += \
-       Batch_BatchManager_PBS.hxx \
-       Batch_FactBatchManager_PBS.hxx \
-       Batch_JobInfo_PBS.hxx \
-       Batch_Job_PBS.hxx
-
 
 # Libraries targets
 
@@ -109,22 +102,58 @@ LIB_SRC = \
        Batch_TypeMismatchException.cxx \
        Batch_Versatile.cxx
 
+LIB_SERVER_IDL = 
+
+
+CPPFLAGS += $(PYTHON_INCLUDES)
+CXXFLAGS += $(PYTHON_INCLUDES)
+LDFLAGS  += 
+LIBS     += -lSALOMELocalTrace
+
+
+
 # Specialisation pour OpenPBS
+ifeq (@WITHOPENPBS@,yes)
+EXPORT_HEADERS += \
+       Batch_BatchManager_PBS.hxx \
+       Batch_FactBatchManager_PBS.hxx \
+       Batch_JobInfo_PBS.hxx \
+       Batch_Job_PBS.hxx
+
 LIB_SRC += \
        Batch_BatchManager_PBS.cxx \
        Batch_FactBatchManager_PBS.cxx \
        Batch_JobInfo_PBS.cxx \
        Batch_Job_PBS.cxx
 
-LIB_SERVER_IDL = 
+CPPFLAGS += $(OPENPBS_INCLUDES)
+CXXFLAGS += $(OPENPBS_INCLUDES)
+LDFLAGS  += $(OPENPBS_LIBDIR)
+LIBS     += $(OPENPBS_LIBS)
+endif
+
 
 
-CPPFLAGS += $(PYTHON_INCLUDES) $(OPENPBS_INCLUDES)
 
-CXXFLAGS += $(PYTHON_INCLUDES) $(OPENPBS_INCLUDES)
+# Specialisation pour LSF
+ifeq (@WITH_LSF@,yes)
+EXPORT_HEADERS += \
+       Batch_BatchManager_LSF.hxx \
+       Batch_FactBatchManager_LSF.hxx \
+       Batch_JobInfo_LSF.hxx \
+       Batch_Job_LSF.hxx
+
+LIB_SRC += \
+       Batch_BatchManager_LSF.cxx \
+       Batch_FactBatchManager_LSF.cxx \
+       Batch_JobInfo_LSF.cxx \
+       Batch_Job_LSF.cxx
 
-LDFLAGS += $(OPENPBS_LIBDIR)
+CPPFLAGS += $(LSF_INCLUDES)
+CXXFLAGS += $(LSF_INCLUDES)
+LDFLAGS  += $(LSF_LIBDIR)
+LIBS     += $(LSF_LIBS)
+endif
 
-LIBS += $(OPENPBS_LIBS) -lSALOMELocalTrace
 
 @CONCLUDE@