Salome HOME
Major refactoring in classes Versatile, Parametre and Swig wrappings. V1_4_0rc1
authorbarate <barate>
Fri, 2 Sep 2011 15:50:56 +0000 (15:50 +0000)
committerbarate <barate>
Fri, 2 Sep 2011 15:50:56 +0000 (15:50 +0000)
Add new boolean parameter "EXCLUSIVE".
Implement parameter "EXCLUSIVE" for ePBS, eLSF, eSlurm and eLL.
Some other fixes and improvements.

29 files changed:
src/CCC/Batch_BatchManager_eCCC.cxx
src/Core/Batch_BatchManager_eClient.cxx
src/Core/Batch_Constants.cxx
src/Core/Batch_Constants.hxx
src/Core/Batch_IntType.cxx [deleted file]
src/Core/Batch_IntType.hxx [deleted file]
src/Core/Batch_ParameterTypeMap.cxx
src/Core/Batch_ParameterTypeMap.hxx
src/Core/Batch_Parametre.cxx
src/Core/Batch_Versatile.cxx
src/Core/Batch_Versatile.hxx
src/Core/CMakeLists.txt
src/LSF/Batch_BatchManager_eLSF.cxx
src/LSF/CMakeLists.txt
src/LSF/Test/CMakeLists.txt [new file with mode: 0644]
src/LSF/Test/Test_eLSF.cxx [new file with mode: 0644]
src/LSF/Test/seta.sh [new file with mode: 0644]
src/LSF/Test/setb.sh [new file with mode: 0644]
src/LSF/Test/test-script.sh [new file with mode: 0755]
src/LoadLeveler/Batch_BatchManager_eLL.cxx
src/LoadLeveler/Test/Test_eLL.cxx
src/PBS/Batch_BatchManager_ePBS.cxx
src/PBS/Test/Test_ePBS.cxx
src/Python/Batch_PyVersatile.cxx [deleted file]
src/Python/Batch_PyVersatile.hxx [deleted file]
src/Python/CMakeLists.txt
src/Python/libBatch_Swig_typemap.i
src/Slurm/Batch_BatchManager_eSlurm.cxx
src/Slurm/Test/Test_eSlurm.cxx

