diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp index 7d4d71db447e64bb58d48559871ab8d9f9038dcc..34f44f7f5eea940e46784b942ffac71b3bd2c7bf 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp @@ -50,6 +50,9 @@ void export_FacilityInfo() .def("liveListener", &FacilityInfo::liveListener, return_value_policy<copy_const_reference>(), "Returns the name of the default live listener") + + .def("computeResources", &FacilityInfo::computeResources, + "Returns a vector of the available compute resources") ; } diff --git a/Code/Mantid/scripts/Interface/reduction_application.py b/Code/Mantid/scripts/Interface/reduction_application.py index 1e3ca9671ff317b8c27ac806b30488fff219f160..96985f771ae6ebf54c5b1a8b0233000ac33c198d 100644 --- a/Code/Mantid/scripts/Interface/reduction_application.py +++ b/Code/Mantid/scripts/Interface/reduction_application.py @@ -4,6 +4,7 @@ import sys, os import traceback from PyQt4 import QtGui, QtCore, uic +import math # Check whether Mantid is available IS_IN_MANTIDPLOT = False @@ -78,10 +79,16 @@ class ReductionGUI(QtGui.QMainWindow, ui.ui_reduction_main.Ui_SANSReduction): # Current file name self._filename = None - # Cluster credentials + # Cluster credentials and options self._cluster_user = None self._cluster_pass = None - + self._number_of_nodes = 4 + self._cores_per_node = 4 + self._compute_resources = ['Fermi'] + if IS_IN_MANTIDPLOT \ + and hasattr(ConfigService.Instance().getFacility(), "computeResources"): + self._compute_resources = ConfigService.Instance().getFacility().computeResources() + # Internal flag for clearing all settings and restarting the application self._clear_and_restart = False @@ -351,15 +358,22 @@ class ReductionGUI(QtGui.QMainWindow, ui.ui_reduction_main.Ui_SANSReduction): Show dialog to get cluster submission details """ class ClusterDialog(QtGui.QDialog, ui.ui_cluster_details_dialog.Ui_Dialog): - def __init__(self, instrument_list=None): + def __init__(self, compute_resources=None): QtGui.QDialog.__init__(self) self.setupUi(self) + self.resource_combo.clear() + for res in compute_resources: + self.resource_combo.addItem(QtGui.QApplication.translate("Dialog", res, None, QtGui.QApplication.UnicodeUTF8)) - dialog = ClusterDialog() + dialog = ClusterDialog(self._compute_resources) dialog.exec_() if dialog.result()==1: self._cluster_user = dialog.username_edit.text() self._cluster_pass = dialog.pass_edit.text() + n_cores = dialog.cores_box.value() + self._number_of_nodes = int(math.ceil(n_cores/4)) + self._cores_per_node = 4 + self._compute_resource = dialog.resource_combo.currentText() def _clear_and_close(self): """ @@ -453,7 +467,10 @@ class ReductionGUI(QtGui.QMainWindow, ui.ui_reduction_main.Ui_SANSReduction): if self._interface is not None \ and self._cluster_user is not None \ and self._cluster_pass is not None: - self._interface.cluster_submit(self._cluster_user, self._cluster_pass) + self._interface.cluster_submit(self._cluster_user, self._cluster_pass, + resource=self._compute_resource, + nodes=self._number_of_nodes, + cores_per_node=self._cores_per_node) def open_file(self, file_path=None): """ diff --git a/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py b/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py index 3fd7e63bada851c1ca26cda2b75ff035e685db69..4f198503a3e608107d2d0099934444c910091e3a 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py @@ -124,7 +124,8 @@ class InstrumentInterface(object): self._error_report(traceback.format_exc()) return None - def cluster_submit(self, user, pwd): + def cluster_submit(self, user, pwd, resource=None, + nodes=4, cores_per_node=4): """ Pass the interface data to the scripter for parallel reduction """ @@ -135,7 +136,7 @@ class InstrumentInterface(object): if job_data_dir is None: job_data_dir = os.path.expanduser('~') - self.scripter.cluster_submit(job_data_dir, user, pwd) + self.scripter.cluster_submit(job_data_dir, user, pwd, resource, nodes, cores_per_node) except: msg = "The following error was encountered:\n\n%s" % sys.exc_value msg += "\n\nPlease check your reduction parameters\n" diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/scripter.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/scripter.py index 654b2f488a555e774fb321ec5e168bcb81e95de1..2ef1f4181e10cc4b9f7f766914e20e8a8d475b72 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/scripter.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/scripter.py @@ -434,7 +434,8 @@ class BaseReductionScripter(object): else: raise RuntimeError, "Reduction could not be executed: Mantid could not be imported" - def cluster_submit(self, output_dir, user, pwd): + def cluster_submit(self, output_dir, user, pwd, resource=None, + nodes=4, cores_per_node=4): """ Submit the reduction job to a cluster @param output_dir: directory where the output data will be written @@ -455,7 +456,8 @@ class BaseReductionScripter(object): Logger.get("scripter").notice("Execution script: %s" % script_path) # Submit the job - submit_cmd = "SubmitRemoteJob(ComputeResource='Fermi', NumNodes=2, CoresPerNode=4, " + submit_cmd = "SubmitRemoteJob(ComputeResource=%s, " % resource + submit_cmd += "NumNodes=%s, CoresPerNode=%s, " % (nodes, cores_per_node) submit_cmd += "UserName='%s', GroupName='users', Password='%s', " % (user, pwd) submit_cmd += "TransactionID='mantid_remote', " submit_cmd += "ScriptName='%s')" % script_path diff --git a/Code/Mantid/scripts/Interface/ui/cluster_details_dialog.ui b/Code/Mantid/scripts/Interface/ui/cluster_details_dialog.ui index cad1ad3c96f565469badd26875868455c13acd37..c4a5c8804905aa82e6fca918841579fd5a73ce02 100644 --- a/Code/Mantid/scripts/Interface/ui/cluster_details_dialog.ui +++ b/Code/Mantid/scripts/Interface/ui/cluster_details_dialog.ui @@ -10,7 +10,7 @@ <x>0</x> <y>0</y> <width>439</width> - <height>143</height> + <height>433</height> </rect> </property> <property name="sizePolicy"> @@ -29,6 +29,58 @@ <bool>true</bool> </property> <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="label_3"> + <property name="minimumSize"> + <size> + <width>160</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>160</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Compute resource:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="resource_combo"/> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QLabel" name="label_5"> + <property name="minimumSize"> + <size> + <width>160</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>160</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Number of cores:</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="cores_box"/> + </item> + </layout> + </item> <item> <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> diff --git a/Code/Mantid/scripts/Interface/ui/ui_cluster_details_dialog.py b/Code/Mantid/scripts/Interface/ui/ui_cluster_details_dialog.py index 53895d99fa707111a3a07d5978f8af7f6ca27ae1..bc8622cf23b62cb11ee29ad757e819379c389d35 100644 --- a/Code/Mantid/scripts/Interface/ui/ui_cluster_details_dialog.py +++ b/Code/Mantid/scripts/Interface/ui/ui_cluster_details_dialog.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'ui/cluster_details_dialog.ui' # -# Created: Thu May 2 09:45:32 2013 +# Created: Fri May 3 11:17:46 2013 # by: PyQt4 UI code generator 4.7.4 # # WARNING! All changes made in this file will be lost! @@ -13,7 +13,7 @@ class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") Dialog.setWindowModality(QtCore.Qt.ApplicationModal) - Dialog.resize(439, 143) + Dialog.resize(439, 433) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -23,6 +23,28 @@ class Ui_Dialog(object): Dialog.setModal(True) self.verticalLayout = QtGui.QVBoxLayout(Dialog) self.verticalLayout.setObjectName("verticalLayout") + self.horizontalLayout_3 = QtGui.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.label_3 = QtGui.QLabel(Dialog) + self.label_3.setMinimumSize(QtCore.QSize(160, 0)) + self.label_3.setMaximumSize(QtCore.QSize(160, 16777215)) + self.label_3.setObjectName("label_3") + self.horizontalLayout_3.addWidget(self.label_3) + self.resource_combo = QtGui.QComboBox(Dialog) + self.resource_combo.setObjectName("resource_combo") + self.horizontalLayout_3.addWidget(self.resource_combo) + self.verticalLayout.addLayout(self.horizontalLayout_3) + self.horizontalLayout_5 = QtGui.QHBoxLayout() + self.horizontalLayout_5.setObjectName("horizontalLayout_5") + self.label_5 = QtGui.QLabel(Dialog) + self.label_5.setMinimumSize(QtCore.QSize(160, 0)) + self.label_5.setMaximumSize(QtCore.QSize(160, 16777215)) + self.label_5.setObjectName("label_5") + self.horizontalLayout_5.addWidget(self.label_5) + self.cores_box = QtGui.QSpinBox(Dialog) + self.cores_box.setObjectName("cores_box") + self.horizontalLayout_5.addWidget(self.cores_box) + self.verticalLayout.addLayout(self.horizontalLayout_5) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.label_2 = QtGui.QLabel(Dialog) @@ -64,6 +86,8 @@ class Ui_Dialog(object): def retranslateUi(self, Dialog): Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8)) + self.label_3.setText(QtGui.QApplication.translate("Dialog", "Compute resource:", None, QtGui.QApplication.UnicodeUTF8)) + self.label_5.setText(QtGui.QApplication.translate("Dialog", "Number of cores:", None, QtGui.QApplication.UnicodeUTF8)) self.label_2.setText(QtGui.QApplication.translate("Dialog", "Username:", None, QtGui.QApplication.UnicodeUTF8)) self.label.setText(QtGui.QApplication.translate("Dialog", "Password:", None, QtGui.QApplication.UnicodeUTF8))