add_subdirectory (LSF)
add_subdirectory (PBS)
add_subdirectory (SGE)
+add_subdirectory (SSH)
# Make a copy of the built value and clear the built value for the next run of cmake
SET(SRC_FILES ${SRC_FILES_BUILD} CACHE INTERNAL "")
add_library (Batch SHARED ${SRC_FILES})
include_directories(${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Core)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Local)
target_link_libraries(Batch ${PTHREAD_LIBRARY})
IF (WIN32)
#include <fstream>
#include <sstream>
+#include <stdlib.h>
+
#ifdef WIN32
#include <direct.h>
#include <io.h>
// Destructeur
BatchManager_eClient::~BatchManager_eClient()
{
- delete _mpiImpl;
+ if (_mpiImpl)
+ delete _mpiImpl;
}
void BatchManager_eClient::exportInputFiles(const Job& job)
Versatile::iterator Vit;
_username = string(params[USER]);
- string subCommand = string("mkdir -p ") + string(params[TMPDIR]);
+ string subCommand = string("mkdir -p ") + string(params[TMPDIR]) + string("/logs");
string command = _protocol.getExecCommand(subCommand, _hostname, _username);
cerr << command.c_str() << endl;
status = system(command.c_str());
Parametre params = job.getParametre();
Versatile V = params[OUTFILE];
Versatile::iterator Vit;
+ _username = string(params[USER]);
for(Vit=V.begin(); Vit!=V.end(); Vit++) {
CoupleType cpt = *static_cast< CoupleType * >(*Vit);
}
}
+ // Copy logs
+ int status = _protocol.copyFile(string(params[TMPDIR]) + string("/logs"), _hostname, _username,
+ directory, "", "");
+ if (status) {
+ std::string mess("Copy logs directory failed ! status is :");
+ ostringstream status_str;
+ status_str << status;
+ mess += status_str.str();
+ cerr << mess << endl;
+ }
+
}
MpiImpl *BatchManager_eClient::FactoryMpiImpl(string mpiImpl) throw(EmulationException)
else if(mpiImpl == "prun")
return new MpiImpl_PRUN();
else if(mpiImpl == "nompi")
- throw EmulationException("you must specify an mpi implementation for batch manager");
+ return NULL;
else{
ostringstream oss;
oss << mpiImpl << " : not yet implemented";
class Job;
- class BATCH_EXPORT BatchManager_eClient : public BatchManager
+ class BATCH_EXPORT BatchManager_eClient : virtual public BatchManager
{
public:
// Constructeur et destructeur
#include <stdlib.h>
#include <iostream>
+#include <stdlib.h>
#include <Batch_config.h>
for (unsigned int i=0 ; i<commandArgs.size() ; i++) {
if (i != 0) commandStr += " ";
- // if the argument contains spaces, we surround it with double quotes
+ // if the argument contains spaces, we surround it with quotes
if (commandArgs[i].find(' ') != string::npos) {
- commandStr += string("\"") + commandArgs[i] + "\"";
+ commandStr += string("\'") + commandArgs[i] + "\'";
} else {
commandStr += commandArgs[i];
}
fullDestination += destinationPath;
cmd.push_back(RCP_COMMAND);
+ cmd.push_back("-r");
cmd.push_back(fullSource);
cmd.push_back(fullDestination);
{
vector<string> cmd;
cmd.push_back(CP_COMMAND);
+#ifndef WIN32
+ cmd.push_back("-r");
+#endif
cmd.push_back(fixPath(sourcePath));
cmd.push_back(fixPath(destinationPath));
return cmd;
if (sourceUser.size() != 0) {
fullSource += sourceUser + "@";
}
- fullSource += sourceHost + ":";
+ fullSource += sourceHost + ":'";
}
fullSource += sourcePath;
+ if (sourceHost.size() != 0)
+ fullSource += "'";
string fullDestination;
if (destinationHost.size() != 0) {
if (destinationUser.size() != 0) {
fullDestination += destinationUser + "@";
}
- fullDestination += destinationHost + ":";
+ fullDestination += destinationHost + ":'";
}
fullDestination += destinationPath;
+ if (destinationHost.size() != 0)
+ fullDestination += "'";
// Option -p is used to keep the same permissions for the destination file
// (particularly useful to keep scripts executable when copying them)
cmd.push_back(SCP_COMMAND);
cmd.push_back("-p");
+ cmd.push_back("-r");
cmd.push_back(fullSource);
cmd.push_back(fullDestination);
# define BATCH_EXPORT
#endif
+#ifdef WIN32
+#define BATCH_CHMOD(name, mode) _chmod(name, mode)
+#else
+#define BATCH_CHMOD(name, mode) chmod(name, mode)
+#endif
+
#endif
virtual Batch::BatchManager_eClient * operator() (const char * hostname,
CommunicationProtocolType protocolType,
- const char * mpi) const = 0;
+ const char * mpi,
+ int nb_proc_per_node = 1) const = 0;
protected:
std::string getName() const;
void setName(const std::string & name);
- protected:
// 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
ostream & operator <<(ostream & os, const SimpleParser & parser) throw()
{
- os << "Configuration map:" << endl;
if (parser._configmap.empty()) {
os << "Empty map" << endl;
} else {
}
// Print the configuration
+ cout << "Configuration map:" << endl;
cout << parser << endl;
return 0;
#include <string>
#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+
#ifdef WIN32
#include <io.h>
#else
BatchManager_eLSF::BatchManager_eLSF(const FactBatchManager * parent, const char * host,
CommunicationProtocolType protocolType, const char * mpiImpl)
- : BatchManager_eClient(parent, host, protocolType, mpiImpl)
+ : BatchManager_eClient(parent, host, protocolType, mpiImpl),
+ BatchManager(parent, host)
{
// Nothing to do
}
{
int status;
Parametre params = job.getParametre();
- const std::string dirForTmpFiles = params[TMPDIR];
+ const std::string workDir = params[WORKDIR];
const string fileToExecute = params[EXECUTABLE];
- std::string fileNameToExecute;
- if( fileToExecute.size() > 0 ){
- string::size_type p1 = fileToExecute.find_last_of("/");
- string::size_type p2 = fileToExecute.find_last_of(".");
- fileNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
- }
- else
- fileNameToExecute = "command";
+ string::size_type p1 = fileToExecute.find_last_of("/");
+ string::size_type p2 = fileToExecute.find_last_of(".");
+ std::string fileNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
// export input files on cluster
+ cerr << "Export des fichiers en entree" << endl;
exportInputFiles(job);
// build batch script for job
+ cerr << "Construction du script de batch" << endl;
buildBatchScript(job);
+ cerr << "Script envoye" << endl;
// define name of log file (local)
string logFile = generateTemporaryFileName("LSF-submitlog");
// define command to submit batch
- string subCommand = string("cd ") + dirForTmpFiles + "; bsub < " +
- fileNameToExecute + "_Batch.sh";
+ string subCommand = string("cd ") + workDir + "; bsub < " + fileNameToExecute + "_Batch.sh";
string command = _protocol.getExecCommand(subCommand, _hostname, _username);
command += " > ";
command += logFile;
+ command += " 2>&1";
cerr << command.c_str() << endl;
status = system(command.c_str());
if(status)
- throw EmulationException("Error of connection on remote host");
+ {
+ ifstream error_message(logFile.c_str());
+ std::string mess;
+ std::string temp;
+ while(std::getline(error_message, temp))
+ mess += temp;
+ error_message.close();
+ throw EmulationException("Error of connection on remote host, error was: " + mess);
+ }
// read id of submitted job in log file
char line[128];
{
#ifndef WIN32 //TODO: need for porting on Windows
Parametre params = job.getParametre();
- Environnement env = job.getEnvironnement();
- const int nbproc = params[NBPROC];
- const long edt = params[MAXWALLTIME];
- const long mem = params[MAXRAMSIZE];
- const string workDir = params[WORKDIR];
- const std::string dirForTmpFiles = params[TMPDIR];
- const string fileToExecute = params[EXECUTABLE];
- const string home = params[HOMEDIR];
- const std::string queue = params[QUEUE];
- std::string rootNameToExecute;
- std::string fileNameToExecute;
- std::string filelogtemp;
- if( fileToExecute.size() > 0 ){
- string::size_type p1 = fileToExecute.find_last_of("/");
- string::size_type p2 = fileToExecute.find_last_of(".");
- rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
- char* basec=strdup(fileToExecute.c_str());
- fileNameToExecute = "~/" + dirForTmpFiles + "/" + string(basename(basec));
- free(basec);
-
- int idx = dirForTmpFiles.find("Batch/");
- filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
- }
- else{
- rootNameToExecute = "command";
- }
+ // Job Parameters
+ string workDir = "";
+ string fileToExecute = "";
+ int nbproc = 0;
+ int edt = 0;
+ int mem = 0;
+ string queue = "";
+
+ // Mandatory parameters
+ if (params.find(WORKDIR) != params.end())
+ workDir = params[WORKDIR].str();
+ else
+ throw EmulationException("params[WORKDIR] is not defined ! Please defined it, cannot submit this job");
+ if (params.find(EXECUTABLE) != params.end())
+ fileToExecute = params[EXECUTABLE].str();
+ else
+ throw EmulationException("params[EXECUTABLE] is not defined ! Please defined it, cannot submit this job");
+
+ // Optional parameters
+ if (params.find(NBPROC) != params.end())
+ nbproc = params[NBPROC];
+ if (params.find(MAXWALLTIME) != params.end())
+ edt = params[MAXWALLTIME];
+ if (params.find(MAXRAMSIZE) != params.end())
+ mem = params[MAXRAMSIZE];
+ if (params.find(QUEUE) != params.end())
+ queue = params[QUEUE].str();
+
+ string::size_type p1 = fileToExecute.find_last_of("/");
+ string::size_type p2 = fileToExecute.find_last_of(".");
+ string rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+ string fileNameToExecute = fileToExecute.substr(p1+1);
+
+ // Create batch submit file
ofstream tempOutputFile;
std::string TmpFileName = createAndOpenTemporaryFile("LSF-script", tempOutputFile);
if( mem > 0 )
tempOutputFile << "#BSUB -M " << mem*1024 << endl ;
tempOutputFile << "#BSUB -n " << nbproc << endl ;
- if( fileToExecute.size() > 0 ){
- tempOutputFile << "#BSUB -o " << home << "/" << dirForTmpFiles << "/output.log." << filelogtemp << endl ;
- tempOutputFile << "#BSUB -e " << home << "/" << dirForTmpFiles << "/error.log." << filelogtemp << endl ;
- }
- else{
- tempOutputFile << "#BSUB -o " << dirForTmpFiles << "/" << env["LOGFILE"] << ".output.log" << endl ;
- tempOutputFile << "#BSUB -e " << dirForTmpFiles << "/" << env["LOGFILE"] << ".error.log" << endl ;
- }
- if( workDir.size() > 0 )
- tempOutputFile << "cd " << workDir << endl ;
- if( fileToExecute.size() > 0 ){
- tempOutputFile << _mpiImpl->boot("",nbproc);
- tempOutputFile << _mpiImpl->run("",nbproc,fileNameToExecute);
- tempOutputFile << _mpiImpl->halt();
- }
+ size_t pos = workDir.find("$HOME");
+ string baseDir;
+ if( pos != string::npos )
+ baseDir = getHomeDir(workDir) + workDir.substr(pos+5,workDir.length()-5);
else{
- tempOutputFile << "source " << env["SOURCEFILE"] << endl ;
- tempOutputFile << env["COMMAND"];
+ pos = workDir.find("~");
+ if( pos != string::npos )
+ baseDir = getHomeDir(workDir) + workDir.substr(pos+1,workDir.length()-1);
+ else
+ baseDir = workDir;
}
-
+ tempOutputFile << "#BSUB -o " << baseDir << "/logs/output.log." << rootNameToExecute << endl ;
+ tempOutputFile << "#BSUB -e " << baseDir << "/logs/error.log." << rootNameToExecute << endl ;
+
+ tempOutputFile << "cd " << workDir << endl ;
+
+ // generate nodes file
+ tempOutputFile << "bool=0" << endl;
+ tempOutputFile << "for i in $LSB_MCPU_HOSTS; do" << endl;
+ tempOutputFile << " if test $bool = 0; then" << endl;
+ tempOutputFile << " n=$i" << endl;
+ tempOutputFile << " bool=1" << endl;
+ tempOutputFile << " else" << endl;
+ tempOutputFile << " for ((j=0;j<$i;j++)); do" << endl;
+ tempOutputFile << " echo $n >> nodesFile" << endl;
+ tempOutputFile << " done" << endl;
+ tempOutputFile << " bool=0" << endl;
+ tempOutputFile << " fi" << endl;
+ tempOutputFile << "done" << endl;
+
+ // Abstraction of PBS_NODEFILE - TODO
+ tempOutputFile << "export LIBBATCH_NODEFILE=nodesFile" << endl;
+
+ // Launch the executable
+ tempOutputFile << "./" + fileNameToExecute << endl;
tempOutputFile.flush();
tempOutputFile.close();
-#ifdef WIN32
- _chmod(
-#else
- chmod(
-#endif
- TmpFileName.c_str(), 0x1ED);
- cerr << TmpFileName.c_str() << endl;
+
+ BATCH_CHMOD(TmpFileName.c_str(), 0x1ED);
+ cerr << "Batch script file generated is: " << TmpFileName.c_str() << endl;
int status = _protocol.copyFile(TmpFileName, "", "",
- dirForTmpFiles + "/" + rootNameToExecute + "_Batch.sh",
+ workDir + "/" + rootNameToExecute + "_Batch.sh",
_hostname, _username);
if (status)
throw EmulationException("Error of connection on remote host");
- remove(TmpFileName.c_str());
#endif
}
return oss.str();
}
+ std::string BatchManager_eLSF::getHomeDir(std::string tmpdir)
+ {
+ std::string home;
+ int idx = tmpdir.find("Batch/");
+ std::string filelogtemp = tmpdir.substr(idx+6, tmpdir.length());
+ filelogtemp = "/tmp/logs" + filelogtemp + "_home";
+
+ string subCommand = string("echo $HOME");
+ string command = _protocol.getExecCommand(subCommand, _hostname, _username) + " > " + filelogtemp;
+ cerr << command.c_str() << endl;
+ int status = system(command.c_str());
+ if (status)
+ throw EmulationException("Error of launching home command on remote host");
+
+ std::ifstream file_home(filelogtemp.c_str());
+ std::getline(file_home, home);
+ file_home.close();
+ return home;
+ }
+
}
private:
+ std::string getHomeDir(std::string tmpdir);
+
#ifdef SWIG
public:
// Recupere le l'identifiant d'un job deja soumis au BatchManager
BatchManager_eClient * FactBatchManager_eLSF::operator() (const char * hostname,
CommunicationProtocolType protocolType,
- const char * mpiImpl) const
+ const char * mpiImpl,
+ int nb_proc_per_node) const
{
// MESSAGE("Building new BatchManager_LSF on host '" << hostname << "'");
return new BatchManager_eLSF(this, hostname, protocolType, mpiImpl);
virtual BatchManager * operator() (const char * hostname) const;
virtual BatchManager_eClient * operator() (const char * hostname,
CommunicationProtocolType protocolType,
- const char * mpiImpl) const;
+ const char * mpiImpl,
+ int nb_proc_per_node = 1) const;
protected:
string local = cp.getLocal();
string remote = cp.getRemote();
+ std::cerr << workdir << std::endl;
+ std::cerr << remote << std::endl;
+
int status = p_ta->getBatchManager().getProtocol().copyFile(local, "", "",
workdir + "/" + remote,
executionhost, user);
// On forke/exec un nouveau process pour pouvoir controler le fils
// (plus finement qu'avec un appel system)
// int rc = system(commande.c_str());
+ //char *const parmList[] = {"/usr/bin/ssh", "localhost", "-l", "aribes", "sleep 10 && echo end", NULL};
+ //execv("/usr/bin/ssh", parmList);
#ifdef WIN32
child = p_ta->launchWin32ChildProcess();
p_ta->pere(child);
int child_rc = 0;
pid_t child_wait_rc = waitpid(child, &child_rc, WNOHANG /* | WUNTRACED */);
if (child_wait_rc > 0) {
+ UNDER_LOCK( cout << "Status is: " << WIFEXITED( child_rc) << endl);
+ UNDER_LOCK( cout << "Status is: " << WEXITSTATUS( child_rc) << endl);
+ UNDER_LOCK( cout << "Status is: " << WIFSIGNALED( child_rc) << endl);
+ UNDER_LOCK( cout << "Status is: " << WTERMSIG( child_rc) << endl);
+ UNDER_LOCK( cout << "Status is: " << WCOREDUMP( child_rc) << endl);
+ UNDER_LOCK( cout << "Status is: " << WIFSTOPPED( child_rc) << endl);
+ UNDER_LOCK( cout << "Status is: " << WSTOPSIG( child_rc) << endl);
+ UNDER_LOCK( cout << "Status is: " << WIFCONTINUED( child_rc) << endl);
if (WIFSTOPPED(child_rc)) {
// NOTA : pour rentrer dans cette section, il faut que le flag WUNTRACED
// soit positionne dans l'appel a waitpid ci-dessus. Ce flag est couramment
Parametre param = _job.getParametre();
Parametre::iterator it;
+ //char *const parmList[] = {"/usr/bin/ssh", "localhost", "-l", "aribes", "sleep 1 && echo end", NULL};
+ //int result = execv("/usr/bin/ssh", parmList);
+ //UNDER_LOCK( cout << "*** debug_command = " << result << endl );
+ //UNDER_LOCK( cout << "*** debug_command = " << strerror(errno) << endl );
try {
// EXECUTABLE is MANDATORY, if missing, we exit with failure notification
argv[command.size()] = NULL;
UNDER_LOCK( cout << "*** debug_command = " << comstr << endl );
+ UNDER_LOCK( cout << "*** debug_command = " << argv[0] << endl );
// Create the environment for the new process. Note (RB): Here we change the environment for
// the process launched in local. It would seem more logical to set the environment for the
envp[i] = NULL;
}
+ //char *const parmList[] = {"/usr/bin/ssh", "localhost", "-l", "aribes", "sleep 1 && echo end", NULL};
+ //int result = execv("/usr/bin/ssh", parmList);
+ //UNDER_LOCK( cout << "*** debug_command = " << result << endl );
+ //UNDER_LOCK( cout << "*** debug_command = " << strerror(errno) << endl );
}
+ //char *const parmList[] = {"/usr/bin/ssh", "localhost", "-l", "aribes", "sleep 1 && echo end", NULL};
+ //int result = execv("/usr/bin/ssh", parmList);
+ //UNDER_LOCK( cout << "*** debug_command = " << result << endl );
+ //UNDER_LOCK( cout << "*** debug_command = " << strerror(errno) << endl );
// On cree une session pour le fils de facon a ce qu'il ne soit pas
// detruit lorsque le shell se termine (le shell ouvre une session et
// On execute la commande du fils
- execve(argv[0], argv, envp);
-
+ int result = execve(argv[0], argv, envp);
+ UNDER_LOCK( cout << "*** debug_command = " << strerror(errno) << endl );
// No need to deallocate since nothing happens after a successful exec
// Normalement on ne devrait jamais arriver ici
class FactBatchManager;
- class BATCH_EXPORT BatchManager_Local : public BatchManager
+ class BATCH_EXPORT BatchManager_Local : virtual public BatchManager
{
private:
#ifdef WIN32
/*
* BatchManager_ePBS.cxx : emulation of PBS client
*
- * Auteur : Bernard SECHER - CEA DEN
+ * Auteur : Bernard SECHER - CEA DEN, André RIBES - EDF R&D
* Mail : mailto:bernard.secher@cea.fr
* Date : Thu Apr 24 10:17:22 2008
* Projet : PAL Salome
#include <sstream>
#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
#include <Batch_config.h>
#ifdef MSVC
namespace Batch {
BatchManager_ePBS::BatchManager_ePBS(const FactBatchManager * parent, const char * host,
- CommunicationProtocolType protocolType, const char * mpiImpl)
- : BatchManager_eClient(parent, host, protocolType, mpiImpl)
+ CommunicationProtocolType protocolType, const char * mpiImpl,
+ int nb_proc_per_node)
+ : BatchManager_eClient(parent, host, protocolType, mpiImpl),
+ BatchManager(parent, host)
{
// Nothing to do
+ _nb_proc_per_node = nb_proc_per_node;
}
// Destructeur
{
int status;
Parametre params = job.getParametre();
- const std::string dirForTmpFiles = params[TMPDIR];
+ const std::string workDir = params[WORKDIR];
const string fileToExecute = params[EXECUTABLE];
string::size_type p1 = fileToExecute.find_last_of("/");
string::size_type p2 = fileToExecute.find_last_of(".");
string logFile = generateTemporaryFileName("PBS-submitlog");
// define command to submit batch
- string subCommand = string("cd ") + dirForTmpFiles + "; qsub " +
- fileNameToExecute + "_Batch.sh";
+ string subCommand = string("cd ") + workDir + "; qsub " + fileNameToExecute + "_Batch.sh";
string command = _protocol.getExecCommand(subCommand, _hostname, _username);
command += " > ";
command += logFile;
+ command += " 2>&1";
cerr << command.c_str() << endl;
status = system(command.c_str());
if(status)
- throw EmulationException("Error of connection on remote host");
+ {
+ ifstream error_message(logFile.c_str());
+ std::string mess;
+ std::string temp;
+ while(std::getline(error_message, temp))
+ mess += temp;
+ error_message.close();
+ throw EmulationException("Error of connection on remote host, error was: " + mess);
+ }
// read id of submitted job in log file
ifstream idfile(logFile.c_str());
void BatchManager_ePBS::buildBatchScript(const Job & job)
{
+ std::cerr << "BuildBatchScript" << std::endl;
Parametre params = job.getParametre();
Environnement env = job.getEnvironnement();
- const long nbproc = params[NBPROC];
- const long edt = params[MAXWALLTIME];
- const long mem = params[MAXRAMSIZE];
- const string workDir = params[WORKDIR];
- const std::string dirForTmpFiles = params[TMPDIR];
- const string fileToExecute = params[EXECUTABLE];
- const string home = params[HOMEDIR];
- const std::string queue = params[QUEUE];
- std::string rootNameToExecute;
- std::string fileNameToExecute;
- std::string filelogtemp;
- if( fileToExecute.size() > 0 ){
- string::size_type p1 = fileToExecute.find_last_of("/");
- string::size_type p2 = fileToExecute.find_last_of(".");
- rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
-
-#ifdef MSVC
- char fname[_MAX_FNAME];
- char ext[_MAX_EXT];
- _splitpath_s(fileToExecute.c_str(), NULL, 0, NULL, 0, fname, _MAX_FNAME, ext, _MAX_EXT);
- string execBaseName = string(fname) + ext;
-#else
- char* basec=strdup(fileToExecute.c_str());
- string execBaseName = string(basename(basec));
- free(basec);
-#endif
- fileNameToExecute = "~/" + dirForTmpFiles + "/" + execBaseName;
+ // Job Parameters
+ string workDir = "";
+ string fileToExecute = "";
+ int nbproc = 0;
+ int edt = 0;
+ int mem = 0;
+ string queue = "";
+
+ // Mandatory parameters
+ if (params.find(WORKDIR) != params.end())
+ workDir = params[WORKDIR].str();
+ else
+ throw EmulationException("params[WORKDIR] is not defined ! Please defined it, cannot submit this job");
+ if (params.find(EXECUTABLE) != params.end())
+ fileToExecute = params[EXECUTABLE].str();
+ else
+ throw EmulationException("params[EXECUTABLE] is not defined ! Please defined it, cannot submit this job");
+
+ // Optional parameters
+ if (params.find(NBPROC) != params.end())
+ nbproc = params[NBPROC];
+ if (params.find(MAXWALLTIME) != params.end())
+ edt = params[MAXWALLTIME];
+ if (params.find(MAXRAMSIZE) != params.end())
+ mem = params[MAXRAMSIZE];
+ if (params.find(QUEUE) != params.end())
+ queue = params[QUEUE].str();
- int idx = dirForTmpFiles.find("Batch/");
- filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
- }
- else{
- rootNameToExecute = "command";
- }
+ string::size_type p1 = fileToExecute.find_last_of("/");
+ string::size_type p2 = fileToExecute.find_last_of(".");
+ string rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+ string fileNameToExecute = fileToExecute.substr(p1+1);
+ // Create batch submit file
ofstream tempOutputFile;
std::string TmpFileName = createAndOpenTemporaryFile("PBS-script", tempOutputFile);
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;
+ }
if (queue != "")
- tempOutputFile << "#BSUB -q " << queue << endl;
+ tempOutputFile << "#PBS -q " << queue << endl;
if( edt > 0 )
- tempOutputFile << "#PBS -l walltime=" << edt*60 << endl ;
+ tempOutputFile << "#PBS -l walltime=" << edt*60 << endl;
if( mem > 0 )
- tempOutputFile << "#PBS -l mem=" << mem << "mb" << endl ;
- if( fileToExecute.size() > 0 ){
- tempOutputFile << "#PBS -o " << home << "/" << dirForTmpFiles << "/output.log." << filelogtemp << endl ;
- tempOutputFile << "#PBS -e " << home << "/" << dirForTmpFiles << "/error.log." << filelogtemp << endl ;
- }
- else{
- tempOutputFile << "#PBS -o " << dirForTmpFiles << "/" << env["LOGFILE"] << ".output.log" << endl ;
- tempOutputFile << "#PBS -e " << dirForTmpFiles << "/" << env["LOGFILE"] << ".error.log" << endl ;
- }
- if( workDir.size() > 0 )
- tempOutputFile << "cd " << workDir << endl ;
- if( fileToExecute.size() > 0 ){
- tempOutputFile << _mpiImpl->boot("${PBS_NODEFILE}",nbproc);
- tempOutputFile << _mpiImpl->run("${PBS_NODEFILE}",nbproc,fileNameToExecute);
- tempOutputFile << _mpiImpl->halt();
- }
- else{
- tempOutputFile << "source " << env["SOURCEFILE"] << endl ;
- tempOutputFile << env["COMMAND"];
+ tempOutputFile << "#PBS -l mem=" << mem << "kb" << endl;
+ tempOutputFile << "#PBS -o " << workDir << "/logs/output.log." << rootNameToExecute << endl;
+ tempOutputFile << "#PBS -e " << workDir << "/logs/error.log." << rootNameToExecute << endl;
+
+ // Define environment for the job
+ if (!env.empty()) {
+ tempOutputFile << "#PBS -v ";
+ Environnement::const_iterator iter;
+ for (iter = env.begin() ; iter != env.end() ; ++iter) {
+ tempOutputFile << iter->first << "=" << iter->second << ",";
+ }
+ tempOutputFile << endl;
}
+ // Abstraction of PBS_NODEFILE - TODO
+ tempOutputFile << "export LIBBATCH_NODEFILE=$PBS_NODEFILE" << endl;
+
+ // Launch the executable
+ tempOutputFile << "cd " << workDir << endl;
+ tempOutputFile << "./" + fileNameToExecute << endl;
tempOutputFile.flush();
tempOutputFile.close();
-#ifdef WIN32
- _chmod(
-#else
- chmod(
-#endif
- TmpFileName.c_str(), 0x1ED);
- cerr << TmpFileName.c_str() << endl;
+
+ BATCH_CHMOD(TmpFileName.c_str(), 0x1ED);
+ cerr << "Batch script file generated is: " << TmpFileName.c_str() << endl;
int status = _protocol.copyFile(TmpFileName, "", "",
- dirForTmpFiles + "/" + rootNameToExecute + "_Batch.sh",
+ workDir + "/" + rootNameToExecute + "_Batch.sh",
_hostname, _username);
if (status)
- throw EmulationException("Error of connection on remote host");
-
- remove(TmpFileName.c_str());
+ throw EmulationException("Error of connection on remote host, cannot copy batch submission file");
}
-
}
public:
// Constructeur et destructeur
BatchManager_ePBS(const FactBatchManager * parent, const char * host="localhost",
- CommunicationProtocolType protocolType = SSH, const char * mpiImpl="nompi"); // connexion a la machine host
+ CommunicationProtocolType protocolType = SSH, const char * mpiImpl="nompi",
+ int nb_proc_per_node=1); // connexion a la machine host
virtual ~BatchManager_ePBS();
// Recupere le nom du serveur par defaut
void buildBatchScript(const Job & job);
private:
+ int _nb_proc_per_node;
#ifdef SWIG
public:
BatchManager_eClient * FactBatchManager_ePBS::operator() (const char * hostname,
CommunicationProtocolType protocolType,
- const char * mpiImpl) const
+ const char * mpiImpl,
+ int nb_proc_per_node) const
{
// MESSAGE("Building new BatchManager_PBS on host '" << hostname << "'");
- return new BatchManager_ePBS(this, hostname, protocolType, mpiImpl);
+ return new BatchManager_ePBS(this, hostname, protocolType, mpiImpl, nb_proc_per_node);
}
virtual BatchManager * operator() (const char * hostname) const;
virtual BatchManager_eClient * operator() (const char * hostname,
CommunicationProtocolType protocolType,
- const char * mpiImpl) const;
+ const char * mpiImpl,
+ int nb_proc_per_node = 1) const;
protected:
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Build the test programs and add the tests
+add_executable(Test_ePBS Test_ePBS.cxx)
+target_link_libraries(Test_ePBS Batch SimpleParser)
+
IF (HAS_SSH)
- add_executable(Test_ePBS_SSH Test_ePBS_SSH.cxx)
- target_link_libraries(Test_ePBS_SSH Batch SimpleParser)
- ADD_TEST(ePBS_SSH Test_ePBS_SSH)
+ ADD_TEST(ePBS_SSH Test_ePBS SSH)
ENDIF (HAS_SSH)
IF (HAS_RSH)
- add_executable(Test_ePBS_RSH Test_ePBS_RSH.cxx)
- target_link_libraries(Test_ePBS_RSH Batch SimpleParser)
- ADD_TEST(ePBS_RSH Test_ePBS_RSH)
+ ADD_TEST(ePBS_RSH Test_ePBS RSH)
ENDIF (HAS_RSH)
IF (BUILD_PBS_INTERFACE AND PBS_FOUND)
using namespace std;
using namespace Batch;
+const int MAX_SLEEP_TIME = 600;
+
int main(int argc, char** argv)
{
cout << "*******************************************************************************************" << endl;
job.setParametre(p);
// ... and its environment
Environnement e;
+ e["MYENVVAR"] = "MYVALUE";
job.setEnvironnement(e);
cout << job << endl;
cout << jobid.__repr__() << endl;
// Wait for the end of the job
- string state = "Undefined";
- for (int i=0 ; i<timeout/2 && state != "U" && state != "C"; i++) {
- sleep(2);
- JobInfo jinfo = jobid.queryJob();
+ int time = 0;
+ int sleeptime = 1;
+ bool testTimeout = (timeout > -1);
+ bool timeoutReached = (testTimeout && time >= timeout);
+ JobInfo jinfo = jobid.queryJob();
+ string state = jinfo.getParametre()["STATE"].str();
+ cout << "State is \"" << state << "\"";
+ while (!timeoutReached && state != "U" && state != "C") {
+ cout << ", sleeping " << sleeptime << "s..." << endl;
+ sleep(sleeptime);
+ time += sleeptime;
+ timeoutReached = (testTimeout && time >= timeout);
+ sleeptime *= 2;
+ if (testTimeout && sleeptime > timeout - time)
+ sleeptime = timeout - time;
+ if (sleeptime > MAX_SLEEP_TIME)
+ sleeptime = MAX_SLEEP_TIME;
+ jinfo = jobid.queryJob();
state = jinfo.getParametre()["STATE"].str();
- cout << "State is \"" << state << "\"" << endl;
+ cout << "State is \"" << state << "\"";
}
+ cout << endl;
if (state == "U" || state == "C") {
cout << "Job " << jobid.__repr__() << " is done" << endl;
}
// test the result file
- string exp = "c = 12";
- string res;
- ifstream f("result.txt");
- getline(f, res);
- f.close();
-
- cout << "result found : " << res << ", expected : " << exp << endl;
-
- if (res == exp)
- return 0;
- else
+ try {
+ SimpleParser resultParser;
+ resultParser.parse("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;
+ }
}
--- /dev/null
+// Copyright (C) 2007-2008 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_ePBS.cxx :
+ *
+ * Author : Renaud BARATE - EDF R&D
+ * Date : April 2009
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+
+#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>
+
+#ifdef WIN32
+#include <Windows.h>
+#define sleep(seconds) Sleep((seconds)*1000)
+#define usleep(useconds) Sleep((useconds)/1000)
+#endif
+
+using namespace std;
+using namespace Batch;
+
+const int MAX_SLEEP_TIME = 600;
+
+void print_usage()
+{
+ cout << "usage: Test_ePBS 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 PBS emulation. Passwordless authentication" << endl;
+ cout << "must be used for this test to pass. For SSH, this can be configured with ssh-agent for" << endl;
+ cout << "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_EPBS_HOMEDIR");
+ const string & host = parser.getValue("TEST_EPBS_HOST");
+ const string & user = parser.getValue("TEST_EPBS_USER");
+ const string & queue = parser.getValue("TEST_EPBS_QUEUE");
+ int timeout = parser.getValueAsInt("TEST_EPBS_TIMEOUT");
+
+ // Define the job...
+ Job job;
+ // ... and its parameters ...
+ Parametre p;
+ p["EXECUTABLE"] = "./test-script.sh";
+ p["NAME"] = string("Test_ePBS_") + 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["USER"] = user;
+ p["NBPROC"] = 1;
+ p["MAXWALLTIME"] = 1;
+ p["MAXRAMSIZE"] = 1000;
+ p["HOMEDIR"] = homedir;
+ p["QUEUE"] = queue;
+ 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("ePBS"));
+ BatchManager_eClient * bm = (*fbm)(host.c_str(), protocol, "lam");
+
+ // Submit the job to the BatchManager
+ JobId jobid = bm->submitJob(job);
+ cout << jobid.__repr__() << endl;
+
+ // Wait for the end of the job
+ int time = 0;
+ int sleeptime = 1;
+ bool testTimeout = (timeout > -1);
+ bool timeoutReached = (testTimeout && time >= timeout);
+ JobInfo jinfo = jobid.queryJob();
+ string state = jinfo.getParametre()["STATE"].str();
+ cout << "State is \"" << state << "\"";
+ while (!timeoutReached && state != "U" && state != "C") {
+ cout << ", sleeping " << sleeptime << "s..." << endl;
+ sleep(sleeptime);
+ time += sleeptime;
+ timeoutReached = (testTimeout && time >= timeout);
+ sleeptime *= 2;
+ if (testTimeout && sleeptime > timeout - time)
+ sleeptime = timeout - time;
+ if (sleeptime > MAX_SLEEP_TIME)
+ sleeptime = MAX_SLEEP_TIME;
+ jinfo = jobid.queryJob();
+ state = jinfo.getParametre()["STATE"].str();
+ cout << "State is \"" << state << "\"";
+ }
+ cout << endl;
+
+ if (state == "U" || state == "C") {
+ cout << "Job " << jobid.__repr__() << " is done" << endl;
+ bm->importOutputFiles(job, ".");
+ } 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("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;
+ }
+}
c=`expr $a "*" $b`
-echo "c = $c" > result.txt
+echo "MYENVVAR = $MYENVVAR" > result.txt
+echo "c = $c" >> result.txt
#include <fstream>
#include <sstream>
#include <sys/stat.h>
+
+#include <stdlib.h>
+#include <string.h>
+
#ifdef WIN32
#include <io.h>
#else
BatchManager_eSGE::BatchManager_eSGE(const FactBatchManager * parent, const char * host,
CommunicationProtocolType protocolType, const char * mpiImpl)
- : BatchManager_eClient(parent, host, protocolType, mpiImpl)
+ : BatchManager_eClient(parent, host, protocolType, mpiImpl),
+ BatchManager(parent, host)
{
// Nothing to do
}
{
int status;
Parametre params = job.getParametre();
- const std::string dirForTmpFiles = params[TMPDIR];
+ const std::string workDir = params[WORKDIR];
const string fileToExecute = params[EXECUTABLE];
string::size_type p1 = fileToExecute.find_last_of("/");
string::size_type p2 = fileToExecute.find_last_of(".");
string logFile = generateTemporaryFileName("SGE-submitlog");
// define command to submit batch
- string subCommand = string("cd ") + dirForTmpFiles + "; qsub " +
- fileNameToExecute + "_Batch.sh";
+ string subCommand = string("cd ") + workDir + "; qsub " + fileNameToExecute + "_Batch.sh";
string command = _protocol.getExecCommand(subCommand, _hostname, _username);
command += " > ";
command += logFile;
+ command += " 2>&1";
cerr << command.c_str() << endl;
status = system(command.c_str());
if(status)
- throw EmulationException("Error of connection on remote host");
+ {
+ ifstream error_message(logFile.c_str());
+ std::string mess;
+ std::string temp;
+ while(std::getline(error_message, temp))
+ mess += temp;
+ error_message.close();
+ throw EmulationException("Error of connection on remote host, error was: " + mess);
+ }
// read id of submitted job in log file
char line[128];
{
#ifndef WIN32
//TODO porting on Win32 platform
+ std::cerr << "BuildBatchScript" << std::endl;
Parametre params = job.getParametre();
- Environnement env = job.getEnvironnement();
- const long nbproc = params[NBPROC];
- const long edt = params[MAXWALLTIME];
- const long mem = params[MAXRAMSIZE];
- const string workDir = params[WORKDIR];
- const std::string dirForTmpFiles = params[TMPDIR];
- const string fileToExecute = params[EXECUTABLE];
- const string home = params[HOMEDIR];
- const std::string queue = params[QUEUE];
- std::string rootNameToExecute;
- std::string fileNameToExecute;
- std::string filelogtemp;
- if( fileToExecute.size() > 0 ){
- string::size_type p1 = fileToExecute.find_last_of("/");
- string::size_type p2 = fileToExecute.find_last_of(".");
- rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
- fileNameToExecute = "~/" + dirForTmpFiles + "/" + string(basename((char *) fileToExecute.c_str()));
-
- int idx = dirForTmpFiles.find("Batch/");
- filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
- }
- else{
- rootNameToExecute = "command";
- }
+ // Job Parameters
+ string workDir = "";
+ string fileToExecute = "";
+ int nbproc = 0;
+ int edt = 0;
+ int mem = 0;
+ string queue = "";
+
+ // Mandatory parameters
+ if (params.find(WORKDIR) != params.end())
+ workDir = params[WORKDIR].str();
+ else
+ throw EmulationException("params[WORKDIR] is not defined ! Please defined it, cannot submit this job");
+ if (params.find(EXECUTABLE) != params.end())
+ fileToExecute = params[EXECUTABLE].str();
+ else
+ throw EmulationException("params[EXECUTABLE] is not defined ! Please defined it, cannot submit this job");
+
+ // Optional parameters
+ if (params.find(NBPROC) != params.end())
+ nbproc = params[NBPROC];
+ if (params.find(MAXWALLTIME) != params.end())
+ edt = params[MAXWALLTIME];
+ if (params.find(MAXRAMSIZE) != params.end())
+ mem = params[MAXRAMSIZE];
+ if (params.find(QUEUE) != params.end())
+ queue = params[QUEUE].str();
+
+ string::size_type p1 = fileToExecute.find_last_of("/");
+ string::size_type p2 = fileToExecute.find_last_of(".");
+ string rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+ string fileNameToExecute = fileToExecute.substr(p1+1);
+
+ // Create batch submit file
ofstream tempOutputFile;
std::string TmpFileName = createAndOpenTemporaryFile("SGE-script", tempOutputFile);
tempOutputFile << "#$ -l h_rt=" << getWallTime(edt) << endl ;
if( mem > 0 )
tempOutputFile << "#$ -l h_vmem=" << mem << "M" << endl ;
- if( fileToExecute.size() > 0 ){
- tempOutputFile << "#$ -o " << home << "/" << dirForTmpFiles << "/output.log." << filelogtemp << endl ;
- tempOutputFile << "#$ -e " << home << "/" << dirForTmpFiles << "/error.log." << filelogtemp << endl ;
- }
- else{
- tempOutputFile << "#$ -o " << dirForTmpFiles << "/" << env["LOGFILE"] << ".output.log" << endl ;
- tempOutputFile << "#$ -e " << dirForTmpFiles << "/" << env["LOGFILE"] << ".error.log" << endl ;
- }
- if( workDir.size() > 0 )
- tempOutputFile << "cd " << workDir << endl ;
- if( fileToExecute.size() > 0 ){
- tempOutputFile << _mpiImpl->boot("",nbproc);
- tempOutputFile << _mpiImpl->run("${TMPDIR}/machines",nbproc,fileNameToExecute);
- tempOutputFile << _mpiImpl->halt();
- }
- else{
- tempOutputFile << "source " << env["SOURCEFILE"] << endl ;
- tempOutputFile << env["COMMAND"];
- }
+ tempOutputFile << "#$ -o " << workDir << "/logs/output.log." << rootNameToExecute << endl ;
+ tempOutputFile << "#$ -e " << workDir << "/logs/error.log." << rootNameToExecute << endl ;
+ // Abstraction of PBS_NODEFILE - TODO
+ tempOutputFile << "export LIBBATCH_NODEFILE=$TMPDIR/machines" << endl;
+
+ // Launch the executable
+ tempOutputFile << "cd " << workDir << endl ;
+ tempOutputFile << "./" + fileNameToExecute << endl;
tempOutputFile.flush();
tempOutputFile.close();
- chmod(TmpFileName.c_str(), 0x1ED);
- cerr << TmpFileName.c_str() << endl;
+
+ BATCH_CHMOD(TmpFileName.c_str(), 0x1ED);
+ cerr << "Batch script file generated is: " << TmpFileName.c_str() << endl;
int status = _protocol.copyFile(TmpFileName, "", "",
- dirForTmpFiles + "/" + rootNameToExecute + "_Batch.sh",
+ workDir + "/" + rootNameToExecute + "_Batch.sh",
_hostname, _username);
if (status)
throw EmulationException("Error of connection on remote host");
- remove(TmpFileName.c_str());
#endif //WIN32
}
BatchManager_eClient * FactBatchManager_eSGE::operator() (const char * hostname,
CommunicationProtocolType protocolType,
- const char * mpiImpl) const
+ const char * mpiImpl,
+ int nb_proc_per_node) const
{
// MESSAGE("Building new BatchManager_SGE on host '" << hostname << "'");
return new BatchManager_eSGE(this, hostname, protocolType, mpiImpl);
virtual BatchManager * operator() (const char * hostname) const;
virtual BatchManager_eClient * operator() (const char * hostname,
CommunicationProtocolType protocolType,
- const char * mpiImpl) const;
+ const char * mpiImpl,
+ int nb_proc_per_node = 1) const;
protected:
--- /dev/null
+// Copyright (C) 2007-2008 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
+//
+/*
+ * BatchManager_eSSH.cxx : emulation of SSH client
+ *
+ * Auteur : André RIBES - EDF R&D
+ * Date : Octobre 2009
+ */
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <sys/stat.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <Batch_config.h>
+
+#ifdef MSVC
+#include <io.h>
+#else
+#include <libgen.h>
+#endif
+
+#include "Batch_BatchManager_eSSH.hxx"
+#include "Batch_JobInfo_eSSH.hxx"
+
+using namespace std;
+
+namespace Batch {
+
+ BatchManager_eSSH::BatchManager_eSSH(const FactBatchManager * parent, const char * host,
+ CommunicationProtocolType protocolType, const char * mpiImpl)
+ : BatchManager_eClient(parent, host, protocolType, mpiImpl),
+ BatchManager_Local(parent, host, protocolType),
+ BatchManager(parent, host)
+ {
+ // Nothing to do
+ }
+
+ // Destructeur
+ BatchManager_eSSH::~BatchManager_eSSH()
+ {
+ // Nothing to do
+ }
+
+ // Methode pour le controle des jobs : soumet un job au gestionnaire
+ const JobId BatchManager_eSSH::submitJob(const Job & job)
+ {
+ // export input files on cluster
+ std::cerr << "BatchManager_eSSH::submitJob exportInputFiles" << std::endl;
+ Parametre param = job.getParametre();
+
+ // Input files copy
+ exportInputFiles(job);
+
+ // Launch job
+ // Patch until Local Manager is patched
+ std::string executable = param[EXECUTABLE].str();
+ std::string::size_type p1 = executable.find_last_of("/");
+ std::string fileNameToExecute = "./" + executable.substr(p1+1);
+ Parametre new_param(param);
+ new_param[INFILE].eraseAll();
+ new_param[OUTFILE].eraseAll();
+ new_param[EXECUTABLE] = fileNameToExecute;
+ new_param[EXECUTIONHOST] = _hostname;
+ Job * j = new Job(new_param);
+
+
+ std::cerr << "BatchManager_eSSH::submitJob Local submitJob" << std::endl;
+ JobId id = BatchManager_Local::submitJob(*j);
+ delete j;
+ return id;
+ }
+
+ // Methode pour le controle des jobs : retire un job du gestionnaire
+ void BatchManager_eSSH::deleteJob(const JobId & jobid)
+ {
+ BatchManager_Local::deleteJob(jobid);
+ }
+
+ // Methode pour le controle des jobs : renvoie l'etat du job
+ JobInfo BatchManager_eSSH::queryJob(const JobId & jobid)
+ {
+ return BatchManager_Local::queryJob(jobid);
+ }
+
+ // Methode pour le controle des jobs : suspend un job en file d'attente
+ void BatchManager_eSSH::holdJob(const JobId & jobid)
+ {
+ BatchManager_Local::holdJob(jobid);
+ }
+
+ // Methode pour le controle des jobs : relache un job suspendu
+ void BatchManager_eSSH::releaseJob(const JobId & jobid)
+ {
+ BatchManager_Local::releaseJob(jobid);
+ }
+
+ // Methode pour le controle des jobs : modifie un job en file d'attente
+ void BatchManager_eSSH::alterJob(const JobId & jobid, const Parametre & param, const Environnement & env)
+ {
+ BatchManager_Local::alterJob(jobid, param, env);
+ }
+
+ // Methode pour le controle des jobs : modifie un job en file d'attente
+ void BatchManager_eSSH::alterJob(const JobId & jobid, const Parametre & param)
+ {
+ BatchManager_Local::alterJob(jobid, param);
+ }
+
+ // Methode pour le controle des jobs : modifie un job en file d'attente
+ void BatchManager_eSSH::alterJob(const JobId & jobid, const Environnement & env)
+ {
+ BatchManager_Local::alterJob(jobid, env);
+ }
+
+ void BatchManager_eSSH::buildBatchScript(const Job & job)
+ {
+ Parametre params = job.getParametre();
+ Environnement env = job.getEnvironnement();
+ const long nbproc = params[NBPROC];
+ const long edt = params[MAXWALLTIME];
+ const long mem = params[MAXRAMSIZE];
+ const string workDir = params[WORKDIR];
+ const std::string dirForTmpFiles = params[TMPDIR];
+ const string fileToExecute = params[EXECUTABLE];
+ const string home = params[HOMEDIR];
+ const std::string queue = params[QUEUE];
+ std::string rootNameToExecute;
+ std::string fileNameToExecute;
+ std::string filelogtemp;
+ if( fileToExecute.size() > 0 ){
+ string::size_type p1 = fileToExecute.find_last_of("/");
+ string::size_type p2 = fileToExecute.find_last_of(".");
+ rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+
+#ifdef MSVC
+ char fname[_MAX_FNAME];
+ char ext[_MAX_EXT];
+ _splitpath_s(fileToExecute.c_str(), NULL, 0, NULL, 0, fname, _MAX_FNAME, ext, _MAX_EXT);
+ string execBaseName = string(fname) + ext;
+#else
+ char* basec=strdup(fileToExecute.c_str());
+ string execBaseName = string(basename(basec));
+ free(basec);
+#endif
+
+ fileNameToExecute = "~/" + dirForTmpFiles + "/" + execBaseName;
+
+ int idx = dirForTmpFiles.find("Batch/");
+ filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
+ }
+ else{
+ rootNameToExecute = "command";
+ }
+
+ ofstream tempOutputFile;
+ std::string TmpFileName = createAndOpenTemporaryFile("SSH-script", tempOutputFile);
+
+ tempOutputFile << "#! /bin/sh -f" << endl;
+ if (queue != "")
+ tempOutputFile << "#BSUB -q " << queue << endl;
+ if( edt > 0 )
+ tempOutputFile << "#SSH -l walltime=" << edt*60 << endl ;
+ if( mem > 0 )
+ tempOutputFile << "#SSH -l mem=" << mem << "mb" << endl ;
+ if( fileToExecute.size() > 0 ){
+ tempOutputFile << "#SSH -o " << home << "/" << dirForTmpFiles << "/output.log." << filelogtemp << endl ;
+ tempOutputFile << "#SSH -e " << home << "/" << dirForTmpFiles << "/error.log." << filelogtemp << endl ;
+ }
+ else{
+ tempOutputFile << "#SSH -o " << dirForTmpFiles << "/" << env["LOGFILE"] << ".output.log" << endl ;
+ tempOutputFile << "#SSH -e " << dirForTmpFiles << "/" << env["LOGFILE"] << ".error.log" << endl ;
+ }
+ if( workDir.size() > 0 )
+ tempOutputFile << "cd " << workDir << endl ;
+ if( fileToExecute.size() > 0 ){
+ tempOutputFile << _mpiImpl->boot("${SSH_NODEFILE}",nbproc);
+ tempOutputFile << _mpiImpl->run("${SSH_NODEFILE}",nbproc,fileNameToExecute);
+ tempOutputFile << _mpiImpl->halt();
+ }
+ else{
+ tempOutputFile << "source " << env["SOURCEFILE"] << endl ;
+ tempOutputFile << env["COMMAND"];
+ }
+
+ tempOutputFile.flush();
+ tempOutputFile.close();
+#ifdef WIN32
+ _chmod(
+#else
+ chmod(
+#endif
+ TmpFileName.c_str(), 0x1ED);
+ cerr << TmpFileName.c_str() << endl;
+
+ int status = Batch::BatchManager_eClient::_protocol.copyFile(TmpFileName, "", "",
+ dirForTmpFiles + "/" + rootNameToExecute + "_Batch.sh",
+ _hostname, _username);
+ if (status)
+ throw EmulationException("Error of connection on remote host");
+
+ remove(TmpFileName.c_str());
+ }
+
+}
--- /dev/null
+// Copyright (C) 2007-2008 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
+//
+/*
+ * BatchManager_eSSH.hxx : emulation of SSH client
+ *
+ * Auteur : André RIBES - EDF R&D
+ * Date : Octobre 2009
+ */
+
+#ifndef _BATCHMANAGER_ESSH_H_
+#define _BATCHMANAGER_ESSH_H_
+
+#include "Batch_Defines.hxx"
+#include "Batch_JobId.hxx"
+#include "Batch_JobInfo.hxx"
+#include "Batch_FactBatchManager.hxx"
+#include "Batch_BatchManager_eClient.hxx"
+#include "Batch_BatchManager_Local.hxx"
+
+namespace Batch {
+
+ class BATCH_EXPORT BatchManager_eSSH :
+ virtual public BatchManager_eClient,
+ virtual public BatchManager_Local
+ {
+ public:
+ // Constructeur et destructeur
+ BatchManager_eSSH(const FactBatchManager * parent, const char * host="localhost",
+ CommunicationProtocolType protocolType = SSH, const char * mpiImpl="nompi"); // connexion a la machine host
+ virtual ~BatchManager_eSSH();
+
+ // 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 JobInfo queryJob(const JobId & jobid); // renvoie l'etat du job
+
+ // Non implanté...
+ 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
+
+
+ protected:
+ void buildBatchScript(const Job & job);
+
+ 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
--- /dev/null
+// Copyright (C) 2007-2008 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
+//
+/*
+ * FactBatchManager_eSSH.cxx :
+ *
+ * Auteur : André RIBES : EDF R&D
+ * Date : Octobre 2009
+ */
+
+#include <string>
+#include "Batch_BatchManager_eSSH.hxx"
+#include "Batch_FactBatchManager_eSSH.hxx"
+
+Batch::FactBatchManager_eSSH::FactBatchManager_eSSH() : FactBatchManager_eClient("eSSH") {}
+
+Batch::FactBatchManager_eSSH::~FactBatchManager_eSSH() {}
+
+Batch::BatchManager *
+Batch::FactBatchManager_eSSH::operator() (const char * hostname) const
+{
+ return new Batch::BatchManager_eSSH(this, hostname);
+}
+
+Batch::BatchManager_eClient *
+Batch::FactBatchManager_eSSH::operator() (const char * hostname,
+ CommunicationProtocolType protocolType,
+ const char * mpiImpl,
+ int nb_proc_per_node) const
+{
+ //protocolType and mpiImpl are ignored.
+ std::cerr << "[Batch::FactBatchManager_eSSH] creating new Batch::BatchManager_eSSH with hostname = " << hostname << std::endl;
+
+ return new Batch::BatchManager_eSSH(this, hostname);
+}
--- /dev/null
+// Copyright (C) 2007-2008 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
+//
+/*
+ * FactBatchManager_eSSH.hxx :
+ *
+ * Auteur : André RIBES : EDF R&D
+ * Date : Octobre 2009
+ */
+
+#ifndef _FACTBATCHMANAGER_eSSH_H_
+#define _FACTBATCHMANAGER_eSSH_H_
+
+#include "Batch_Defines.hxx"
+
+#include <string>
+#include <map>
+#include "Batch_BatchManager_eClient.hxx"
+#include "Batch_FactBatchManager_eClient.hxx"
+
+namespace Batch {
+
+ class BatchManager_eSSH;
+
+ class BATCH_EXPORT FactBatchManager_eSSH : public FactBatchManager_eClient
+ {
+ public:
+ FactBatchManager_eSSH();
+ virtual ~FactBatchManager_eSSH();
+
+ virtual BatchManager * operator() (const char * hostname) const; // From FactBacthManager
+ virtual BatchManager_eClient * operator() (const char * hostname,
+ CommunicationProtocolType protocolType,
+ const char * mpiImpl,
+ int nb_proc_per_node = 1) const; // From FactBatchManager_eClient
+ };
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2007-2008 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
+//
+/*
+ * JobInfo_eSSH.cxx : emulation of SSH client
+ *
+ * Auteur : André RIBES - EDF R&D
+ * Date : Octobre 2009
+ */
+
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "Batch_Parametre.hxx"
+#include "Batch_Environnement.hxx"
+#include "Batch_RunTimeException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_JobInfo_eSSH.hxx"
+
+using namespace std;
+
+namespace Batch {
+
+ // Constructeurs
+ JobInfo_eSSH::JobInfo_eSSH(int id, string status) : JobInfo()
+ {
+ // On remplit les membres _param et _env
+ ostringstream oss;
+ oss << id;
+ _param[ID] = oss.str();
+ _param[STATE] = status;
+ }
+
+ // Destructeur
+ JobInfo_eSSH::~JobInfo_eSSH()
+ {
+ // Nothing to do
+ }
+
+ // Methode pour l'interfacage avec Python (SWIG) : affichage en Python
+ string JobInfo_eSSH::__str__() const
+ {
+ ostringstream sst;
+ sst << "<JobInfo_eSSH (" << this << ") :" << endl;
+ sst << " ID = " <<_param[ID] << endl;
+ sst << " STATE = " <<_param[STATE] << endl;
+
+ return sst.str();
+ }
+
+
+}
--- /dev/null
+// Copyright (C) 2007-2008 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
+//
+/*
+ * JobInfo_eSSH.hxx : emulation of SSH client
+ *
+ * Auteur : André RIBES - EDF R&D
+ * Date : Octobre 2009
+ */
+
+#ifndef _JOBINFO_SSH_H_
+#define _JOBINFO_SSH_H_
+
+#include <string>
+#include "Batch_RunTimeException.hxx"
+#include "Batch_JobInfo.hxx"
+
+namespace Batch {
+
+ class JobInfo_eSSH : public JobInfo
+ {
+ public:
+ // Constructeurs et destructeur
+ JobInfo_eSSH(int id, std::string status);
+ virtual ~JobInfo_eSSH();
+
+ // Methodes pour l'interfacage avec Python (SWIG)
+ // TODO : supprimer ces methodes et transferer leur definitions dans SWIG
+ std::string __str__() const; // SWIG : affichage en Python
+ std::string __repr__() const { return __str__(); }; // SWIG : affichage en Python
+
+ };
+
+}
+
+#endif
--- /dev/null
+# Copyright (C) 2007-2008 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
+#
+
+SET(CLASS_LIST SSH/Batch_FactBatchManager_eSSH
+ SSH/Batch_BatchManager_eSSH
+ SSH/Batch_JobInfo_eSSH
+ )
+
+APPEND_CLASSES_TO_SRC_FILES(${CLASS_LIST})
+APPEND_CLASSES_TO_HDR_FILES(${CLASS_LIST})
+
+#IF (TEST_ENABLED)
+# add_subdirectory(Test)
+#ENDIF (TEST_ENABLED)