Salome HOME
Try to kill Salome application when a YACS Launcher job is killed
[modules/kernel.git] / src / Launcher / Launcher.cxx
index c169487a2d6c04b3f543f315afe0842938557550..f0d731297f5890dac1791856a4e75047c4712410 100644 (file)
@@ -1,23 +1,23 @@
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
+// 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 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.
+// 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
+// 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
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #ifdef WITH_LIBBATCH
@@ -62,12 +62,12 @@ Launcher_cpp::~Launcher_cpp()
 {
   LAUNCHER_MESSAGE("Launcher_cpp destructor");
 #ifdef WITH_LIBBATCH
-  std::map < std::string, Batch::BatchManager_eClient * >::const_iterator it1;
-  for(it1=_batchmap.begin();it1!=_batchmap.end();it1++)
-    delete it1->second;
   std::map<int, Launcher::Job *>::const_iterator it_job;
   for(it_job = _launcher_job_map.begin(); it_job != _launcher_job_map.end(); it_job++)
     delete it_job->second;
+  std::map <int, Batch::BatchManager_eClient * >::const_iterator it1;
+  for(it1=_batchmap.begin();it1!=_batchmap.end();it1++)
+    delete it1->second;
 #endif
 
   pthread_mutex_destroy(_job_cpt_mutex);
@@ -85,68 +85,7 @@ void
 Launcher_cpp::createJob(Launcher::Job * new_job)
 {
   LAUNCHER_MESSAGE("Creating a new job");
-  
-  // First step take a resource
-  std::vector<std::string> ResourceList;
-  resourceParams params = new_job->getResourceRequiredParams();
-  try{
-    ResourceList = _ResManager->GetFittingResources(params);
-  }
-  catch(const ResourcesException &ex){
-    throw LauncherException(ex.msg.c_str());
-  }
-  if (ResourceList.size() == 0)
-  {
-    LAUNCHER_INFOS("No adequate resource found for the job, number " << new_job->getNumber() << " - deleting it");
-    delete new_job;
-    throw LauncherException("No resource found the job");
-  }
-
-  // Second step configure the job with the resource selected - the first of the list
-  ParserResourcesType resource_definition = _ResManager->GetResourcesDescr(ResourceList[0]);
-
-  // Set resource definition to the job
-  // The job will check if the definitions needed
-  try 
-  {
-    new_job->setResourceDefinition(resource_definition);
-  }
-  catch(const LauncherException &ex)
-  {
-    LAUNCHER_INFOS("Error in the definition of the resource, mess: " << ex.msg);
-    delete new_job;
-    throw ex;
-  }
-
-  // Third step search batch manager for the resource into the map -> instanciate one if does not exist
-  std::string resource_name = resource_definition.Name;
-  std::map<std::string, Batch::BatchManager_eClient *>::const_iterator it = _batchmap.find(resource_name);
-  if(it == _batchmap.end())
-  {
-    try 
-    {
-      // Warning cannot write on one line like this, because map object is constructed before
-      // the method is called...
-      //_batchmap.[resource_name] = FactoryBatchManager(resource_definition);
-      Batch::BatchManager_eClient * batch_client = FactoryBatchManager(resource_definition);
-      _batchmap[resource_name] = batch_client;
-    }
-    catch(const LauncherException &ex)
-    {
-      LAUNCHER_INFOS("Error during creation of the batch manager of the resource, mess: " << ex.msg);
-      delete new_job;
-      throw ex;
-    }
-    catch(const Batch::EmulationException &ex)
-    {
-      LAUNCHER_INFOS("Error during creation of the batch manager of the resource, mess: " << ex.message);
-      delete new_job;
-      throw LauncherException(ex.message);
-    }
-  }
-
-
-  // Final step - add job to the jobs map
+  // Add job to the jobs map
   pthread_mutex_lock(_job_cpt_mutex);
   new_job->setNumber(_job_cpt);
   _job_cpt++;
@@ -190,9 +129,17 @@ Launcher_cpp::launchJob(int job_id)
     throw LauncherException("Bad state of the job: " + job->getState());
   }
 
-  std::string resource_name = job->getResourceDefinition().Name;
+  // Third step search batch manager for the job into the map -> instanciate one if does not exist
+#ifdef WITH_LIBBATCH
+  std::map<int, Batch::BatchManager_eClient *>::const_iterator it = _batchmap.find(job_id);
+  if(it == _batchmap.end())
+  {
+    createBatchManagerForJob(job);
+  }
+#endif
+
   try {
-    Batch::JobId batch_manager_job_id = _batchmap[resource_name]->submitJob(*(job->getBatchJob()));
+    Batch::JobId batch_manager_job_id = _batchmap[job_id]->submitJob(*(job->getBatchJob()));
     job->setBatchManagerJobId(batch_manager_job_id);
     job->setState("QUEUED");
   }
@@ -251,9 +198,45 @@ Launcher_cpp::getJobResults(int job_id, std::string directory)
   try 
   {
     if (directory != "")
-      _batchmap[resource_name]->importOutputFiles(*(job->getBatchJob()), directory);
+      _batchmap[job_id]->importOutputFiles(*(job->getBatchJob()), directory);
+    else
+      _batchmap[job_id]->importOutputFiles(*(job->getBatchJob()), job->getResultDirectory());
+  }
+  catch(const Batch::EmulationException &ex)
+  {
+    LAUNCHER_INFOS("getJobResult is maybe incomplete, exception: " << ex.message);
+    throw LauncherException(ex.message.c_str());
+  }
+  LAUNCHER_MESSAGE("getJobResult ended");
+}
+
+//=============================================================================
+/*!
+ * Get Job dump state - the result directory could be changed
+ */ 
+//=============================================================================
+bool
+Launcher_cpp::getJobDumpState(int job_id, std::string directory)
+{
+  bool rtn;
+  LAUNCHER_MESSAGE("Get Job dump state");
+
+  // Check if job exist
+  std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
+  if (it_job == _launcher_job_map.end())
+  {
+    LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
+    throw LauncherException("Cannot find the job, is it created ?");
+  }
+
+  Launcher::Job * job = it_job->second;
+  std::string resource_name = job->getResourceDefinition().Name;
+  try 
+  {
+    if (directory != "")
+      rtn = _batchmap[job_id]->importDumpStateFile(*(job->getBatchJob()), directory);
     else
-      _batchmap[resource_name]->importOutputFiles(*(job->getBatchJob()), job->getResultDirectory());
+      rtn = _batchmap[job_id]->importDumpStateFile(*(job->getBatchJob()), job->getResultDirectory());
   }
   catch(const Batch::EmulationException &ex)
   {
@@ -261,6 +244,7 @@ Launcher_cpp::getJobResults(int job_id, std::string directory)
     throw LauncherException(ex.message.c_str());
   }
   LAUNCHER_MESSAGE("getJobResult ended");
+  return rtn;
 }
 
 //=============================================================================
