Salome HOME
Add job parameter Memory per CPU (EDF issue #2671)
authorbarate <barate>
Mon, 23 Sep 2013 13:31:19 +0000 (13:31 +0000)
committerbarate <barate>
Mon, 23 Sep 2013 13:31:19 +0000 (13:31 +0000)
src/engine/BL_Job.cxx
src/engine/BL_Job.hxx
src/engine/BL_SALOMEServices.cxx
src/genericgui/BL_CreateJobWizard.cxx
src/genericgui/BL_CreateJobWizard.hxx
src/genericgui/BL_JobTab.cxx
src/genericgui/BL_JobsManager_QT.cxx
src/genericgui/ResourceRequirementsWizardPage.ui

index ba78ceffb353ceda03319b84c696f11ef30cf336..a172e8985fc617f59ea08c82f5d7977a53cd7812 100644 (file)
@@ -23,11 +23,13 @@ BL::Job::Job()
 {
   DEBTRACE("Creating BL::Job");
   _name = "";
+  _type = COMMAND;
   _job_file = "";
   _env_file = "";
   _batch_params.batch_directory = "";
   _batch_params.maximum_duration = "";
-  _batch_params.expected_memory = "";
+  _batch_params.mem_limit = 0;
+  _batch_params.mem_req_type = MEM_PER_NODE;
   _batch_params.nb_proc = 0;
   _batch_params.exclusive = false;
   _files_params.result_directory = "";
@@ -48,11 +50,13 @@ BL::Job::Job(const std::string & name)
 {
   DEBTRACE("Creating BL::Job with name : " << name);
   _name = name;
+  _type = COMMAND;
   _job_file = "";
   _env_file = "";
   _batch_params.batch_directory = "";
   _batch_params.maximum_duration = "";
-  _batch_params.expected_memory = "";
+  _batch_params.mem_limit = 0;
+  _batch_params.mem_req_type = MEM_PER_NODE;
   _batch_params.nb_proc = 0;
   _batch_params.exclusive = false;
   _files_params.result_directory = "";
index 464abb3a4e168a6b614e71892aec4a3289c4abb8..e20b24590bd6dd304a7be16b088f36a4412a685c 100644 (file)
@@ -56,11 +56,14 @@ namespace BL{
       void setDumpYACSState(const int & dump_yacs_state);
       int getDumpYACSState();
 
+      enum MemReqType {MEM_PER_NODE, MEM_PER_CPU};
+
       struct BatchParam
       {
         std::string batch_directory;
         std::string maximum_duration;
-        std::string expected_memory;
+        unsigned long mem_limit;
+        MemReqType mem_req_type;
         int nb_proc;
         bool exclusive;
 
index 911e5649669bb7d23d50d5371f619e4ebdccac3e..2ec486c21f226adedddf856884a8bfcc8b4f919a 100644 (file)
@@ -323,14 +323,19 @@ BL::SALOMEServices::create_job(BL::Job * job)
   job_parameters->exclusive = cpp_batch_params.exclusive;
 
   // Memory
-  CORBA::Long memory;
-  std::string ram = cpp_batch_params.expected_memory.substr(0,cpp_batch_params.expected_memory.size()-2);
-  std::istringstream iss(ram);
-  iss >> memory;
-  std::string unity = cpp_batch_params.expected_memory.substr(cpp_batch_params.expected_memory.size()-2, 2);
-  if((unity.find("gb") != std::string::npos))
-    memory = memory * 1024;
-  job_parameters->resource_required.mem_mb = memory;
+  switch (cpp_batch_params.mem_req_type)
+  {
+  case BL::Job::MEM_PER_NODE:
+    job_parameters->resource_required.mem_mb = cpp_batch_params.mem_limit;
+    job_parameters->mem_per_cpu = 0;
+    break;
+  case BL::Job::MEM_PER_CPU:
+    job_parameters->resource_required.mem_mb = 0;
+    job_parameters->mem_per_cpu = cpp_batch_params.mem_limit;
+    break;
+  default:
+    throw Exception("Unknown memory requirement, unable to create job");
+  }
 
   // Parameters for COORM
   job_parameters->launcher_file = CORBA::string_dup(cpp_batch_params.launcher_file.c_str());
@@ -625,11 +630,19 @@ BL::SALOMEServices::get_new_job(int job_number)
     batch_param.maximum_duration = job_parameters->maximum_duration.in();
     batch_param.nb_proc = job_parameters->resource_required.nb_proc;
     batch_param.exclusive = job_parameters->exclusive;
-    std::ostringstream mem_stream;
-    mem_stream << job_parameters->resource_required.mem_mb << "mb";
-    batch_param.expected_memory = mem_stream.str();
 
-       // Parameters for COORM
+    if (job_parameters->mem_per_cpu != 0)
+    {
+      batch_param.mem_limit = job_parameters->mem_per_cpu;
+      batch_param.mem_req_type = BL::Job::MEM_PER_CPU;
+    }
+    else
+    {
+      batch_param.mem_limit = job_parameters->resource_required.mem_mb;
+      batch_param.mem_req_type = BL::Job::MEM_PER_NODE;
+    }
+
+    // Parameters for COORM
     batch_param.launcher_file = job_parameters->launcher_file.in();
     batch_param.launcher_args = job_parameters->launcher_args.in();
 
index 2152d41ae5ed01168a51340bdad83fc3627a34c8..a5db879a25159fe2865842e08055909aea9dcc99 100644 (file)
@@ -34,6 +34,9 @@
 #undef ERROR
 #endif
 
+using namespace std;
+using namespace BL;
+
 BL::CreateJobWizard::CreateJobWizard(BL::JobsManager_QT * jobs_manager, BL::SALOMEServices * salome_services)
 {
   DEBTRACE("Creating BL::CreateJobWizard");
@@ -53,7 +56,8 @@ BL::CreateJobWizard::CreateJobWizard(BL::JobsManager_QT * jobs_manager, BL::SALO
   coorm_batch_directory = "";
 
   maximum_duration = "";
-  expected_memory = "";
+  mem_limit = 0;
+  mem_req_type = BL::Job::MEM_PER_NODE;
   nb_proc = 1;
 
   // Parameters for COORM
@@ -73,9 +77,10 @@ BL::CreateJobWizard::CreateJobWizard(BL::JobsManager_QT * jobs_manager, BL::SALO
 
   // Common pages
   _job_name_page = new BL::JobNamePage(this, _jobs_manager);
+  _batch_parameters_page = new BL::BatchParametersPage(this, salome_services);
 
   setPage(Page_JobName, _job_name_page);
-  setPage(Page_BatchParameters, new BL::BatchParametersPage(this));
+  setPage(Page_BatchParameters, _batch_parameters_page);
 
   // For COORM
   setPage(Page_COORM_BatchParameters, new BL::COORM_BatchParametersPage(this, salome_services));
@@ -183,16 +188,18 @@ BL::CreateJobWizard::clone(const std::string & name)
       setField("duration_min", min);
     }
 
-    std::string mem_type = batch_params.expected_memory.substr(batch_params.expected_memory.size() - 2, 2);
-    if (mem_type == "mb")
-      setField("mem_type", 0);
+    unsigned long long mem_mb = batch_params.mem_limit;
+    if (mem_mb % 1024 == 0)
+    {
+      setField("mem_value", mem_mb / 1024);
+      _batch_parameters_page->setMemUnit(BatchParametersPage::GB);
+    }
     else
-      setField("mem_type", 1);
-    std::string mem_value = batch_params.expected_memory.substr(0, batch_params.expected_memory.find(mem_type));
-    int mem_val; 
-    std::istringstream iss_mem(mem_value);
-    iss_mem >> mem_val;
-    setField("mem_value", mem_val);
+    {
+      setField("mem_value", mem_mb);
+      _batch_parameters_page->setMemUnit(BatchParametersPage::MB);
+    }
+    _batch_parameters_page->setMemReqType(batch_params.mem_req_type);
 
     BL::Job::FilesParam files_params = job->getFilesParameters();
 
@@ -282,12 +289,20 @@ BL::CreateJobWizard::end(int result)
       maximum_duration = time_hour.toStdString() + ":" + time_min.toStdString();
     }
 
-    QString mem = field("mem_value").toString();
-    int mem_type_i = field("mem_type").toInt();
-    QString mem_type("gb");
-    if (mem_type_i == 0)
-      mem_type = "mb";
-    expected_memory = mem.trimmed().toStdString() + mem_type.toStdString();
+    unsigned long mem = field("mem_value").toULongLong();
+    BatchParametersPage::MemUnit mem_unit = _batch_parameters_page->getMemUnit();
+    switch (mem_unit)
+    {
+    case BatchParametersPage::MB:
+      mem_limit = mem;
+      break;
+    case BatchParametersPage::GB:
+      mem_limit = mem * 1024;
+      break;
+    default:
+      throw Exception("Invalid memory unit");
+    }
+    mem_req_type = _batch_parameters_page->getMemReqType();
 
     nb_proc = field("proc_value").toInt();
     exclusive = field("exclusive").toBool();
@@ -643,44 +658,119 @@ BL::CommandMainPage::nextId() const
   return BL::CreateJobWizard::Page_Resource;
 }
 
-BL::BatchParametersPage::BatchParametersPage(QWidget * parent)
+BatchParametersPage::BatchParametersPage(QWidget * parent, SALOMEServices * salome_services)
 : QWizardPage(parent),
-  ui(new Ui::ResourceRequirementsWizardPage)
+  ui(new Ui::ResourceRequirementsWizardPage),
+  _salome_services(salome_services),
+  resource_choosed()
 {
   ui->setupUi(this);
 
   registerField("duration_hour", ui->spin_duration_hour);
   registerField("duration_min", ui->spin_duration_min);
   registerField("mem_value", ui->spin_memory);
-  registerField("mem_type", ui->combo_memory);
   registerField("proc_value", ui->spin_proc);
   registerField("exclusive", ui->check_exclusive);
+
+  ui->combo_memory_unit->insertItem(ui->combo_memory_unit->count(), "MB", MB);
+  ui->combo_memory_unit->insertItem(ui->combo_memory_unit->count(), "GB", GB);
+  setMemUnit(GB);
+
+  ui->combo_memory_req_type->insertItem(ui->combo_memory_req_type->count(),
+                                        "per node", Job::MEM_PER_NODE);
+  ui->combo_memory_req_type->insertItem(ui->combo_memory_req_type->count(),
+                                        "per core", Job::MEM_PER_CPU);
+
+  ui->label_warning_icon->setPixmap(QIcon::fromTheme("dialog-error").pixmap(16, 16));
+
+  connect(ui->combo_memory_req_type, SIGNAL(currentIndexChanged(int)), this, SIGNAL(completeChanged()));
+  connect(ui->check_exclusive, SIGNAL(stateChanged(int)), this, SIGNAL(completeChanged()));
 };
 
-BL::BatchParametersPage::~BatchParametersPage()
+BatchParametersPage::~BatchParametersPage()
 {
   delete ui;
 }
 
-void BL::BatchParametersPage::cleanupPage() {}
+void
+BatchParametersPage::initializePage()
+{
+  string f_resource_choosed = field("resource_choosed").toString().toStdString();
+  if (f_resource_choosed != resource_choosed)
+  {
+    resource_choosed = f_resource_choosed;
+    // If choosed resource has a SLURM batch manager, activate option "memory per cpu"
+    ResourceDescr resource_descr = _salome_services->getResourceDescr(resource_choosed);
+    if (resource_descr.batch == "slurm")
+    {
+      ui->combo_memory_req_type->setEnabled(true);
+    }
+    else
+    {
+      ui->combo_memory_req_type->setEnabled(false);
+      setMemReqType(Job::MEM_PER_NODE);
+    }
+  }
+}
+
+BatchParametersPage::MemUnit
+BatchParametersPage::getMemUnit() const
+{
+  int idx = ui->combo_memory_unit->currentIndex();
+  return (MemUnit)(ui->combo_memory_unit->itemData(idx).toInt());
+}
+
+void
+BatchParametersPage::setMemUnit(MemUnit mem_unit)
+{
+  ui->combo_memory_unit->setCurrentIndex(ui->combo_memory_unit->findData(mem_unit));
+}
+
+Job::MemReqType
+BatchParametersPage::getMemReqType() const
+{
+  int idx = ui->combo_memory_req_type->currentIndex();
+  return (Job::MemReqType)(ui->combo_memory_req_type->itemData(idx).toInt());
+}
+
+void
+BatchParametersPage::setMemReqType(Job::MemReqType mem_req_type)
+{
+  ui->combo_memory_req_type->setCurrentIndex(ui->combo_memory_req_type->findData(mem_req_type));
+}
 
 bool
-BL::BatchParametersPage::validatePage()
+BatchParametersPage::isComplete() const
 {
-  int mem = field("mem_value").toInt();
-  if (mem == 0)
+  QString warn_msg;
+  if (field("exclusive").toBool() && getMemReqType() == Job::MEM_PER_CPU)
+  {
+    warn_msg = "Parameters \"Exclusive\" and \"Memory required per core\" "
+               "are mutually exclusive. Please uncheck \"Exclusive\" if you "
+               "want to specify the memory requirement \"per core\".";
+  }
+  ui->label_warning_text->setText(warn_msg);
+  if (warn_msg.isEmpty())
+  {
+    ui->label_warning_icon->hide();
+    return true;
+  }
+  else
   {
-    QMessageBox::warning(NULL, "Memory Error", "Please enter an expected memory");
+    ui->label_warning_icon->show();
     return false;
   }
+}
 
-  return true;
+void
+BatchParametersPage::cleanupPage()
+{
 }
 
 int 
-BL::BatchParametersPage::nextId() const
+BatchParametersPage::nextId() const
 {
-  return BL::CreateJobWizard::Page_Files;
+  return CreateJobWizard::Page_Files;
 }
 
 BL::COORM_BatchParametersPage::COORM_BatchParametersPage(QWidget * parent, BL::SALOMEServices * salome_services)
index b1f5c67d581d79376d0faca0da696f469d074a9a..16260981442e8a792de32865e74395add94b96f2 100644 (file)
@@ -38,6 +38,7 @@ namespace BL{
 
   class JobsManager_QT;
   class JobNamePage;
+  class BatchParametersPage;
   class CreateJobWizard: public QWizard
   {
     Q_OBJECT
@@ -54,13 +55,12 @@ namespace BL{
       void end(int result);
 
     private:
-      //Page Name
-      QLineEdit * _nameLineEdit;
       BL::JobsManager_QT * _jobs_manager;
       QListWidget * _input_files_list;
       QListWidget * _output_files_list;
 
       BL::JobNamePage * _job_name_page;
+      BL::BatchParametersPage * _batch_parameters_page;
       BL::SALOMEServices * _salome_services;
 
     public:
@@ -75,17 +75,18 @@ namespace BL{
 
       std::string batch_directory;
 
-         // For COORM
-         std::string coorm_batch_directory;
+      // For COORM
+      std::string coorm_batch_directory;
 
-         std::string maximum_duration;
-      std::string expected_memory;
+      std::string maximum_duration;
+      unsigned long mem_limit;
+      BL::Job::MemReqType mem_req_type;
       int nb_proc;
       bool exclusive;
 
-         // Parameters for COORM
-         std::string launcher_file;
-         std::string launcher_args;
+      // Parameters for COORM
+      std::string launcher_file;
+      std::string launcher_args;
 
       std::string result_directory;
       std::list<std::string> input_files_list;
@@ -104,7 +105,7 @@ namespace BL{
             Page_Command_Main_Definitions,
             Page_PythonSalome_Main_Definitions,
             Page_BatchParameters,
-                       Page_COORM_BatchParameters,
+            Page_COORM_BatchParameters,
             Page_Files,
             Page_Resource,
             Page_Conclusion};
@@ -154,15 +155,26 @@ namespace BL{
     Q_OBJECT
 
     public:
-      BatchParametersPage(QWidget * parent);
+      enum MemUnit {MB, GB};
+
+      BatchParametersPage(QWidget * parent, BL::SALOMEServices * salome_services);
       virtual ~BatchParametersPage();
 
-      virtual bool validatePage();
+      virtual void initializePage();
+      virtual bool isComplete() const;
       virtual int nextId() const;
       virtual void cleanupPage();
 
+      MemUnit getMemUnit() const;
+      void setMemUnit(MemUnit mem_unit);
+
+      BL::Job::MemReqType getMemReqType() const;
+      void setMemReqType(BL::Job::MemReqType mem_req_type);
+
     private:
       Ui::ResourceRequirementsWizardPage * ui;
+      BL::SALOMEServices * _salome_services;
+      std::string resource_choosed;
   };
 
   // For COORM
index eaf9bbef96ec9a495c42bae42c52f3458120d70b..4d294d25da35edc9f427a51506e955c600dc2725 100644 (file)
@@ -24,6 +24,8 @@
 #undef ERROR
 #endif
 
+using namespace std;
+
 BL::JobTab::JobTab(QWidget *parent, BL::JobsManager_QT * jobs_manager) : QTabWidget(parent)
 {
   DEBTRACE("Creating BL::JobTab");
@@ -234,12 +236,31 @@ BL::JobTab::job_selected(const QModelIndex & index)
     _job_rd_label_value->setText(QString(files_params.result_directory.c_str()));
 
     _job_mdt_label_value->setText(QString(batch_params.maximum_duration.c_str()));
-    _job_em_label_value->setText(QString(batch_params.expected_memory.c_str()));
     _job_nop_label_value->setText(QVariant(batch_params.nb_proc).toString());
     QString exclText = (batch_params.exclusive)? "yes" : "no";
     _job_excl_label_value->setText(exclText);
 
-       // Parameters for COORM
+    // Memory requirement
+    unsigned long long mem_mb = batch_params.mem_limit;
+    ostringstream mem_ss;
+    if (mem_mb % 1024 == 0)
+      mem_ss << mem_mb / 1024 << "GB";
+    else
+      mem_ss << mem_mb << "MB";
+    switch (batch_params.mem_req_type)
+    {
+    case BL::Job::MEM_PER_NODE:
+      mem_ss << " per node";
+      break;
+    case BL::Job::MEM_PER_CPU:
+      mem_ss << " per core";
+      break;
+    default:
+      throw Exception("Unknown memory requirement, unable to show selected job");
+    }
+    _job_em_label_value->setText(QString(mem_ss.str().c_str()));
+
+    // Parameters for COORM
     _job_lf_label_value->setText(QString(batch_params.launcher_file.c_str()));
     _job_la_label_value->setText(QString(batch_params.launcher_args.c_str()));
 
index 987f1f814f92be81979c9973f7ec74c7a4fed2cb..5f1f15e78b124faed6740acd42ce7251dfd44f6f 100644 (file)
@@ -306,7 +306,8 @@ BL::JobsManager_QT::create_job_with_wizard(BL::CreateJobWizard & wizard)
   }
 
   param.maximum_duration = wizard.maximum_duration;
-  param.expected_memory = wizard.expected_memory;
+  param.mem_limit = wizard.mem_limit;
+  param.mem_req_type = wizard.mem_req_type;
   param.nb_proc = wizard.nb_proc;
   param.exclusive = wizard.exclusive;
 
index bca7c53b38b40b3945504d6be0039107170ba70f..d5e4ddcc09be1cff108332ec7565148c830d305a 100644 (file)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>512</width>
-    <height>325</height>
+    <width>525</width>
+    <height>383</height>
    </rect>
   </property>
   <property name="windowTitle">
            </widget>
           </item>
           <item>
-           <widget class="QComboBox" name="combo_memory">
+           <widget class="QComboBox" name="combo_memory_unit">
             <property name="currentIndex">
-             <number>1</number>
+             <number>-1</number>
             </property>
-            <item>
-             <property name="text">
-              <string>MB</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>GB</string>
-             </property>
-            </item>
            </widget>
           </item>
           <item>
-           <widget class="QComboBox" name="comboBox_2">
-            <property name="enabled">
-             <bool>false</bool>
-            </property>
-            <item>
-             <property name="text">
-              <string>per node</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>per core</string>
-             </property>
-            </item>
-           </widget>
+           <widget class="QComboBox" name="combo_memory_req_type"/>
           </item>
          </layout>
         </item>
      </layout>
     </widget>
    </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <item>
+      <widget class="QLabel" name="label_warning_icon"/>
+     </item>
+     <item>
+      <widget class="QLabel" name="label_warning_text">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>50</height>
+        </size>
+       </property>
+       <property name="wordWrap">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
   </layout>
  </widget>
  <resources/>