index b7337fdb7236b63f751408439f692bfe6c99a118..a52ee88f49d7cd637ea0a999001fefdeff69399a 100644 (file)
@@ -243,7 +243,7 @@ namespace Batch {
     if (params.find(NBPROC) != params.end()) 
       nbproc = params[NBPROC];
     if (params.find(MAXWALLTIME) != params.end()) 
-      edt = params[MAXWALLTIME] * 60;
+      edt = (long)params[MAXWALLTIME] * 60;
     if (params.find(MAXRAMSIZE) != params.end()) 
       mem = params[MAXRAMSIZE];
     if (params.find(QUEUE) != params.end()) 
index 67c7725953d038dbc8c1db467436abc6e5d4e91f..c19c926e6f37b2d381c7715b6a8e795ed734e4c6 100644 (file)
@@ -82,8 +82,8 @@ namespace Batch {
   {
     int status;
     Parametre params = job.getParametre();
-    Versatile V = params[INFILE];
-    Versatile::iterator Vit;
+    const Versatile & V = params[INFILE];
+    Versatile::const_iterator Vit;
 
     status = _protocol.makeDirectory(string(params[TMPDIR]) + "/logs", _hostname, _username);
     if(status) {
@@ -147,8 +147,8 @@ namespace Batch {
   void BatchManager_eClient::importOutputFiles( const Job & job, const string directory )
   {
     Parametre params = job.getParametre();
-    Versatile V = params[OUTFILE];
-    Versatile::iterator Vit;
+    const Versatile & V = params[OUTFILE];
+    Versatile::const_iterator Vit;
 
     // Create local result directory
     int status = CommunicationProtocol::getInstance(SH).makeDirectory(directory, "", "");
index 95b97f2ae3b3d788fcb8e6e72a62adb77089abbe..c5cb22d9675e29102fbaec76dd46f5a8d43b20a4 100644 (file)
@@ -71,6 +71,7 @@ namespace Batch {
   def_Constant(USER);
   def_Constant(WORKDIR);
   def_Constant(HOMEDIR);
+  def_Constant(EXCLUSIVE);
 
   // These constants define the status of a job (parameter STATE);
   def_Constant(CREATED);
index d022fa5afa721842e51a12e38510f27037598594..5e948b1bf9fc018fd274ae0b685b2d4db4c1ab24 100644 (file)
@@ -82,6 +82,7 @@ namespace Batch {
   decl_extern_Constant(USER);
   decl_extern_Constant(WORKDIR);
   decl_extern_Constant(HOMEDIR);
+  decl_extern_Constant(EXCLUSIVE);
 
   // These constants define the status of a job (parameter STATE)
   decl_extern_Constant(CREATED);
diff --git a/src/Core/Batch_IntType.cxx b/src/Core/Batch_IntType.cxx
deleted file mode 100644 (file)
index 01d1c18..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-//  Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-/*
- * IntType.cxx : 
- *
- * Auteur : Ivan DUTKA-MALEN - EDF R&D
- * Date   : Septembre 2003
- * Projet : SALOME 2
- *
- */
-
-#include <string>
-#include <sstream>
-#include <assert.h>
-//#include "MEDMEM_STRING.hxx"
-#include "Batch_IntType.hxx"
-using namespace std;
-
-
-namespace Batch {
-
-       // Conversion en chaine
-  string IntType::affiche() const
-  {
-    //MEDMEM::STRING sst;
-    ostringstream sst;
-    sst << _data;
-    return sst.str();
-  }
-
-       // Operateur d'affectation
-  IntType & IntType::operator =(int i)
-  {
-    _data = i;
-    return *this;
-  }
-
-       // Conversion en int
-  IntType::operator int()  const
-  {
-    return this->_data;
-  }
-
-       // Clone duplique l'objet et en fabrique un nouveau a l'aide de new
-       // qu'il faudra detruire ensuite manuellement
-  GenericType * IntType::clone() const
-  {
-    IntType * pI = new IntType(this->_data);
-    assert(pI != 0);
-    return pI;
-  }
-
-}
diff --git a/src/Core/Batch_IntType.hxx b/src/Core/Batch_IntType.hxx
deleted file mode 100644 (file)
index c3c8ee7..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-//  Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-/*
- * IntType.hxx : 
- *
- * Auteur : Ivan DUTKA-MALEN - EDF R&D
- * Date   : Septembre 2003
- * Projet : SALOME 2
- *
- */
-
-#ifndef _INTTYPE_H_
-#define _INTTYPE_H_
-
-#include "Batch_Defines.hxx"
-
-#include <string>
-#include "Batch_GenericType.hxx"
-
-namespace Batch {
-
-  class BATCH_EXPORT IntType : public GenericType
-  {
-  public:
-               // Constructeur
-    IntType(const int i=0) : _data(i) {}
-
-               // Conversion en chaine
-    virtual std::string affiche() const;
-
-               // Operateur d'affectation
-    virtual IntType & operator =(int);
-
-               // Conversion en int
-    virtual operator int() const;
-
-               // Clone duplique l'objet et en fabrique un nouveau a l'aide de new
-               // qu'il faudra detruire ensuite manuellement
-    virtual GenericType * clone() const;
-
-  protected:
-    int _data;
-
-  private:
-
-  };
-
-}
-
-#endif
index 89279b1845128029558f39fe6ea059c151638f3a..8acb4f80a30e031bf07c497623b928d334f4076d 100644 (file)
@@ -84,6 +84,7 @@ namespace Batch {
     addParameter("USER", STRING, 1);
     addParameter("WORKDIR", STRING, 1);
     addParameter("HOMEDIR", STRING, 1);
+    addParameter("EXCLUSIVE", BOOL, 1);
   }
 
   ParameterTypeMap::~ParameterTypeMap()
@@ -106,13 +107,6 @@ namespace Batch {
     return (_map.find(key) != _map.end());
   }
 
-  const ParameterType & ParameterTypeMap::operator[](const string & key) const
-  {
-    map<string, ParameterType>::const_iterator it = _map.find(key);
-    if (it == _map.end()) throw InvalidKeyException(key);
-    return it->second;
-  }
-
   void ParameterTypeMap::addParameter(const std::string & key, DiscriminatorType type, int maxelem)
   {
     if (hasKey(key)) throw InvalidKeyException(key + " is already present in type map");
@@ -120,4 +114,11 @@ namespace Batch {
     _map[key].maxelem = maxelem;
   }
 
+  Versatile ParameterTypeMap::createVersatile(const std::string & parameterName)
+  {
+    map<string, ParameterType>::const_iterator it = _map.find(parameterName);
+    if (it == _map.end()) throw InvalidKeyException(parameterName);
+    return Versatile(it->second.type, it->second.maxelem, parameterName);
+  }
+
 }
index 277e2814527e7f7de8c1c584aa1d2fc56f24e059..bebeeeaa453cf2325531f5d6f68b796b8d60b64c 100644 (file)
@@ -54,9 +54,8 @@ namespace Batch {
     static ParameterTypeMap& getInstance();
 
     bool hasKey(const std::string & key) const;
-    const ParameterType & operator[](const std::string & key) const;
-
     void addParameter(const std::string & key, DiscriminatorType type, int maxelem);
+    Versatile createVersatile(const std::string & parameterName);
 
   protected:
 
index 9a50e53381709b4ef5e54f9cda88a626931e8665..d38a3feb53e4e3500ffed9c226766d2f7bdf4a53 100644 (file)
@@ -44,24 +44,20 @@ namespace Batch {
 
   // Operateur de recherche dans la map
   // Cet operateur agit sur les objets NON CONSTANTS, il autorise la modification de
-  // la valeur associ�e ï¿½ la clef car il retourne une reference non constante
+  // la valeur associée Ã  la clef car il retourne une reference non constante
   Versatile & Parametre::operator [] (const string & mk)
   {
     // On controle que la clef est valide
     if (!ParameterTypeMap::getInstance().hasKey(mk)) throw InvalidKeyException(mk);
 
-    // On recherche la valeur associee...
-    Versatile & V = map< string, Versatile >::operator [] (mk);
-
-    // ... et on l'initialise systematiquement
-    // ATTENTION : si un probleme de type survient (ie, on stocke une valeur d'un type
-    // different de celui inscrit dans TypeMap) une exception TypeMismatchException est
-    // levee
-    V.setName(mk);
-    V.setType(ParameterTypeMap::getInstance()[mk].type);
-    V.setMaxSize(ParameterTypeMap::getInstance()[mk].maxelem);
-
-    return V;
+    Parametre::iterator it = find(mk);
+    if (it != end()) {
+      return it->second;
+    } else {
+      Versatile V = ParameterTypeMap::getInstance().createVersatile(mk);
+      pair<iterator, bool> result = insert(make_pair(mk, V));
+      return result.first->second;
+    }
   }
 
   // Operateur de recherche dans la map
index 73b422182f2fe8f950e630b11b72a12fb063485d..790e0715d74edee9b0402baad2c0ce76b06db6d9 100644 (file)
@@ -22,9 +22,8 @@
 /*
  * Versatile.cxx : 
  *
- * Auteur : Ivan DUTKA-MALEN - EDF R&D
- * Date   : Septembre 2003
- * Projet : SALOME 2
+ * Author : Ivan DUTKA-MALEN - EDF R&D
+ * Date   : September 2003
  *
  */
 
 #include <list>
 #include <string>
 #include <sstream>
-#include <assert.h>
-//#include "MEDMEM_STRING.hxx"
+
 #include "Batch_GenericType.hxx"
-#include "Batch_IntType.hxx"
 #include "Batch_BoolType.hxx"
 #include "Batch_CharType.hxx"
 #include "Batch_LongType.hxx"
 #include "Batch_Versatile.hxx"
 #include "Batch_TypeMismatchException.hxx"
 #include "Batch_ListIsFullException.hxx"
+
 using namespace std;
 
 namespace Batch {
 
-       // Constructeur par recopie
-  Versatile::Versatile(const Versatile & V) : _discriminator(V._discriminator), _maxsize(V._maxsize), _name(V._name) // , _str_value(0)
+  Versatile::Versatile(DiscriminatorType discriminator, size_type maxsize, std::string name)
+    : _discriminator(discriminator),
+      _maxsize(maxsize),
+      _name(name)
   {
-    Versatile::const_iterator it;
-
-               // On prend un a un les elements de l'objet passe en argument qu'on duplique
-    for(it=V.begin(); it!=V.end(); it++)
-      push_back( (*it)->clone() ); // Attention, la methode clone fait un new implicite
   }
 
-       // Destructeur
-  Versatile::~Versatile()
+  Versatile::Versatile(const Versatile & V)
+   : _discriminator(V._discriminator),
+     _maxsize(V._maxsize),
+     _name(V._name)
   {
-               eraseAll();
+    Versatile::const_iterator it;
+    for(it=V.begin(); it!=V.end(); it++)
+      push_back( (*it)->clone() );
   }
 
-       // Operateur d'affectation entre objets
-  Versatile & Versatile::operator = (const Versatile & Vrhs) throw(TypeMismatchException)
+  Versatile::~Versatile()
   {
-               // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
-    setType(Vrhs._discriminator);
-    setMaxSize(Vrhs._maxsize);
-    _name = Vrhs._name;
-
-    // On efface les donnees precedentes
     eraseAll();
-
-    // On copie les donnees de Vrhs
-    Versatile::const_iterator it;
-
-    for(it=Vrhs.begin(); it!=Vrhs.end(); it++)
-      push_back( (*it)->clone() ); // Attention, la methode clone fait un new implicite
-
-    return *this;
   }
 
-       // Operateur d'affectation a partir d'un long
-  Versatile & Versatile::operator = (const long   l) throw(TypeMismatchException)
+  Versatile & Versatile::operator = (const long l) throw(TypeMismatchException)
   {
-               // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
-    setType(LONG);
-
-    // On efface les donnees precedentes
+    checkType(LONG);
     eraseAll();
-
-               // On ajoute un element interne de type long a l'objet  
-    LongType * pL = new LongType(l);
-    assert(pL != 0);
-    push_back(pL);
+    push_back(new LongType(l));
     return *this;
   }
 
-       // Operateur d'affectation a partir d'une string
   Versatile & Versatile::operator = (const string & ch) throw(TypeMismatchException)
   {
-               // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
-    setType(STRING);
-
-    // On efface les donnees precedentes
+    checkType(STRING);
     eraseAll();
-  
-               // On ajoute un element interne de type string a l'objet  
-    StringType * pS = new StringType(ch);
-    assert(pS != 0);
-    push_back(pS);
-
+    push_back(new StringType(ch));
     return *this;
   }
 
-       // Operateur de concatenation a partir d'une string
   Versatile & Versatile::operator +=(const string & ch) throw(TypeMismatchException,ListIsFullException)
   {
-               // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
-    setType(STRING);
+    checkType(STRING);
 
-               // Si la taille maximale est atteinte, on leve une exception ListIsFullException
-    if (_maxsize == 0) push_back(new StringType(ch));
-    else if ((_maxsize > 0) && (size() < _maxsize)) push_back(new StringType(ch));
+       // If max size is reached, throw a ListIsFullException
+    if (_maxsize == 0 || size() < _maxsize)
+      push_back(new StringType(ch));
     else {
-      //MEDMEM::STRING msg;
       ostringstream msg;
-      msg << "Taille maximum : " << _maxsize;
+      msg << "Maximum size for \"" << _name << "\" is reached: " << _maxsize;
       throw(ListIsFullException(msg.str()));
     }
     return *this;
   }
 
-       // Operateur de concatenation a partir d'une string
   Versatile & Versatile::operator , (const string & ch) throw(TypeMismatchException,ListIsFullException)
   {
     *this += ch;
     return *this;
   }
 
-       // Operateur d'affectation a partir d'un Couple
-  Versatile & Versatile::operator = (const Couple & cp) throw(TypeMismatchException)
+  Versatile & Versatile::operator = (const char * ch) throw(TypeMismatchException)
+  {
+    return operator=(string(ch));
+  }
+
+  Versatile & Versatile::operator +=(const char * ch) throw(TypeMismatchException,ListIsFullException)
   {
-               // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
-               setType(COUPLE);
+    return operator+=(string(ch));
+  }
 
-    // On efface les donnees precedentes
-    eraseAll();
-  
-               // On ajoute un element interne de type Couple a l'objet  
-    CoupleType * pC = new CoupleType(cp);
-    assert(pC != 0);
-    push_back(pC);
+  Versatile & Versatile::operator , (const char * ch) throw(TypeMismatchException,ListIsFullException)
+  {
+    return operator,(string(ch));
+  }
 
+  Versatile & Versatile::operator = (const Couple & cp) throw(TypeMismatchException)
+  {
+    checkType(COUPLE);
+    eraseAll();
+    push_back(new CoupleType(cp));
     return *this;
   }
 
-       // Operateur de concatenation a partir d'un Couple
   Versatile & Versatile::operator +=(const Couple & cp) throw(TypeMismatchException,ListIsFullException)
   {
-               // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
-    setType(COUPLE);
-
-               // Si la taille maximale est atteinte, on leve une exception ListIsFullException
-    if (_maxsize == 0) push_back(new CoupleType(cp));
-    else if ((_maxsize > 0) && (size() < _maxsize)) push_back(new CoupleType(cp));
+    checkType(COUPLE);
+    // If max size is reached, throw a ListIsFullException
+    if (_maxsize == 0 || size() < _maxsize)
+      push_back(new CoupleType(cp));
     else {
-      //MEDMEM::STRING msg;
       ostringstream msg;
-      msg << "Taille maximum : " << _maxsize;
+      msg << "Maximum size for \"" << _name << "\" is reached: " << _maxsize;
       throw(ListIsFullException(msg.str()));
     }
     return *this;
   }
 
-       // Operateur de concatenation a partir d'un Couple
   Versatile & Versatile::operator , (const Couple & cp) throw(TypeMismatchException,ListIsFullException)
   {
     *this += cp;
@@ -195,88 +159,79 @@ namespace Batch {
     return os;
   }
 
-       // Positionnement du type de l'element interne
-  void Versatile::setType(DiscriminatorType t) throw(TypeMismatchException)
+  Versatile & Versatile::operator = (const int i) throw(TypeMismatchException)
   {
-               // Si le type est deja defini et ne correspond pas au type en argument
-               // une exception TypeMismatchException est levee
-    if ( (_discriminator == UNDEFINED) || (_discriminator == t) )
-      _discriminator = t;
-    else {
-      //MEDMEM::STRING sst;
-      ostringstream sst;
-      sst << "Trying to change type of Versatile object \""
-                                       << _name << "\"";
-      throw(TypeMismatchException(sst.str()));
-    }
+    checkType(LONG);
+    eraseAll();
+    push_back(new LongType((long)i));
+    return *this;
   }
-       
-       // Positionnement du nombre d'elements internes
-  void Versatile::setMaxSize(int i)
+
+  Versatile & Versatile::operator = (const bool b) throw(TypeMismatchException)
   {
-    _maxsize = i;
-    if (i <= 0) return;
-               // Si la nouvelle taille est inferieure au nombre d'elements deja
-               // presents, les elements en surplus sont effaces (troncature)
-    if (size() > _maxsize)
-      {
-                               int reste = size() - _maxsize;
-                               Versatile::iterator it;
-                               for(it=end(); (it!=begin()) && reste; it--, reste--)
-                                       {
-                                               delete back();
-                                               pop_back();
-                                       }
-      }
+    checkType(BOOL);
+    eraseAll();
+    push_back(new BoolType(b));
+    return *this;
   }
 
+  void Versatile::checkType(DiscriminatorType t) const throw(TypeMismatchException)
+  {
+    if (_discriminator != t)
+      throw (TypeMismatchException("Trying to change type of Versatile object \"" + _name + "\""));
+  }
 
-       // Conversion de type vers un long
   Versatile::operator long() const throw(TypeMismatchException)
   {
-               // Si le type ne correspond pas ou si la liste contient plus d'un element,
-               // la conversion est impossible et une exception TypeMismatchException 
-               // est levee
-    if ( (_maxsize != 1) || (_discriminator != LONG) || (size() == 0) ) {
-      //MEDMEM::STRING sst;
+    // If the type does not correspond or if the list has more than one element,
+    // throw a TypeMismatchException
+    if ( _maxsize != 1 || _discriminator != LONG || size() == 0 ) {
       ostringstream sst;
-      sst << "Cannot cast Versatile object \""
-                                       << _name << "\" to long";
+      sst << "Cannot cast Versatile object \"" << _name << "\" to long";
+      throw (TypeMismatchException(sst.str()));
+    }
+       return *( static_cast<LongType *>(this->front()) );
+  }
+
+  Versatile::operator bool() const throw(TypeMismatchException)
+  {
+    // If the type does not correspond or if the list has more than one element,
+    // throw a TypeMismatchException
+    if ( _maxsize != 1 || _discriminator != BOOL || size() == 0 ) {
+      ostringstream sst;
+      sst << "Cannot cast Versatile object \"" << _name << "\" to bool";
       throw(TypeMismatchException(sst.str()));
     }
-               return *( static_cast<LongType *>(this->front()) );
+    return *( static_cast<BoolType *>(this->front()) );
+  }
+
+  Versatile::operator int() const throw(TypeMismatchException)
+  {
+    return operator long();
   }
 
-       // Conversion de type vers un Couple
   Versatile::operator Couple() const throw(TypeMismatchException)
   {
-               // Si le type ne correspond pas ou si la liste contient plus d'un element,
-               // la conversion est impossible et une exception TypeMismatchException 
-               // est levee
-    if ( (_maxsize != 1) || (_discriminator != COUPLE) || (size() == 0) ) {
-      //MEDMEM::STRING sst;
+    // If the type does not correspond or if the list has more than one element,
+    // throw a TypeMismatchException
+    if ( _maxsize != 1 || _discriminator != COUPLE || size() == 0 ) {
       ostringstream sst;
-      sst << "Cannot cast Versatile object \""
-                                       << _name << "\" to Couple";
+      sst << "Cannot cast Versatile object \"" << _name << "\" to Couple";
       throw(TypeMismatchException(sst.str()));
     }
-               return *( static_cast<CoupleType *>(this->front()) );
+    return *( static_cast<CoupleType *>(this->front()) );
   }
 
-       // Conversion de type vers une string
   string Versatile::str() const throw(TypeMismatchException)
   {
-               // Si le type ne correspond pas, la conversion est impossible et 
-               // une exception TypeMismatchException est levee
-    if ( (_discriminator != STRING) || (size() == 0) ) {
-      //MEDMEM::STRING sst;
+    // If the type does not correspond, throw a TypeMismatchException
+    if ( _discriminator != STRING || size() == 0 ) {
       ostringstream sst;
-      sst << "Cannot cast Versatile object \""
-                                       << _name << "\" to string";
+      sst << "Cannot cast Versatile object \"" << _name << "\" to string";
       throw(TypeMismatchException(sst.str()));
     }
 
-               // La chaine renvoyee est la concatenation des chaines internes
+       // The returned string is the concatenation of internal strings
     string s;
     Versatile::const_iterator it;
     const char * sep = "";
@@ -286,38 +241,32 @@ namespace Batch {
     return s;
   }
 
-       // Conversion de type vers une string
   Versatile::operator string () const throw(TypeMismatchException)
   {
     return str();
   }
 
-       // Efface tous les elements internes de l'objet
   void Versatile::eraseAll()
   {
-    while(!empty()) 
-      {
-                               delete back();
-                               pop_back();
-      }
+    while(!empty()) {
+      delete back();
+      pop_back();
+    }
   }
 
-
-       // Recuperation du type de l'element interne
   DiscriminatorType Versatile::getType() const
   {
     return _discriminator;
   }
 
-       // Recuperation du nom de l'objet
-  string Versatile::getName() const
+  Versatile::size_type Versatile::getMaxSize() const
   {
-    return _name;
+    return _maxsize;
   }
 
-       // Positionnement du nom de l'objet
-  void Versatile::setName(const string & name)
+  const string & Versatile::getName() const
   {
-    _name = name;
+    return _name;
   }
+
 }
index ee8eb2ab73925ebfb17baa930497db84e4f6ca78..96b4b6016c9dc6ff941709eba32f152894dd96d4 100644 (file)
@@ -22,9 +22,8 @@
 /*
  * Versatile.hxx :
  *
- * Auteur : Ivan DUTKA-MALEN - EDF R&D
- * Date   : Septembre 2003
- * Projet : SALOME 2
+ * Author : Ivan DUTKA-MALEN - EDF R&D
+ * Date   : September 2003
  *
  */
 
@@ -37,7 +36,6 @@
 #include <list>
 #include <string>
 #include "Batch_GenericType.hxx"
-#include "Batch_IntType.hxx"
 #include "Batch_BoolType.hxx"
 #include "Batch_CharType.hxx"
 #include "Batch_LongType.hxx"
 
 namespace Batch {
 
-       // Les types autorises
-  // enum DiscriminatorType { UNDEFINED, BOOL, CHAR, INT, LONG, STRING};
-  enum DiscriminatorType { UNDEFINED, LONG, STRING, COUPLE };
+  // Authorized types
+  enum DiscriminatorType { BOOL, LONG, STRING, COUPLE };
 
   class BATCH_EXPORT Versatile : public std::list< GenericType * >
   {
   public:
-               // Constructeur standard et destructeur
-    Versatile() : _discriminator(UNDEFINED), _maxsize(1), _name("undefined") {}
-    virtual ~Versatile();
 
-               // Constructeur par recopie
+    // Constructors
+    Versatile(DiscriminatorType discriminator, size_type maxsize, std::string name);
     Versatile(const Versatile & V);
 
-               // Constructeur depuis le type de "base"
-    Versatile(long   l) : _discriminator(LONG), _maxsize(1), _name("long")   { push_back(new LongType(l)); }
-    Versatile(const std::string & s) : _discriminator(STRING), _maxsize(1), _name("string") { push_back(new StringType(s)); }
-    Versatile(const Couple & c) : _discriminator(COUPLE), _maxsize(1), _name("couple") { push_back(new CoupleType(c)); }
+    // Destructor
+    virtual ~Versatile();
 
-               // Operateur d'affectation et de concatenation a partir d'un type de "base"
+    // Affectation and concatenation operators from base types
     Versatile & operator = (const long     l)    throw(TypeMismatchException);
     Versatile & operator = (const std::string & ch)   throw(TypeMismatchException);
     Versatile & operator +=(const std::string & ch)   throw(TypeMismatchException,ListIsFullException);
     Versatile & operator , (const std::string & ch)   throw(TypeMismatchException,ListIsFullException);
+    Versatile & operator = (const char * ch)   throw(TypeMismatchException);
+    Versatile & operator +=(const char * ch)   throw(TypeMismatchException,ListIsFullException);
+    Versatile & operator , (const char * ch)   throw(TypeMismatchException,ListIsFullException);
     Versatile & operator = (const Couple & cp)   throw(TypeMismatchException);
     Versatile & operator +=(const Couple & cp)   throw(TypeMismatchException,ListIsFullException);
     Versatile & operator , (const Couple & cp)   throw(TypeMismatchException,ListIsFullException);
+    Versatile & operator = (const int i) throw(TypeMismatchException);
+    Versatile & operator = (const bool b) throw(TypeMismatchException);
 
-               // Operateur d'affectation entre objets
-    Versatile & operator = (const Versatile & V) throw(TypeMismatchException);
-
-               // Conversion de type vers un type de "base"
+    // Type conversion to base types
     operator long() const throw(TypeMismatchException);
     operator std::string() const throw(TypeMismatchException);
     operator Couple() const throw(TypeMismatchException);
     std::string str() const throw(TypeMismatchException);
+    operator bool() const throw(TypeMismatchException);
+    operator int() const throw(TypeMismatchException);
 
-               // Operateur pour l'affichage sur un stream
+    // Display on a stream
     BATCH_EXPORT friend std::ostream & operator << (std::ostream & os, const Versatile & );
 
-               // Positionnement et recuperation du type de l'element interne
-    void setType(DiscriminatorType) throw(TypeMismatchException);
-    DiscriminatorType getType() const;
+    // Check the type
+    void checkType(DiscriminatorType t) const throw (TypeMismatchException);
 
-               // Positionnement et recuperation du nombre d'elements internes
-    void setMaxSize(int i);
-               int getMaxSize() const { return _maxsize; }
+    // Getter methods
+    DiscriminatorType getType() const;
+    size_type getMaxSize() const;
+    const std::string & getName() const;
 
-               // Positionnement et recuperation du nom de l'objet
-    std::string getName() const;
-    void setName(const std::string & name);
+    // Erase all internal elements
+    void eraseAll();
 
-               // Efface tous les elements internes de l'objet
-    virtual void eraseAll();
   protected:
 
-    DiscriminatorType _discriminator; // type de l'element interne
-    size_type _maxsize; // nombre max d'elements internes
-    std::string _name; // nom de l'objet (sert pour les exceptions)
+    DiscriminatorType _discriminator; // Internal element type
+    size_type _maxsize; // Maximum number of internal elements
+    std::string _name; // Object name (used for exceptions)
 
   private:
 
+    // Forbid the use of default constructor and affectation operator
+    Versatile() {}
+    void operator= (const Versatile & V) {}
+
   };
 
 }
index c53d1bbc27f9ef70eb62f8793b410d46d4650db4..1e4f5c21a3e4700555cd01470870a346536ddf55 100644 (file)
@@ -39,7 +39,6 @@ SET(CLASS_LIST Core/Batch_APIInternalFailureException
                Core/Batch_FactBatchManager
                Core/Batch_GenericException
                Core/Batch_GenericType
-               Core/Batch_IntType
                Core/Batch_InvalidArgumentException
                Core/Batch_InvalidKeyException
                Core/Batch_Job
index fe3cfc7ef634039ed8679d98c8c56a8ac210d7e6..1da7a923427f65fcd61934319d29e7763ae731f7 100644 (file)
@@ -267,6 +267,11 @@ namespace Batch {
     if( mem > 0 )
       tempOutputFile << "#BSUB -M " << mem*1024 << endl ;
     tempOutputFile << "#BSUB -n " << nbproc << endl ;
+
+    if (params.find(EXCLUSIVE) != params.end() && params[EXCLUSIVE]) {
+      tempOutputFile << "#BSUB -x" << endl ;
+    }
+
     size_t pos = workDir.find("$HOME");
     string baseDir;
     if( pos != string::npos )
@@ -281,10 +286,16 @@ namespace Batch {
     tempOutputFile << "#BSUB -o " << baseDir << "/logs/output.log." << rootNameToExecute << endl ;
     tempOutputFile << "#BSUB -e " << baseDir << "/logs/error.log." << rootNameToExecute << endl ;
 
+    // Define environment for the job
+    Environnement env = job.getEnvironnement();
+    for (Environnement::const_iterator iter = env.begin() ; iter != env.end() ; ++iter) {
+      tempOutputFile << "export " << iter->first << "=" << iter->second << endl;
+    }
+
     tempOutputFile << "cd " << workDir << endl ;
 
     // generate nodes file
-    tempOutputFile << "NODEFILE=`mktemp nodefile-XXXXXXXXXX` || exit 1" << endl;
+    tempOutputFile << "LIBBATCH_NODEFILE=`mktemp nodefile-XXXXXXXXXX` || exit 1" << endl;
     tempOutputFile << "bool=0" << endl;
     tempOutputFile << "for i in $LSB_MCPU_HOSTS; do" << endl;
     tempOutputFile << "  if test $bool = 0; then" << endl;
@@ -292,20 +303,18 @@ namespace Batch {
     tempOutputFile << "    bool=1" << endl;
     tempOutputFile << "  else" << endl;
     tempOutputFile << "    for ((j=0;j<$i;j++)); do" << endl;
-    tempOutputFile << "      echo $n >> $NODEFILE" << endl;
+    tempOutputFile << "      echo $n >> $LIBBATCH_NODEFILE" << endl;
     tempOutputFile << "    done" << endl;
     tempOutputFile << "    bool=0" << endl;
     tempOutputFile << "  fi" << endl;
     tempOutputFile << "done" << endl;
-
-    // Abstraction of PBS_NODEFILE - TODO
-    tempOutputFile << "export LIBBATCH_NODEFILE=$NODEFILE" << endl;
+    tempOutputFile << "export LIBBATCH_NODEFILE" << endl;
 
     // Launch the executable
     tempOutputFile << "./" + fileNameToExecute << endl;
 
     // Remove the node file
-    tempOutputFile << "rm $NODEFILE" << endl;
+    tempOutputFile << "rm $LIBBATCH_NODEFILE" << endl;
 
     tempOutputFile.flush();
     tempOutputFile.close();
index 764d224474ced9f79f135e4c7a28e7888648f6b7..434003f985995a3c6cbae69b0b71435905aec26d 100644 (file)
@@ -35,3 +35,7 @@ IF (BUILD_LSF_INTERFACE AND LSF_FOUND)
 ENDIF (BUILD_LSF_INTERFACE AND LSF_FOUND)
 
 APPEND_CLASSES_TO_SRC_FILES(${CLASS_LIST})
+
+IF (TEST_ENABLED)
+    add_subdirectory(Test)
+ENDIF (TEST_ENABLED)
diff --git a/src/LSF/Test/CMakeLists.txt b/src/LSF/Test/CMakeLists.txt
new file mode 100644 (file)
index 0000000..47e0512
--- /dev/null
@@ -0,0 +1,44 @@
+#  Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Just copy the test scripts to the binary dir
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/seta.sh ${CMAKE_CURRENT_BINARY_DIR}/seta.sh COPYONLY)
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/setb.sh ${CMAKE_CURRENT_BINARY_DIR}/setb.sh COPYONLY)
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/test-script.sh ${CMAKE_CURRENT_BINARY_DIR}/test-script.sh COPYONLY)
+
+# set the include directories
+include_directories(${CMAKE_SOURCE_DIR}/src/Core)
+include_directories(${CMAKE_SOURCE_DIR}/src/Core/Test)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+# Build the test programs and add the tests
+add_executable(Test_eLSF Test_eLSF.cxx)
+target_link_libraries(Test_eLSF Batch SimpleParser)
+
+IF (HAS_SSH)
+    ADD_TEST(eLSF_SSH Test_eLSF SSH)
+ENDIF (HAS_SSH)
+
+#IF (HAS_RSH)
+#    ADD_TEST(eLSF_RSH Test_eLSF RSH)
+#ENDIF (HAS_RSH)
diff --git a/src/LSF/Test/Test_eLSF.cxx b/src/LSF/Test/Test_eLSF.cxx
new file mode 100644 (file)
index 0000000..b3962a9
--- /dev/null
@@ -0,0 +1,163 @@
+//  Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * Test_eLSF.cxx :
+ *
+ * Author : Renaud BARATE - EDF R&D
+ * Date   : September 2011
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <cstring>
+
+#include <Batch_Constants.hxx>
+#include <Batch_Job.hxx>
+#include <Batch_BatchManagerCatalog.hxx>
+#include <Batch_FactBatchManager.hxx>
+#include <Batch_FactBatchManager_eClient.hxx>
+#include <Batch_BatchManager.hxx>
+#include <Batch_BatchManager_eClient.hxx>
+
+#include <SimpleParser.hxx>
+
+using namespace std;
+using namespace Batch;
+
+void print_usage()
+{
+  cout << "usage: Test_eLSF PROTOCOL" << endl;
+  cout << "    PROTOCOL      \"SSH\" or \"RSH\"" << endl;
+}
+
+int main(int argc, char** argv)
+{
+  // Parse argument
+  if (argc != 2) {
+    print_usage();
+    return 1;
+  }
+  CommunicationProtocolType protocol;
+  if (strcmp(argv[1], "SSH") == 0)
+    protocol = SSH;
+  else if (strcmp(argv[1], "RSH") == 0)
+    protocol = RSH;
+  else {
+    print_usage();
+    return 1;
+  }
+
+  cout << "*******************************************************************************************" << endl;
+  cout << "This program tests the batch submission based on LSF emulation. Passwordless" << endl;
+  cout << "authentication must be used for this test to pass. For SSH, this can be configured with" << endl;
+  cout << "ssh-agent for instance. For RSH, this can be configured with the .rhosts file." << endl;
+  cout << "*******************************************************************************************" << endl;
+
+  // eventually remove any previous result
+  remove("result.txt");
+
+  try {
+    // Parse the test configuration file
+    SimpleParser parser;
+    parser.parseTestConfigFile();
+    const string & homedir = parser.getValue("TEST_ELSF_HOMEDIR");
+    const string & host = parser.getValue("TEST_ELSF_HOST");
+    const string & user = parser.getValue("TEST_ELSF_USER");
+    int timeout = parser.getValueAsInt("TEST_ELSF_TIMEOUT");
+
+    // Define the job...
+    Job job;
+    // ... and its parameters ...
+    Parametre p;
+    p[EXECUTABLE]    = "./test-script.sh";
+    p[NAME]          = string("Test eLSF ") + argv[1];
+    p[WORKDIR]       = homedir + "/tmp/Batch";
+    p[INFILE]        = Couple("seta.sh", "tmp/Batch/seta.sh");
+    p[INFILE]       += Couple("setb.sh", "tmp/Batch/setb.sh");
+    p[OUTFILE]       = Couple("result.txt", "tmp/Batch/result.txt");
+    p[TMPDIR]        = "tmp/Batch/";
+    p[NBPROC]        = 1;
+    p[MAXWALLTIME]   = 1;
+    p[MAXRAMSIZE]    = 50;
+    p[HOMEDIR]       = homedir;
+    p[EXCLUSIVE]     = true;
+    job.setParametre(p);
+    // ... and its environment
+    Environnement e;
+    e["MYENVVAR"] = "MYVALUE";
+    job.setEnvironnement(e);
+    cout << job << endl;
+
+    // Get the catalog
+    BatchManagerCatalog& c = BatchManagerCatalog::getInstance();
+
+    // Create a BatchManager of type ePBS on localhost
+    FactBatchManager_eClient * fbm = (FactBatchManager_eClient *)(c("eLSF"));
+    BatchManager_eClient * bm = (*fbm)(host.c_str(), user.c_str(), protocol);
+
+    // Submit the job to the BatchManager
+    JobId jobid = bm->submitJob(job);
+    cout << jobid.__repr__() << endl;
+
+    // Wait for the end of the job
+    string state = bm->waitForJobEnd(jobid, timeout);
+
+    if (state == FINISHED) {
+      cout << "Job " << jobid.__repr__() << " is done" << endl;
+      bm->importOutputFiles(job, "resultdir/seconddirname");
+    } else if (state == FAILED) {
+      cerr << "Job " << jobid.__repr__() << " finished in error" << endl;
+      bm->importOutputFiles(job, "resultdir/seconddirname");
+      return 1;
+    } else {
+      cerr << "Timeout while executing job" << endl;
+      return 1;
+    }
+
+  } catch (GenericException e) {
+    cerr << "Error: " << e << endl;
+    return 1;
+  } catch (ParserException e) {
+    cerr << "Parser error: " << e.what() << endl;
+    return 1;
+  }
+
+  // test the result file
+  try {
+    SimpleParser resultParser;
+    resultParser.parse("resultdir/seconddirname/result.txt");
+    cout << "Result:" << endl << resultParser;
+    const string & envvar = resultParser.getValue("MYENVVAR");
+    int result = resultParser.getValueAsInt("c");
+    if (envvar == "MYVALUE" && result == 12) {
+      cout << "OK, Expected result found." << endl;
+      return 0;
+    } else {
+      cerr << "Error, result is not the expected one (MYENVVAR = MYVALUE, c = 12)." << endl;
+      return 1;
+    }
+  } catch (ParserException e) {
+    cerr << "Parser error on result file: " << e.what() << endl;
+    return 1;
+  }
+}
diff --git a/src/LSF/Test/seta.sh b/src/LSF/Test/seta.sh
new file mode 100644 (file)
index 0000000..42d1e38
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+a=4
diff --git a/src/LSF/Test/setb.sh b/src/LSF/Test/setb.sh
new file mode 100644 (file)
index 0000000..8969060
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+b=3
diff --git a/src/LSF/Test/test-script.sh b/src/LSF/Test/test-script.sh
new file mode 100755 (executable)
index 0000000..1d56247
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+. ./seta.sh
+. ./setb.sh
+
+c=`expr $a "*" $b`
+
+echo "MYENVVAR = $MYENVVAR" > result.txt
+echo "c = $c" >> result.txt
index 85a387c738e98cbf404e1297f5cbc89f38a6e40b..aa3562a4fc1ce1088dba263b1bcc6c4a0470b0ca 100644 (file)
@@ -147,7 +147,6 @@ namespace Batch {
     tempOutputFile << "#!/bin/bash" << endl;
     tempOutputFile << "# @ output = " << workDir << "/logs/output.log." << rootNameToExecute << endl;
     tempOutputFile << "# @ error = " << workDir << "/logs/error.log." << rootNameToExecute << endl;
-    tempOutputFile << "# @ node_usage = not_shared" << endl;
 
     if (params.find(NAME) != params.end())
       tempOutputFile << "# @ job_name = " << params[NAME] << endl;
@@ -157,6 +156,13 @@ namespace Batch {
     if (params.find(NBPROC) != params.end())
       nbproc = params[NBPROC];
 
+    if (params.find(EXCLUSIVE) != params.end()) {
+      if (params[EXCLUSIVE])
+        tempOutputFile << "# @ node_usage = not_shared" << endl;
+      else
+        tempOutputFile << "# @ node_usage = shared" << endl;
+    }
+
     // If job type is not specified, try to guess it from number of procs
     string job_type;
     if (params.find(LL_JOBTYPE) != params.end())
@@ -168,10 +174,10 @@ namespace Batch {
 
     tempOutputFile << "# @ job_type = " << job_type << endl;
 
-    if (job_type != "serial") {
+    if (job_type == "mpich") {
       int nodes_requested = (nbproc + _nb_proc_per_node -1) / _nb_proc_per_node;
       tempOutputFile << "# @ node = " << nodes_requested << endl;
-      tempOutputFile << "# @ tasks_per_node = " << _nb_proc_per_node << endl;
+      tempOutputFile << "# @ total_tasks = " << nbproc << endl;
     }
 
     if (params.find(MAXWALLTIME) != params.end())
index a3e70d616eecb69fd3ac89e5fcd894cbf9f18a62..80643867d384c16e0f23458bdd14e22ecbd6bdd1 100644 (file)
@@ -104,7 +104,8 @@ int main(int argc, char** argv)
     p[MAXRAMSIZE]    = 50;
     p[HOMEDIR]       = homedir;
     p[QUEUE]         = queue;
-    p[LL_JOBTYPE]       = jobType;
+    p[LL_JOBTYPE]    = jobType;
+    p[EXCLUSIVE]     = false;
     job.setParametre(p);
     // ... and its environment
     Environnement e;
index 7232f7e958b87af2f17da8dfce03f59d152873d8..c92a121d7ec0a0e2d1a227a541ca21abcb15dc26 100644 (file)
@@ -256,9 +256,31 @@ namespace Batch {
     tempOutputFile << "#! /bin/sh -f" << endl;
     if (nbproc > 0)
     {
-      // Division - arrondi supérieur
-      int nodes_requested = (nbproc + _nb_proc_per_node -1) / _nb_proc_per_node;
-      tempOutputFile << "#PBS -l nodes=" << nodes_requested << ":ppn=" << _nb_proc_per_node << endl;
+      int nb_full_nodes = nbproc / _nb_proc_per_node;
+      int nb_proc_on_last_node = nbproc % _nb_proc_per_node;
+
+      // In exclusive mode, we reserve all procs on the nodes
+      if (params.find(EXCLUSIVE) != params.end() && params[EXCLUSIVE] && nb_proc_on_last_node > 0) {
+        nb_full_nodes += 1;
+        nb_proc_on_last_node = 0;
+      }
+
+      tempOutputFile << "#PBS -l nodes=";
+
+      // Full nodes
+      if (nb_full_nodes > 0) {
+        tempOutputFile << nb_full_nodes << ":ppn=" << _nb_proc_per_node;
+        if (nb_proc_on_last_node > 0) {
+          tempOutputFile << "+";
+        }
+      }
+
+      // Partly reserved node
+      if (nb_proc_on_last_node > 0) {
+        tempOutputFile << "1:ppn=" << nb_proc_on_last_node;
+      }
+
+      tempOutputFile << endl;
     }
     if (queue != "")
       tempOutputFile << "#PBS -q " << queue << endl;
index 0e57d3ce369b9a3d3a479b048f1fea36e3c8cfda..1040faae9374eec5b416cf263acb17e71c30f771 100644 (file)
@@ -114,7 +114,7 @@ int main(int argc, char** argv)
 
     // Create a BatchManager of type ePBS on localhost
     FactBatchManager_eClient * fbm = (FactBatchManager_eClient *)(c("ePBS"));
-    BatchManager_eClient * bm = (*fbm)(host.c_str(), user.c_str(), protocol, "lam");
+    BatchManager_eClient * bm = (*fbm)(host.c_str(), user.c_str(), protocol, "nompi", 8);
 
     // Submit the job to the BatchManager
     JobId jobid = bm->submitJob(job);
diff --git a/src/Python/Batch_PyVersatile.cxx b/src/Python/Batch_PyVersatile.cxx
deleted file mode 100644 (file)
index 3584724..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-//  Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-/*
- * PyVersatile.cxx : 
- *
- * Auteur : Ivan DUTKA-MALEN - EDF R&D
- * Mail   : mailto:ivan.dutka-malen@der.edf.fr
- * Date   : Mon Oct 13 12:01:12 2003
- * Projet : Salome 2
- *
- */
-
-#include <Python.h>
-#include "Batch_TypeMismatchException.hxx"
-#include "Batch_ListIsFullException.hxx"
-#include "Batch_InvalidArgumentException.hxx"
-#include "Batch_PyVersatile.hxx"
-#include <string>
-
-using namespace std;
-
-namespace Batch {
-
-  // Constructeur a partir d'un objet Versatile
-  PyVersatile::PyVersatile(const Versatile & V) : Versatile(V)
-  {
-    // Nothing to do
-  }
-
-
-  // Constructeur a partir d'un PyObject
-  // Les objets autorises sont les strings et les ints,
-  // ainsi que les listes de strings
-  PyVersatile::PyVersatile(const PyObject * PyO) throw(TypeMismatchException, ListIsFullException, InvalidArgumentException) : Versatile()
-  {
-    PyObject * _PyO = const_cast<PyObject *>(PyO);
-
-    if (PyList_Check(_PyO)) { // c'est une liste
-      _maxsize = PyList_Size(_PyO);
-      for (size_type i=0; i<_maxsize; i++) {
-        PyObject * val = PyList_GetItem(_PyO, i);
-        if (PyString_Check(val)) {
-          *this += PyString_AsString(val);
-
-        } else if (PyTuple_Check(val) &&
-            (PyTuple_Size(val) == 2) &&
-            PyString_Check( PyTuple_GetItem(val,0) ) &&
-            PyString_Check( PyTuple_GetItem(val,1) )   ) {
-          *this += Couple( PyString_AsString( PyTuple_GetItem(val,0) ),
-                           PyString_AsString( PyTuple_GetItem(val,1) )
-                         );
-
-        } else {
-          PyErr_SetString(PyExc_RuntimeWarning, "PyVersatile::PyVersatile(const PyObject * PyO) : invalid PyObject");
-        }
-      }
-
-    } else if (PyString_Check(_PyO)) { // c'est une string
-      const char * s = PyString_AsString(_PyO);
-      Versatile V = string(s);
-      *this = V;
-
-    } else if (PyInt_Check(_PyO)) { // c'est un int
-      *this = PyInt_AsLong(_PyO);
-
-    } else { // erreur
-      PyErr_SetString(PyExc_RuntimeWarning, "PyVersatile::PyVersatile(const PyObject * PyO) : invalid PyObject");
-    }
-  }
-
-
-
-  // Conversion de type vers un PyObject
-  PyVersatile::operator PyObject *() const
-  {
-    PyObject * obj;
-
-    if (_maxsize != 1) { // une liste
-      obj = PyList_New(0);
-      for(Versatile::const_iterator it=begin(); it!=end(); it++) {
-        //     char ch[2] = {0, 0};
-        string st;
-        Couple cp;
-        //     PyObject * tuple;
-        switch (_discriminator) {
-        //     case BOOL:
-        //       PyList_Append(obj, PyInt_FromLong(* static_cast<BoolType *>(*it)));
-        //       break;
-
-        //     case CHAR:
-        //       *ch = * static_cast<CharType *>(*it);
-        //       PyList_Append(obj, PyString_FromString(ch));
-        //       break;
-
-        //     case INT:
-        //       PyList_Append(obj, PyInt_FromLong(* static_cast<IntType *>(*it)));
-        //       break;
-
-        case LONG:
-          PyList_Append(obj, PyInt_FromLong(* static_cast<LongType *>(*it)));
-          break;
-
-        case STRING:
-          st = * static_cast<StringType *>(*it);
-          PyList_Append(obj, PyString_FromString(st.c_str()));
-          break;
-
-        case COUPLE:
-          cp = * static_cast<CoupleType *>(*it);
-          //     tuple = PyTuple_New(2);
-          //     PyTuple_SetItem(tuple, 0, PyString_FromString( cp.getLocal().c_str()  ) );
-          //     PyTuple_SetItem(tuple, 1, PyString_FromString( cp.getRemote().c_str() ) );
-          //     PyList_Append(obj, tuple);
-          PyList_Append(obj, Py_BuildValue("(ss)", cp.getLocal().c_str(), cp.getRemote().c_str() ));
-          break;
-
-        case UNDEFINED:
-          PyList_Append(obj, Py_None);
-          break;
-        }
-
-      }
-
-    } else { // un scalaire
-      //      char ch[2] = {0, 0};
-      string st;
-      Couple cp;
-      //       PyObject * tuple;
-      switch (_discriminator) {
-      //       case BOOL:
-      //       obj = PyInt_FromLong(* static_cast<BoolType *>(front()));
-      //       break;
-
-      //       case CHAR:
-      //       *ch = * static_cast<CharType *>(front());
-      //       obj = PyString_FromString(ch);
-      //       break;
-
-      //       case INT:
-      //       obj = PyInt_FromLong(* static_cast<IntType *>(front()));
-      //       break;
-
-      case LONG:
-        obj = PyInt_FromLong(* static_cast<LongType *>(front()));
-        break;
-
-      case STRING:
-        st = * static_cast<StringType *>(front());
-        obj = PyString_FromString(st.c_str());
-        break;
-
-      case COUPLE:
-        cp = * static_cast<CoupleType *>(front());
-        //     tuple = PyTuple_New(2);
-        //     PyTuple_SetItem(tuple, 0, PyString_FromString( cp.getLocal().c_str()  ) );
-        //     PyTuple_SetItem(tuple, 1, PyString_FromString( cp.getRemote().c_str() ) );
-        //     obj = PyList_New(0);
-        //     PyList_Append(obj, tuple);
-        obj = Py_BuildValue("[(ss)]", cp.getLocal().c_str(), cp.getRemote().c_str() );
-        break;
-
-      case UNDEFINED:
-        obj = Py_None;
-        break;
-      }
-    }
-
-    return obj;
-  }
-
-
-  // Operateur d'affectation a partir d'un objet Versatile
-  PyVersatile & PyVersatile::operator =(const Versatile & V)
-  {
-    Versatile * me = this;
-    *me = V;
-    return *this;
-  }
-
-}
-
-
-// COMMENTS
diff --git a/src/Python/Batch_PyVersatile.hxx b/src/Python/Batch_PyVersatile.hxx
deleted file mode 100644 (file)
index 1e33af0..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-//  Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-/*
- * PyVersatile.hxx :
- *
- * Auteur : Ivan DUTKA-MALEN - EDF R&D
- * Mail   : mailto:ivan.dutka-malen@der.edf.fr
- * Date   : Mon Oct 13 12:01:12 2003
- * Projet : Salome 2
- *
- */
-
-#ifndef _PYVERSATILE_H_
-#define _PYVERSATILE_H_
-
-
-#include "Batch_Defines.hxx"
-
-#include <Python.h>
-#include "Batch_Versatile.hxx"
-#include "Batch_TypeMismatchException.hxx"
-#include "Batch_ListIsFullException.hxx"
-#include "Batch_InvalidArgumentException.hxx"
-
-#ifdef WIN32
-# if defined _libBatch_Swig_EXPORTS
-#  define BATCH_SWIG_EXPORT __declspec( dllexport )
-# else
-#  define BATCH_SWIG_EXPORT __declspec( dllimport )
-# endif
-#else
-# define BATCH_SWIG_EXPORT
-#endif
-
-namespace Batch {
-
-  class BATCH_SWIG_EXPORT PyVersatile : public Versatile
-  {
-  public:
-               // Constructeur a partir d'un objet Versatile
-    PyVersatile(const Versatile &);
-
-               // Constructeur a partir d'un PyObject
-    PyVersatile(const PyObject *) throw(TypeMismatchException, ListIsFullException, InvalidArgumentException);
-
-               // Conversion de type vers un PyObject
-    operator PyObject *() const;
-
-               // Operateur d'affectation a partir d'un objet Versatile
-    PyVersatile & operator =(const Versatile &);
-
-  protected:
-
-  private:
-
-  };
-
-}
-
-#endif
index a24051ebd192181d129634f7c6cde4ece24d49e3..08febb7550cdaf8cbb15f330d481b04b62b0f43a 100644 (file)
@@ -28,13 +28,12 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
 SET(SWIG_SRC_FILE libBatch_Swig.i)
 SET_SOURCE_FILES_PROPERTIES(${SWIG_SRC_FILE} PROPERTIES CPLUSPLUS ON
                                                         SWIG_FLAGS "-shadow")
-SWIG_ADD_MODULE(libBatch_Swig python ${SWIG_SRC_FILE} Batch_PyVersatile.cxx)
+SWIG_ADD_MODULE(libBatch_Swig python ${SWIG_SRC_FILE})
 SWIG_LINK_LIBRARIES(libBatch_Swig Batch ${PYTHON_LIBRARIES})
 
 INSTALL(TARGETS ${SWIG_MODULE_libBatch_Swig_REAL_NAME} DESTINATION lib/python${PYTHON_VERSION}/site-packages)
 INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libBatch_Swig.py
         DESTINATION lib/python${PYTHON_VERSION}/site-packages)
-INSTALL(FILES Batch_PyVersatile.hxx DESTINATION include/Batch)
 
 SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES libBatch_Swig.py)
 
index e4fea7dd9d871b412015162bc5477f8d4ab9df1a..d6a95751c8d2a28b62deab5929d514b4fd7dc54c 100644 (file)
 #include <string>
 #include <list>
 #include <map>
+#include "Batch_ParameterTypeMap.hxx"
 #include "Batch_Parametre.hxx"
-#include "Batch_PyVersatile.hxx"
 #include "Batch_JobId.hxx"
 #include "Batch_FactBatchManager.hxx"
-#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
-typedef int Py_ssize_t;
-#define PY_SSIZE_T_MAX INT_MAX
-#define PY_SSIZE_T_MIN INT_MIN
-#endif
+#include "Batch_RunTimeException.hxx"
 %}
 
 # // supprime toutes les definitions par defaut => sert au debug
 # %typemap(in) SWIGTYPE ;
 
+%{
+// Helper function to initialize a Batch::Versatile from a PyObj
+static bool initVersatile(Batch::Versatile & newVersatile, PyObject * input)
+{
+  if (PyList_Check(input)) { // c'est une liste
+    for (Py_ssize_t i=0; i<PyList_Size(input); i++) {
+      PyObject * val = PyList_GetItem(input, i);
+      if (PyString_Check(val)) {
+        newVersatile += PyString_AsString(val);
+
+      } else if (PyTuple_Check(val) &&
+          (PyTuple_Size(val) == 2) &&
+          PyString_Check( PyTuple_GetItem(val,0) ) &&
+          PyString_Check( PyTuple_GetItem(val,1) )   ) {
+        newVersatile += Batch::Couple( PyString_AsString( PyTuple_GetItem(val,0) ),
+                                       PyString_AsString( PyTuple_GetItem(val,1) )
+                                     );
+
+      } else {
+        PyErr_SetString(PyExc_RuntimeWarning, "initVersatile : invalid PyObject");
+        return false;
+      }
+    }
+
+  } else if (PyString_Check(input)) { // c'est une string
+    newVersatile = PyString_AsString(input);
+  } else if (PyInt_Check(input)) { // c'est un int
+    newVersatile = PyInt_AsLong(input);
+  } else if (PyBool_Check(input)) { // c'est un bool
+    newVersatile = (input == Py_True);
+  } else { // erreur
+    PyErr_SetString(PyExc_RuntimeWarning, "initVersatile : invalid PyObject");
+    return false;
+  }
+  return true;
+}
+
+// Helper function to create a PyObj from a Batch::Versatile
+static PyObject * versatileToPyObj(const Batch::Versatile & vers)
+{
+  PyObject * obj;
+
+  if (vers.getMaxSize() != 1) { // une liste
+    obj = PyList_New(0);
+    for(Batch::Versatile::const_iterator it=vers.begin(); it!=vers.end(); it++) {
+      std::string st;
+      Batch::Couple cp;
+      switch (vers.getType()) {
+      case Batch::LONG:
+        PyList_Append(obj, PyInt_FromLong(* static_cast<Batch::LongType *>(*it)));
+        break;
+
+      case Batch::STRING:
+        st = * static_cast<Batch::StringType *>(*it);
+        PyList_Append(obj, PyString_FromString(st.c_str()));
+        break;
+
+      case Batch::COUPLE:
+        cp = * static_cast<Batch::CoupleType *>(*it);
+        PyList_Append(obj, Py_BuildValue("(ss)", cp.getLocal().c_str(), cp.getRemote().c_str() ));
+        break;
+
+      default:
+        throw Batch::RunTimeException("Versatile object cannot be converted to Python object");
+      }
+
+    }
+
+  } else {
+    bool b;
+    std::string st;
+    Batch::Couple cp;
+    switch (vers.getType()) {
+    case Batch::BOOL:
+      b = (* static_cast<Batch::BoolType *>(vers.front()));
+      obj = PyBool_FromLong(b);
+      break;
+
+    case Batch::LONG:
+      obj = PyInt_FromLong(* static_cast<Batch::LongType *>(vers.front()));
+      break;
+
+    case Batch::STRING:
+      st = * static_cast<Batch::StringType *>(vers.front());
+      obj = PyString_FromString(st.c_str());
+      break;
+
+    case Batch::COUPLE:
+      cp = * static_cast<Batch::CoupleType *>(vers.front());
+      obj = Py_BuildValue("[(ss)]", cp.getLocal().c_str(), cp.getRemote().c_str() );
+      break;
+
+    default:
+      throw Batch::RunTimeException("Versatile object cannot be converted to Python object");
+    }
+  }
+
+  return obj;
+}
+
+// Helper function to initialize a Batch::Parametre from a PyObj
+static bool initParameter(Batch::Parametre & newParam, PyObject * input)
+{
+  if (!PyDict_Check(input)) {
+    PyErr_SetString(PyExc_ValueError, "Expected a dictionnary");
+    return false;
+  }
+
+  try {
+    // on itere sur toutes les clefs du dictionnaire, et on passe par la classe PyVersatile
+    // qui convertit un Versatile en PyObject et vice versa
+    PyObject *key, *value;
+    Py_ssize_t pos = 0;
+    while (PyDict_Next(input, &pos, &key, &value)) {
+      std::string mk = PyString_AsString(key);
+      bool res = initVersatile(newParam[mk], value);
+      if (!res)
+        return false;
+    }
+  }
+  catch (Batch::GenericException & ex) {
+      std::string msg = ex.type + " : " + ex.message;
+      PyErr_SetString(PyExc_RuntimeWarning, msg.c_str());
+      return false;
+  }
+  catch (...) {
+      PyErr_SetString(PyExc_RuntimeWarning, "unknown exception");
+      return false;
+  }
+  return true;
+}
+
+// Helper function to initialize a Batch::Environnement from a PyObj
+static bool initEnvironment(Batch::Environnement & newEnv, PyObject * input)
+{
+  if (!PyDict_Check(input)) {
+    PyErr_SetString(PyExc_ValueError, "Expected a dictionnary");
+    return false;
+  }
+
+  // on itere sur toutes les clefs du dictionnaire
+  PyObject *key, *value;
+  Py_ssize_t pos = 0;
+  while (PyDict_Next(input, &pos, &key, &value)) {
+    std::string mk  = PyString_AsString(key);
+    std::string val = PyString_AsString(value);
+    newEnv[mk] = val;
+  }
+  return true;
+}
+%}
 
 # // construction d'un dictionnaire Python a partir d'un objet BatchManagerCatalog C++
 %typemap(out) std::map<std::string, Batch::FactBatchManager *> *
@@ -73,78 +220,26 @@ typedef int Py_ssize_t;
   // on itere sur toutes les clefs de la map, et on passe par la classe PyVersatile
        // qui convertit un Versatile en PyObject et vice versa
   for(Batch::Parametre::const_iterator it=$1.begin(); it!=$1.end(); it++) {
-    std::string key = (*it).first;
-    Batch::PyVersatile PyV = (*it).second;
-    PyDict_SetItem($result, PyString_FromString(key.c_str()), PyV);
+    const std::string & key = (*it).first;
+    const Batch::Versatile & vers = (*it).second;
+    PyDict_SetItem($result, PyString_FromString(key.c_str()), versatileToPyObj(vers));
   }
 }
 
-
-# // construction d'un objet Parametre C++ a partir d'un dictionnaire Python
-%typemap(in) Batch::Parametre & (Batch::Parametre PM)
+// Build a C++ object Batch::Parametre from a Python dictionary
+%typemap(in) const Batch::Parametre & (Batch::Parametre PM)
 {
-  if (!PyDict_Check($input)) {
-    PyErr_SetString(PyExc_ValueError,"Expected a dictionnary");
+  bool res = initParameter(PM, $input);
+  if (res)
+    $1 = &PM;
+  else
     return NULL;
-  }
-
-  try {        
-  // on itere sur toutes les clefs du dictionnaire, et on passe par la classe PyVersatile
-       // qui convertit un Versatile en PyObject et vice versa
-       PyObject *key, *value;
-       Py_ssize_t pos = 0;
-       while (PyDict_Next($input, &pos, &key, &value)) {
-               std::string mk = PyString_AsString(key);
-               Batch::PyVersatile PyV = value;
-               PyV.setName(mk);
-               PM[mk] = PyV;
-       }
-
-  $1 = &PM; // $1 est une reference donc on lui passe une adresse
-  }
-  catch (Batch::GenericException & ex) {
-      std::string msg = ex.type + " : " + ex.message;
-      PyErr_SetString(PyExc_RuntimeWarning, msg.c_str());
-      return NULL;
-  }
-  catch (...) {
-      PyErr_SetString(PyExc_RuntimeWarning, "unknown exception");
-      return NULL;
-  }
 }
 
-
-# // construction d'un objet Parametre C++ a partir d'un dictionnaire Python
-%typemap(in) Batch::Parametre (Batch::Parametre PM)
+%typemap(in) Batch::Parametre
 {
-  if (!PyDict_Check($input)) {
-    PyErr_SetString(PyExc_ValueError,"Expected a dictionnary");
-    return NULL;
-  }
-
-  try {
-  // on itere sur toutes les clefs du dictionnaire, et on passe par la classe PyVersatile
-       // qui convertit un Versatile en PyObject et vice versa
-       PyObject *key, *value;
-       Py_ssize_t pos = 0;
-       while (PyDict_Next($input, &pos, &key, &value)) {
-               std::string mk = PyString_AsString(key);
-               Batch::PyVersatile PyV = value;
-               PyV.setName(mk);
-               PM[mk] = PyV;
-       }
-
-  $1 = PM;
-  }
-  catch (Batch::GenericException & ex) {
-      std::string msg = ex.type + " : " + ex.message;
-      PyErr_SetString(PyExc_RuntimeWarning, msg.c_str());
-      return NULL;
-  }
-  catch (...) {
-      PyErr_SetString(PyExc_RuntimeWarning, "unknown exception");
-      return NULL;
-  }
+  bool res = initParameter($1, $input);
+  if (!res) return NULL;
 }
 
 %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) Batch::Environnement
@@ -167,47 +262,20 @@ typedef int Py_ssize_t;
   }
 }
 
-
-# // construction d'un objet Environnement C++ a partir d'un dictionnaire Python
-%typemap(in) Batch::Environnement & (Batch::Environnement E)
+// Build a C++ object Batch::Environnement from a Python dictionary
+%typemap(in) const Batch::Environnement & (Batch::Environnement E)
 {
-  if (!PyDict_Check($input)) {
-    PyErr_SetString(PyExc_ValueError,"Expected a dictionnary");
+  bool res = initEnvironment(E, $input);
+  if (res)
+    $1 = &E;
+  else
     return NULL;
-  }
-
-       // on itere sur toutes les clefs du dictionnaire
-       PyObject *key, *value;
-       Py_ssize_t pos = 0;
-       while (PyDict_Next($input, &pos, &key, &value)) {
-               std::string mk  = PyString_AsString(key);
-               std::string val = PyString_AsString(value);
-               E[mk] = val;
-       }
-  
-  $1 = &E; // $1 est une reference donc on lui passe une adresse
 }
 
-
-
-# // construction d'un objet Environnement C++ a partir d'un dictionnaire Python
-%typemap(in) Batch::Environnement (Batch::Environnement E)
+%typemap(in) Batch::Environnement
 {
-  if (!PyDict_Check($input)) {
-    PyErr_SetString(PyExc_ValueError,"Expected a dictionnary");
-    return NULL;
-  }
-
-       // on itere sur toutes les clefs du dictionnaire
-       PyObject *key, *value;
-       Py_ssize_t pos = 0;
-       while (PyDict_Next($input, &pos, &key, &value)) {
-               std::string mk  = PyString_AsString(key);
-               std::string val = PyString_AsString(value);
-               E[mk] = val;
-       }
-  
-  $1 = E;
+  bool res = initEnvironment($1, $input);
+  if (!res) return NULL;
 }
 
 // Dynamic cast to FactBatchManager_eClient if necessary
index c6bcbc8f486203a543baddcb0db70c6de347f50f..e677509a17cbb82551bd1617ea3695191eb59a06 100644 (file)
@@ -150,10 +150,14 @@ namespace Batch {
     int nbproc = 1;
     if (params.find(NBPROC) != params.end())
       nbproc = params[NBPROC];
+    tempOutputFile << "#SBATCH --ntasks=" << nbproc << endl;
 
-    int nodes_requested = (nbproc + _nb_proc_per_node -1) / _nb_proc_per_node;
-    tempOutputFile << "#SBATCH --nodes=" << nodes_requested << endl;
-    tempOutputFile << "#SBATCH --ntasks-per-node=" << _nb_proc_per_node << endl;
+    if (params.find(EXCLUSIVE) != params.end()) {
+      if (params[EXCLUSIVE])
+        tempOutputFile << "#SBATCH --exclusive" << endl;
+      else
+        tempOutputFile << "#SBATCH --share" << endl;
+    }
 
     if (params.find(MAXWALLTIME) != params.end())
       tempOutputFile << "#SBATCH --time=" << params[MAXWALLTIME] << endl;
@@ -177,6 +181,9 @@ namespace Batch {
     tempOutputFile << "cd " << workDir << endl;
     tempOutputFile << "./" + fileNameToExecute << endl;
 
+    // Remove the node file
+    tempOutputFile << "rm $LIBBATCH_NODEFILE" << endl;
+
     tempOutputFile.flush();
     tempOutputFile.close();
 
index 1726db70dcea9e9c22bce08fce0bd0d093bfe721..09ff90c9170e434964df32a7bf4b7105a555987c 100644 (file)
@@ -100,6 +100,7 @@ int main(int argc, char** argv)
     p[MAXWALLTIME]   = 1;
     p[MAXRAMSIZE]    = 50;
     p[HOMEDIR]       = homedir;
+    p[EXCLUSIVE]     = true;
     job.setParametre(p);
     // ... and its environment
     Environnement e;