From 17bf8eddc16939c593d7a02123c48130ea69cfb0 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 4 Jan 2019 15:53:10 +0100 Subject: [PATCH] Launcher is now usable outside a SALOME session. Launcher::Job instances lifecycle are managed using ref counting. --- src/CMakeLists.txt | 1 + src/Launcher/Launcher.cxx | 39 ++- src/Launcher/Launcher.hxx | 5 +- src/Launcher/Launcher_Job.cxx | 13 + src/Launcher/Launcher_Job.hxx | 9 +- src/Launcher/Launcher_Job_Command.hxx | 3 +- src/Launcher/Launcher_Job_CommandSALOME.hxx | 3 +- src/Launcher/Launcher_Job_PythonSALOME.hxx | 3 +- src/Launcher/Launcher_Job_SALOME.hxx | 3 +- src/Launcher/Launcher_Job_YACSFile.hxx | 3 +- src/Launcher/Launcher_XML_Persistence.cxx | 2 +- src/Launcher_SWIG/CMakeLists.txt | 52 +++ src/Launcher_SWIG/Launcher.i | 334 ++++++++++++++++++++ src/Launcher_SWIG/test.py | 43 +++ src/ResourcesManager/ResourcesManager.cxx | 4 +- src/ResourcesManager/ResourcesManager.hxx | 2 +- 16 files changed, 483 insertions(+), 36 deletions(-) create mode 100644 src/Launcher_SWIG/CMakeLists.txt create mode 100644 src/Launcher_SWIG/Launcher.i create mode 100644 src/Launcher_SWIG/test.py diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ef1cdb922..832150e89 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,6 +41,7 @@ SET(SUBDIR_CORBA SALOMESDS TestContainer Launcher + Launcher_SWIG LifeCycleCORBA LifeCycleCORBA_SWIG SALOMEDSClient diff --git a/src/Launcher/Launcher.cxx b/src/Launcher/Launcher.cxx index 96a1fafd0..1226253fe 100644 --- a/src/Launcher/Launcher.cxx +++ b/src/Launcher/Launcher.cxx @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef WITH_LIBBATCH #include @@ -66,7 +67,7 @@ Launcher_cpp::~Launcher_cpp() #ifdef WITH_LIBBATCH std::map::const_iterator it_job; for(it_job = _launcher_job_map.begin(); it_job != _launcher_job_map.end(); it_job++) - delete it_job->second; + it_job->second->decrRef(); std::map ::const_iterator it1; for(it1=_batchmap.begin();it1!=_batchmap.end();it1++) delete it1->second; @@ -91,11 +92,11 @@ Launcher_cpp::createJob(Launcher::Job * new_job) if (it_job == _launcher_job_map.end()) { _launcher_job_map[new_job->getNumber()] = new_job; + new_job->incrRef(); } else { LAUNCHER_INFOS("A job has already the same id: " << new_job->getNumber()); - delete new_job; throw LauncherException("A job has already the same id - job is not created !"); } LAUNCHER_MESSAGE("New Job created"); @@ -310,7 +311,7 @@ Launcher_cpp::removeJob(int job_id) } it_job->second->removeJob(); - delete it_job->second; + it_job->second->decrRef(); _launcher_job_map.erase(it_job); } @@ -341,25 +342,22 @@ int Launcher_cpp::restoreJob(const std::string& dumpedJob) { LAUNCHER_MESSAGE("restore Job"); - Launcher::Job * new_job=NULL; + auto JobDel = [] (Launcher::Job *job) { if(job) job->decrRef(); }; + std::unique_ptr new_job(nullptr,JobDel); int jobId = -1; try { { - new_job = Launcher::XML_Persistence::createJobFromString(dumpedJob); + new_job.reset(Launcher::XML_Persistence::createJobFromString(dumpedJob)); } - if(new_job) + if(new_job.get()) { - jobId = addJob(new_job); - if(jobId < 0) - delete new_job; + jobId = addJob(new_job.get()); } } catch(const LauncherException &ex) { LAUNCHER_INFOS("Cannot load the job. Exception: " << ex.msg.c_str()); - if(new_job) - delete new_job; } return jobId; } @@ -380,7 +378,8 @@ Launcher_cpp::createJobWithFile(const std::string xmlExecuteFile, ParserLauncherType job_params = ParseXmlFile(xmlExecuteFile); // Creating a new job - Launcher::Job_Command * new_job = new Launcher::Job_Command(); + auto JobDel = [] (Launcher::Job *job) { if(job) job->decrRef(); }; + std::unique_ptr new_job(new Launcher::Job_Command,JobDel); std::string cmdFile = Kernel_Utils::GetTmpFileName(); #ifndef WIN32 @@ -415,7 +414,7 @@ Launcher_cpp::createJobWithFile(const std::string xmlExecuteFile, p.mem_mb = 0; new_job->setResourceRequiredParams(p); - createJob(new_job); + createJob(new_job.get()); return new_job->getNumber(); } @@ -537,7 +536,6 @@ void Launcher_cpp::createJob(Launcher::Job * new_job) { LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot create a job !!!"); - delete new_job; throw LauncherException("Method Launcher_cpp::createJob is not available " "(libBatch was not present at compilation time)"); } @@ -785,11 +783,11 @@ Launcher_cpp::addJobDirectlyToMap(Launcher::Job * new_job) if (it_job == _launcher_job_map.end()) { _launcher_job_map[new_job->getNumber()] = new_job; + new_job->incrRef(); } else { LAUNCHER_INFOS("A job as already the same id: " << new_job->getNumber()); - delete new_job; throw LauncherException("A job as already the same id - job is not created !"); } LAUNCHER_MESSAGE("New job added"); @@ -843,6 +841,8 @@ Launcher_cpp::addJob(Launcher::Job * new_job) list Launcher_cpp::loadJobs(const char* jobs_file) { + auto JobDel = [] (Launcher::Job *job) { if(job) job->decrRef(); }; + list new_jobs_id_list; // Load the jobs from XML file @@ -852,20 +852,17 @@ Launcher_cpp::loadJobs(const char* jobs_file) list::const_iterator it_job; for (it_job = jobs_list.begin(); it_job != jobs_list.end(); it_job++) { - Launcher::Job * new_job = *it_job; + std::unique_ptr new_job(*it_job, JobDel); int jobId = -1; try { - jobId = addJob(new_job); + jobId = addJob(new_job.get()); if(jobId >= 0) new_jobs_id_list.push_back(jobId); - else - delete new_job; } catch(const LauncherException &ex) { LAUNCHER_INFOS("Cannot load the job. Exception: " << ex.msg.c_str()); - delete new_job; } } @@ -900,4 +897,4 @@ Launcher_cpp::findJob(int job_id) } Launcher::Job * job = it_job->second; return job; -} \ No newline at end of file +} diff --git a/src/Launcher/Launcher.hxx b/src/Launcher/Launcher.hxx index a8fbef7a8..e069f42f8 100644 --- a/src/Launcher/Launcher.hxx +++ b/src/Launcher/Launcher.hxx @@ -86,19 +86,18 @@ public: long createJobWithFile(std::string xmlExecuteFile, std::string clusterName); std::map getJobs(); void addJobDirectlyToMap(Launcher::Job * new_job); + Launcher::Job * findJob(int job_id); // Lib methods void SetResourcesManager( ResourcesManager_cpp* rm ) {_ResManager = rm;} // Used by SALOME_Launcher - ResourcesManager_cpp *_ResManager; + ResourcesManager_cpp *_ResManager = nullptr; protected: virtual void notifyObservers(const std::string & event_name, const std::string & event_data) {} int addJob(Launcher::Job * new_job); - Launcher::Job * findJob(int job_id); - // Methods used by user interface methods #ifdef WITH_LIBBATCH Batch::BatchManager *FactoryBatchManager(ParserResourcesType& params); diff --git a/src/Launcher/Launcher_Job.cxx b/src/Launcher/Launcher_Job.cxx index ac015eb7f..562a9915f 100644 --- a/src/Launcher/Launcher_Job.cxx +++ b/src/Launcher/Launcher_Job.cxx @@ -77,6 +77,19 @@ Launcher::Job::~Job() #endif } +bool Launcher::Job::decrRef() const +{ + bool ret=((--_cnt)==0); + if(ret) + delete this; + return ret; +} + +void Launcher::Job::incrRef() const +{ + _cnt++; +} + void Launcher::Job::stopJob() { diff --git a/src/Launcher/Launcher_Job.hxx b/src/Launcher/Launcher_Job.hxx index 44d5f75fe..eab918c72 100644 --- a/src/Launcher/Launcher_Job.hxx +++ b/src/Launcher/Launcher_Job.hxx @@ -47,10 +47,13 @@ namespace Launcher { class LAUNCHER_EXPORT Job { + protected: + virtual ~Job(); public: Job(); - virtual ~Job(); - + int getRCValue() const { return _cnt; } + bool decrRef() const; + void incrRef() const; // Launcher managing parameters // State of a Job: CREATED, IN_PROCESS, QUEUED, RUNNING, PAUSED, FINISHED, ERROR void setState(const std::string & state); @@ -185,6 +188,8 @@ namespace Launcher Batch::Job * _batch_job; Batch::JobId _batch_job_id; #endif + protected: + mutable int _cnt = 1; }; } diff --git a/src/Launcher/Launcher_Job_Command.hxx b/src/Launcher/Launcher_Job_Command.hxx index d95b01b5d..75f91c5f9 100644 --- a/src/Launcher/Launcher_Job_Command.hxx +++ b/src/Launcher/Launcher_Job_Command.hxx @@ -33,9 +33,10 @@ namespace Launcher { class LAUNCHER_EXPORT Job_Command : virtual public Launcher::Job { + protected: + virtual ~Job_Command(); public: Job_Command(); - virtual ~Job_Command(); virtual void update_job(); diff --git a/src/Launcher/Launcher_Job_CommandSALOME.hxx b/src/Launcher/Launcher_Job_CommandSALOME.hxx index dd3884bcf..e3118d04f 100644 --- a/src/Launcher/Launcher_Job_CommandSALOME.hxx +++ b/src/Launcher/Launcher_Job_CommandSALOME.hxx @@ -33,9 +33,10 @@ namespace Launcher { class LAUNCHER_EXPORT Job_CommandSALOME : virtual public Launcher::Job_Command { + private: + virtual ~Job_CommandSALOME(); public: Job_CommandSALOME(); - virtual ~Job_CommandSALOME(); static const char TYPE_NAME[]; #ifdef WITH_LIBBATCH diff --git a/src/Launcher/Launcher_Job_PythonSALOME.hxx b/src/Launcher/Launcher_Job_PythonSALOME.hxx index 876f775db..6f27a791c 100644 --- a/src/Launcher/Launcher_Job_PythonSALOME.hxx +++ b/src/Launcher/Launcher_Job_PythonSALOME.hxx @@ -28,9 +28,10 @@ namespace Launcher { class LAUNCHER_EXPORT Job_PythonSALOME : virtual public Launcher::Job_SALOME { + private: + virtual ~Job_PythonSALOME(); public: Job_PythonSALOME(); - virtual ~Job_PythonSALOME(); virtual void setJobFile(const std::string & job_file); virtual void addJobTypeSpecificScript(std::ofstream & launch_script_stream); diff --git a/src/Launcher/Launcher_Job_SALOME.hxx b/src/Launcher/Launcher_Job_SALOME.hxx index 4e2a2dbd3..16a9fe4da 100644 --- a/src/Launcher/Launcher_Job_SALOME.hxx +++ b/src/Launcher/Launcher_Job_SALOME.hxx @@ -33,9 +33,10 @@ namespace Launcher { class LAUNCHER_EXPORT Job_SALOME : virtual public Launcher::Job { + protected: + virtual ~Job_SALOME(); public: Job_SALOME(); - virtual ~Job_SALOME(); virtual void setResourceDefinition(const ParserResourcesType & resource_definition); virtual void update_job(); diff --git a/src/Launcher/Launcher_Job_YACSFile.hxx b/src/Launcher/Launcher_Job_YACSFile.hxx index 657231244..e37499afd 100644 --- a/src/Launcher/Launcher_Job_YACSFile.hxx +++ b/src/Launcher/Launcher_Job_YACSFile.hxx @@ -28,9 +28,10 @@ namespace Launcher { class LAUNCHER_EXPORT Job_YACSFile : virtual public Launcher::Job_SALOME { + private: + virtual ~Job_YACSFile(); public: Job_YACSFile(); - virtual ~Job_YACSFile(); virtual void setJobFile(const std::string & job_file); virtual void addJobTypeSpecificScript(std::ofstream & launch_script_stream); diff --git a/src/Launcher/Launcher_XML_Persistence.cxx b/src/Launcher/Launcher_XML_Persistence.cxx index 3e4c50df4..4c2d5ce06 100644 --- a/src/Launcher/Launcher_XML_Persistence.cxx +++ b/src/Launcher/Launcher_XML_Persistence.cxx @@ -284,7 +284,7 @@ XML_Persistence::createJobFromXmlNode(xmlNodePtr job_node) } catch (const LauncherException & exc) { - delete new_job; + new_job->decrRef(); string error = string("Invalid job \"") + job_name + "\": " + exc.msg; throw LauncherException(error); } diff --git a/src/Launcher_SWIG/CMakeLists.txt b/src/Launcher_SWIG/CMakeLists.txt new file mode 100644 index 000000000..e758b78d9 --- /dev/null +++ b/src/Launcher_SWIG/CMakeLists.txt @@ -0,0 +1,52 @@ +# Copyright (C) 2019 CEA/DEN, EDF R&D, OPEN CASCADE +# +# 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, or (at your option) any later version. +# +# 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 +# + +INCLUDE(${SWIG_USE_FILE}) + +ADD_DEFINITIONS(${PYTHON_DEFINITIONS}) + +SET(Launcher_target_name pylauncher) + +IF(SALOME_USE_LIBBATCH) + ADD_DEFINITIONS(-DWITH_LIBBATCH) + SET(SWIG_MODULE_${Launcher_target_name}_EXTRA_FLAGS "-DWITH_LIBBATCH") +ENDIF(SALOME_USE_LIBBATCH) + +SET_SOURCE_FILES_PROPERTIES(Launcher.i PROPERTIES CPLUSPLUS ON) +SET_SOURCE_FILES_PROPERTIES(Launcher.i PROPERTIES SWIG_FLAGS "-py3") + + +INCLUDE_DIRECTORIES( + ${PYTHON_INCLUDE_DIRS} + ${LIBBATCH_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/../ResourcesManager + ${CMAKE_CURRENT_SOURCE_DIR}/../Launcher + ) + +SWIG_ADD_LIBRARY(${Launcher_target_name} LANGUAGE python SOURCES Launcher.i) + +SWIG_LINK_LIBRARIES(${Launcher_target_name} ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} Launcher) + +SWIG_CHECK_GENERATION(${Launcher_target_name}) + +INSTALL(TARGETS ${SWIG_MODULE_${Launcher_target_name}_REAL_NAME} DESTINATION ${SALOME_INSTALL_PYTHON}) + +SET(PYFILES_TO_INSTALL ${PYFILES_TO_INSTALL} ${CMAKE_CURRENT_BINARY_DIR}/pylauncher.py) + +SALOME_INSTALL_SCRIPTS("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_PYTHON} EXTRA_DPYS "${SWIG_MODULE_${Launcher_target_name}_REAL_NAME}") diff --git a/src/Launcher_SWIG/Launcher.i b/src/Launcher_SWIG/Launcher.i new file mode 100644 index 000000000..20da573b2 --- /dev/null +++ b/src/Launcher_SWIG/Launcher.i @@ -0,0 +1,334 @@ +// Copyright (C) 2019 CEA/DEN, EDF R&D +// +// 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, or (at your option) any later version. +// +// 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 +// + +%module pylauncher + +%{ +#include "SALOME_ResourcesCatalog_Parser.hxx" +#include "Launcher_Job.hxx" +#include "Launcher_Job_SALOME.hxx" +#include "Launcher_Job_YACSFile.hxx" +#include "Launcher.hxx" +#include "ResourcesManager.hxx" + +static PyObject *convertJob(Launcher::Job *job, int owner) +{ + PyObject *ret(nullptr); + if(!job) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast(job)) + return SWIG_NewPointerObj((void*)dynamic_cast(job),SWIGTYPE_p_Launcher__Job_YACSFile,owner); + throw LauncherException("Not recognized type of job on downcast !"); +} + +%} + +%include std_string.i + +%typemap(out) const std::list& +{ + std::size_t i; + std::list::const_iterator iL; + $result = PyList_New($1->size()); + for (i=0, iL=$1->cbegin(); iL!=$1->cend(); i++, iL++) + PyList_SetItem($result,i,PyUnicode_FromString((*iL).c_str())); +} + +%typemap(out) const std::map & +{ + $result = PyDict_New(); + for(std::map::const_iterator iL=$1->cbegin();iL!=$1->cend();iL++) + { + PyObject *a(PyUnicode_FromString((*iL).first.c_str())); + PyObject *b(PyUnicode_FromString((*iL).second.c_str())); + PyDict_SetItem($result,a,b); + Py_DECREF(a); Py_DECREF(b); + } +} + +%typemap(out) std::vector * +{ + std::size_t i; + std::vector::const_iterator iL; + $result = PyList_New($1->size()); + for (i=0, iL=$1->cbegin(); iL!=$1->cend(); i++, iL++) + PyList_SetItem($result,i,PyUnicode_FromString((*iL).c_str())); +} + +%typemap(out) Launcher::Job * +{ + $result=convertJob($1,$owner); +} + +%exception +{ + try { + $function + } + catch(LauncherException& e) + { + SWIG_exception_fail(SWIG_RuntimeError,e.msg.c_str()); + } + catch (...) + { + SWIG_exception_fail(SWIG_UnknownError, "Unknown"); + } +} + +struct resourceParams +{ + resourceParams(); + + std::string name; + std::string hostname; + bool can_launch_batch_jobs; + bool can_run_containers; + std::string OS; + long nb_proc; + long nb_node; + long nb_proc_per_node; + long cpu_clock; + long mem_mb; + std::vector componentList; + std::vector resourceList; +}; + +class ResourcesManager_cpp +{ + public: + ResourcesManager_cpp(const char *xmlFilePath); +}; + +class ParserResourcesType +{ +public: + ParserResourcesType(); + ~ParserResourcesType(); + std::string getAccessProtocolTypeStr() const; + std::string getResourceTypeStr() const; + std::string getBatchTypeStr() const; + std::string getMpiImplTypeStr() const; + std::string getClusterInternalProtocolStr() const; + std::string getCanLaunchBatchJobsStr() const; + std::string getCanRunContainersStr() const; + + void setAccessProtocolTypeStr(const std::string & protocolTypeStr); + void setResourceTypeStr(const std::string & resourceTypeStr); + void setBatchTypeStr(const std::string & batchTypeStr); + void setMpiImplTypeStr(const std::string & mpiImplTypeStr); + void setClusterInternalProtocolStr(const std::string & internalProtocolTypeStr); + void setCanLaunchBatchJobsStr(const std::string & canLaunchBatchJobsStr); + void setCanRunContainersStr(const std::string & canRunContainersStr); +}; + +%feature("unref") Launcher::Job "$this->decrRef();" +%feature("unref") Launcher::Job_SALOME "$this->decrRef();" +%feature("unref") Launcher::Job_YACSFile "$this->decrRef();" + +namespace Launcher +{ + class Job + { + public: + Job(); + virtual ~Job(); + void setState(const std::string & state); + std::string getState() const; + std::string getAssignedHostnames(); + void setNumber(const int & number); + int getNumber(); + virtual void setResourceDefinition(const ParserResourcesType & resource_definition); + ParserResourcesType getResourceDefinition() const; + // Common parameters + void setJobName(const std::string & job_name); + virtual void setJobFile(const std::string & job_file); + void setPreCommand(const std::string & preCommand); + void setWorkDirectory(const std::string & work_directory); + void setLocalDirectory(const std::string & local_directory); + void setResultDirectory(const std::string & result_directory); + void add_in_file(const std::string & file); + void add_out_file(const std::string & file); + void setMaximumDuration(const std::string & maximum_duration); + void setResourceRequiredParams(const resourceParams & resource_required_params); + void setQueue(const std::string & queue); + void setPartition(const std::string & partition); + void setEnvFile(const std::string & env_file); + void setExclusive(bool exclusive); + void setExclusiveStr(const std::string & exclusiveStr); + void setMemPerCpu(unsigned long mem_per_cpu); + void setWCKey(const std::string & wckey); + void setExtraParams(const std::string & extra_params); + void setReference(const std::string & reference); + // For COORM + void setLauncherFile(const std::string & launcher_file); + void setLauncherArgs(const std::string & launcher_args); + + std::string getJobName() const; + std::string getJobFile() const; + std::string getPreCommand() const; + std::string getWorkDirectory() const; + std::string getLocalDirectory() const; + std::string getResultDirectory() const; + const std::list & get_in_files() const; + const std::list & get_out_files() const; + std::string getMaximumDuration() const; + resourceParams getResourceRequiredParams() const; + std::string getQueue() const; + std::string getPartition() const; + std::string getEnvFile() const; + std::string getJobType() const; + bool getExclusive() const; + std::string getExclusiveStr() const; + unsigned long getMemPerCpu() const; + std::string getWCKey() const; + std::string getExtraParams() const; + std::string getReference() const; + std::string getLauncherFile() const; + std::string getLauncherArgs() const; + std::string updateJobState(); + + void addSpecificParameter(const std::string & name, const std::string & value); + const std::map & getSpecificParameters() const; + virtual void checkSpecificParameters(); + + // Checks + void checkMaximumDuration(const std::string & maximum_duration); + void checkResourceRequiredParams(const resourceParams & resource_required_params); + + // Helps + long convertMaximumDuration(const std::string & maximum_duration); + std::string getLaunchDate() const; + + void stopJob(); + void removeJob(); + virtual void update_job() = 0; + }; + + class Job_SALOME : public Job + { + private: + Job_SALOME(); + public: + virtual ~Job_SALOME(); + virtual void setResourceDefinition(const ParserResourcesType & resource_definition); + virtual void update_job(); +#ifdef WITH_LIBBATCH + public: + std::string buildSalomeScript(Batch::Parametre params); +#endif + }; + + class Job_YACSFile : public Job_SALOME + { + public: + Job_YACSFile(); + virtual ~Job_YACSFile(); + virtual void setJobFile(const std::string & job_file); + virtual void checkSpecificParameters(); + }; +} + +class Launcher_cpp +{ +public: + Launcher_cpp(); + virtual ~Launcher_cpp(); + void createJob(Launcher::Job * new_job); + void launchJob(int job_id); + const char * getJobState(int job_id); + const char * getAssignedHostnames(int job_id); // Get names or ids of hosts assigned to the job + void getJobResults(int job_id, std::string directory); + void clearJobWorkingDir(int job_id); + bool getJobDumpState(int job_id, std::string directory); + bool getJobWorkFile(int job_id, std::string work_file, std::string directory); + void stopJob(int job_id); + void removeJob(int job_id); + std::string dumpJob(int job_id); + int restoreJob(const std::string& dumpedJob); + std::list loadJobs(const char* jobs_file); + void saveJobs(const char* jobs_file); + long createJobWithFile(std::string xmlExecuteFile, std::string clusterName); + std::map getJobs(); + void addJobDirectlyToMap(Launcher::Job * new_job); + void SetResourcesManager( ResourcesManager_cpp *rm ); + Launcher::Job * findJob(int job_id); +}; + +%pythoncode %{ +def sendJobToSession(self, job_id, sessionId=None): + """Send job specified by its job_id in self to a remote SALOME session. + Doing so, it's possible to follow the job created locally into the JobManager module of the target SALOME session. + SALOME session is specified by the file pointed by the content of OMNIORB_CONFIG environement var. The content of this var is called sessionId. + If sessionId is let untouched, the current OMNIORB_CONFIG environement var is used. + If this method fails to connect to the target SALOME session a RuntimeError exception will be thrown. + """ + def job_type_traducer(jyf): + dico = {'Job_YACSFile' : 'yacs_file'} + st = type(jyf).__name__ + if st not in dico: + raise RuntimeError("Not recognized type %s !"%st) + return dico[st] + # + def resource_required_func(jyf): + import Engines + rp =jyf.getResourceRequiredParams() + l12 = [('name', None), ('hostname', None), ('can_launch_batch_jobs', None), ('can_run_containers', None), ('OS', None), ('componentList', None), ('nb_proc', None), ('mem_mb', None), ('cpu_clock', None), ('nb_node', None), ('nb_proc_per_node', None), ('policy', lambda x: 'cycl'), ('resList', lambda x: x.resourceList)] + kw2={} + for a,b in l12: + if a and not b: + kw2[a]=getattr(rp,a) + else: + if a and b: + kw2[a]=b(rp) + return Engines.ResourceParameters(**kw2) + # + filest = self.dumpJob(job_id); + # Connect to SALOME session a retrieve its SalomeLauncher object + import os + if sessionId is not None: + os.environ["OMNIORB_CONFIG"]=sessionId + import Engines + import orbmodule + try: + clt=orbmodule.client() + sl = clt.Resolve("SalomeLauncher") + except: + raise RuntimeError("Fail to connect to the remote SALOME session.") + # swig to CORBA translation + # Job_YACSFile -> Engines.JobParameters and resourceParams -> Engines.ResourceParameters() + l21= [('job_name', None), ('job_type', job_type_traducer), ('job_file', None), ('pre_command', None), ('env_file', None), ('in_files', lambda x: x.get_in_files()), ('out_files', lambda x: x.get_out_files()), ('work_directory', None), ('local_directory', None), ('result_directory', None), ('maximum_duration', None), ('resource_required',resource_required_func) , ('queue', None), ('partition', None), ('exclusive', None), ('mem_per_cpu', None), ('wckey', lambda x: x.getWCKey() ), ('extra_params', None), ('specific_parameters', lambda x: list(x.getSpecificParameters().items())), ('launcher_file', None), ('launcher_args', None)] + kw={} + jyf = self.findJob(job_id) + for a,b in l21: + if not b and a: + kw[a]=eval("jyf.get%s()"%"".join(["%s%s"%(elt2[0].upper(),elt2[1:]) for elt2 in a.split("_")]),{"jyf" : jyf}) + else: + if a and b: + kw[a]=b(jyf) + jyc = Engines.JobParameters(**kw) + ######################## + bpc = sl.createJob(jyc) + sl.restoreJob(filest) + +Launcher_cpp.sendJobToSession = sendJobToSession +del sendJobToSession +%} diff --git a/src/Launcher_SWIG/test.py b/src/Launcher_SWIG/test.py new file mode 100644 index 000000000..6cb2371e7 --- /dev/null +++ b/src/Launcher_SWIG/test.py @@ -0,0 +1,43 @@ +import pylauncher as pyla +jyf=pyla.Job_YACSFile() +jyf.setJobName("YDFX") +jyf.setWorkDirectory("/scratch/geay/Example") +jyf.setLocalDirectory("/home/geay/Example") +jyf.setResultDirectory("/home/geay/Example") +jyf.setLauncherFile("") +jyf.setLauncherArgs("") +jyf.setJobFile("/tmp/EvalYFX_geay_180119_093600.xml") # schema YACS +jyf.setPreCommand("") +jyf.setEnvFile("") +for elt in []: + jyf.add_in_file(elt) +for elt in ["EvalYFX_geay_180119_093600"]: + jyf.add_out_file(elt) +jyf.setMaximumDuration("00:05") +jyf.setQueue("") +jyf.setPartition("") +jyf.setExclusive(False) +jyf.setMemPerCpu(0) +jyf.setWCKey("P11U5:CARBONES") +jyf.setExtraParams("") +# +rp=pyla.resourceParams() +rp.name = "athos" +rp.hostname = "" +rp.OS = "Linux" +rp.nb_proc = 5 +rp.nb_node = 0 +rp.nb_proc_per_node = 1 +rp.cpu_clock = -1 +rp.mem_mb = 0 +jyf.setResourceRequiredParams(rp) +jyf.checkSpecificParameters() +l = pyla.Launcher_cpp() +res = pyla.ResourcesManager_cpp("/home/geay/salome/V9_DEV/appli_V9_2_0/CatalogResources.xml") +l.SetResourcesManager(res) +l.createJob(jyf) +nb=jyf.getNumber() +l.launchJob(nb) +l.sendJobToSession(nb) +#l.getJobState(nb) +#l.getJobResults(nb,jyf.getLocalDirectory()) diff --git a/src/ResourcesManager/ResourcesManager.cxx b/src/ResourcesManager/ResourcesManager.cxx index b2ed58fa5..687911a5d 100644 --- a/src/ResourcesManager/ResourcesManager.cxx +++ b/src/ResourcesManager/ResourcesManager.cxx @@ -160,8 +160,6 @@ ResourcesManager_cpp::ResourcesManager_cpp() throw(ResourcesException) } } - _lasttime=0; - ParseXmlFiles(); RES_MESSAGE("ResourcesManager_cpp constructor end"); } @@ -436,7 +434,7 @@ const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFiles() return _resourcesList; } - if(statinfo.st_mtime > _lasttime) + if(_lasttime == 0 || statinfo.st_mtime > _lasttime) { to_parse = true; _lasttime = statinfo.st_mtime; diff --git a/src/ResourcesManager/ResourcesManager.hxx b/src/ResourcesManager/ResourcesManager.hxx index 5e8c54d66..c81e7da1d 100644 --- a/src/ResourcesManager/ResourcesManager.hxx +++ b/src/ResourcesManager/ResourcesManager.hxx @@ -117,7 +117,7 @@ class RESOURCESMANAGER_EXPORT ResourcesManager_cpp std::map _resourceManagerMap; //! contain the time where resourcesList was created - time_t _lasttime; + time_t _lasttime = 0; //! the name of the default local resource static const std::string DEFAULT_RESOURCE_NAME; -- 2.39.2