@@ -281,10 +265,32 @@ Launcher_cpp::removeJob(int job_id)
     throw LauncherException("Cannot find the job, is it created ?");
   }
 
+  it_job->second->removeJob();
   delete it_job->second;
   _launcher_job_map.erase(it_job);
 }
 
+//=============================================================================
+/*!
+ * stop the job
+ */ 
+//=============================================================================
+void
+Launcher_cpp::stopJob(int job_id)
+{
+  LAUNCHER_MESSAGE("Stop Job");
+
+  // Check if job exist
+  std::map<int, Launcher::Job *>::iterator it_job = _launcher_job_map.find(job_id);
+  if (it_job == _launcher_job_map.end())
+  {
+    LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
+    throw LauncherException("Cannot find the job, is it created ?");
+  }
+
+  it_job->second->stopJob();
+}
+
 //=============================================================================
 /*! 
  *  create a launcher job based on a file
@@ -382,8 +388,8 @@ Launcher_cpp::FactoryBatchManager(ParserResourcesType& params)
     case openmpi:
       mpi = "openmpi";
       break;
-    case slurm:
-      mpi = "slurm";
+    case slurmmpi:
+      mpi = "slurmmpi";
       break;
     case prun:
       mpi = "prun";
@@ -407,9 +413,15 @@ Launcher_cpp::FactoryBatchManager(ParserResourcesType& params)
     case ccc:
       bmType = "eCCC";
       break;
+    case slurm:
+      bmType = "eSLURM";
+      break;
     case ssh_batch:
       bmType = "eSSH";
       break;
+    case ll:
+      bmType = "eLL";
+      break;
     default:
       LAUNCHER_MESSAGE("Bad batch description of the resource: Batch = " << params.Batch);
       throw LauncherException("No batchmanager for that cluster - Bad batch description of the resource");
@@ -421,8 +433,8 @@ Launcher_cpp::FactoryBatchManager(ParserResourcesType& params)
     throw LauncherException("Cannot find batch manager factory");
   }
   LAUNCHER_MESSAGE("Instanciation of batch manager of type: " << bmType);
-  Batch::BatchManager_eClient * batch_client = (*fact)(hostname.c_str(), protocol, mpi.c_str(), nb_proc_per_node);
-  batch_client->setUsername(params.UserName);
+  Batch::BatchManager_eClient * batch_client = (*fact)(hostname.c_str(), params.UserName.c_str(),
+                                                       protocol, mpi.c_str(), nb_proc_per_node);
   return batch_client;
 }
 
@@ -464,6 +476,14 @@ Launcher_cpp::getJobResults(int job_id, std::string directory)
                           "(libBatch was not present at compilation time)");
 }
 
+bool
+Launcher_cpp::getJobDumpState(int job_id, std::string directory)
+{
+  LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job dump state!!!");
+  throw LauncherException("Method Launcher_cpp::getJobDumpState is not available "
+                          "(libBatch was not present at compilation time)");
+}
+
 void
 Launcher_cpp::removeJob(int job_id)
 {
@@ -472,6 +492,13 @@ Launcher_cpp::removeJob(int job_id)
                           "(libBatch was not present at compilation time)");
 }
 
+void
+Launcher_cpp::stopJob(int job_id)
+{
+  throw LauncherException("Method Launcher_cpp::stopJob is not available "
+                          "(libBatch was not present at compilation time)");
+}
+
 long 
 Launcher_cpp::createJobWithFile( const std::string xmlExecuteFile, std::string clusterName)
 {
@@ -526,72 +553,104 @@ Launcher_cpp::getJobs()
 }
 
 void 
-Launcher_cpp::checkFactoryForResource(const std::string & resource_name)
+Launcher_cpp::createBatchManagerForJob(Launcher::Job * job)
 {
-  // Step 1: Check if resource exist in the resource manager
-  ParserResourcesType resource_definition;
+  int job_id = job->getNumber();
+
+  // Select a ressource for the job
+  std::vector<std::string> ResourceList;
+  resourceParams params = job->getResourceRequiredParams();
   try
   {
-    resource_definition = _ResManager->GetResourcesDescr(resource_name);
+    ResourceList = _ResManager->GetFittingResources(params);
   }
   catch(const ResourcesException &ex)
   {
-    LAUNCHER_INFOS(ex.msg);
-    throw LauncherException(ex.msg);
+    throw LauncherException(ex.msg.c_str());
+  }
+  if (ResourceList.size() == 0)
+  {
+    LAUNCHER_INFOS("No adequate resource found for the job, number " << job->getNumber());
+    job->setState("ERROR");
+    throw LauncherException("No resource found the job");
   }
 
-  // Step 2: We can now add a Factory is the resource is correctly define
-  std::map<std::string, Batch::BatchManager_eClient *>::const_iterator it = _batchmap.find(resource_name);
+  // Configure the job with the resource selected - the first of the list
+  ParserResourcesType resource_definition = _ResManager->GetResourcesDescr(ResourceList[0]);
+
+  // Set resource definition to the job
+  // The job will check if the definitions needed
+  try
+  {
+    job->setResourceDefinition(resource_definition);
+  }
+  catch(const LauncherException &ex)
+  {
+    LAUNCHER_INFOS("Error in the definition of the resource, mess: " << ex.msg);
+    job->setState("ERROR");
+    throw ex;
+  }
+
+  // Step 2: We can now add a Factory if the resource is correctly define
+#ifdef WITH_LIBBATCH
+  std::map<int, Batch::BatchManager_eClient *>::const_iterator it = _batchmap.find(job_id);
   if(it == _batchmap.end())
   {
     try
     {
       // Warning cannot write on one line like this, because map object is constructed before
       // the method is called...
-      //_batchmap.[resource_name] = FactoryBatchManager(resource_definition);
+      //_batchmap[job_id] = FactoryBatchManager(resource_definition);
       Batch::BatchManager_eClient * batch_client = FactoryBatchManager(resource_definition);
-      _batchmap[resource_name] = batch_client;
+      _batchmap[job_id] = batch_client;
     }
     catch(const LauncherException &ex)
     {
-      LAUNCHER_INFOS("Error during creation of the batch manager of the resource, mess: " << ex.msg);
+      LAUNCHER_INFOS("Error during creation of the batch manager of the job, mess: " << ex.msg);
       throw ex;
     }
     catch(const Batch::EmulationException &ex)
     {
-      LAUNCHER_INFOS("Error during creation of the batch manager of the resource, mess: " << ex.message);
+      LAUNCHER_INFOS("Error during creation of the batch manager of the job, mess: " << ex.message);
+      throw LauncherException(ex.message);
+    }
+    catch(const Batch::InvalidArgumentException &ex)
+    {
+      LAUNCHER_INFOS("Error during creation of the batch manager of the job, mess: " << ex.message);
       throw LauncherException(ex.message);
     }
   }
+#endif
 }
 
 void 
 Launcher_cpp::addJobDirectlyToMap(Launcher::Job * new_job, const std::string job_reference)
 {
+  // Step 0: Calculated job_id
+  pthread_mutex_lock(_job_cpt_mutex);
+  _job_cpt++;
+  int job_id = _job_cpt;
+  new_job->setNumber(job_id);
+  pthread_mutex_unlock(_job_cpt_mutex);
+
   // Step 1: check if resource is already in the map
-  std::string resource_name = new_job->getResourceDefinition().Name;
-  checkFactoryForResource(resource_name);
-  ParserResourcesType resource_definition = _ResManager->GetResourcesDescr(resource_name);
-  new_job->setResourceDefinition(resource_definition);
+  createBatchManagerForJob(new_job);
 
   // Step 2: add the job to the batch manager
+#ifdef WITH_LIBBATCH
   try
   {
-    Batch::JobId batch_manager_job_id = _batchmap[resource_name]->addJob(*(new_job->getBatchJob()), 
-                                                                         job_reference);
+    Batch::JobId batch_manager_job_id = _batchmap[job_id]->addJob(*(new_job->getBatchJob()),
+                                                                  job_reference);
     new_job->setBatchManagerJobId(batch_manager_job_id);
   }
   catch(const Batch::EmulationException &ex)
   {
-    LAUNCHER_INFOS("Job is not launched, exception in submitJob: " << ex.message);
+    LAUNCHER_INFOS("Job cannot be added, exception in addJob: " << ex.message);
     throw LauncherException(ex.message.c_str());
   }
 
   // Step 3: add job to launcher map
-  pthread_mutex_lock(_job_cpt_mutex);
-  new_job->setNumber(_job_cpt);
-  _job_cpt++;
-  pthread_mutex_unlock(_job_cpt_mutex);
   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(new_job->getNumber());
   if (it_job == _launcher_job_map.end())
     _launcher_job_map[new_job->getNumber()] = new_job;
@@ -602,4 +661,5 @@ Launcher_cpp::addJobDirectlyToMap(Launcher::Job * new_job, const std::string job
     throw LauncherException("A job as already the same id - job is not created !");
   }
   LAUNCHER_MESSAGE("New job added");
+#endif
 }