Show More
@@ -0,0 +1,229 b'' | |||||
|
1 | #!/usr/bin/env python | |||
|
2 | # encoding: utf-8 | |||
|
3 | """ | |||
|
4 | Job and task components for writing .xml files that the Windows HPC Server | |||
|
5 | 2008 can use to start jobs. | |||
|
6 | """ | |||
|
7 | ||||
|
8 | #----------------------------------------------------------------------------- | |||
|
9 | # Copyright (C) 2008-2009 The IPython Development Team | |||
|
10 | # | |||
|
11 | # Distributed under the terms of the BSD License. The full license is in | |||
|
12 | # the file COPYING, distributed as part of this software. | |||
|
13 | #----------------------------------------------------------------------------- | |||
|
14 | ||||
|
15 | #----------------------------------------------------------------------------- | |||
|
16 | # Imports | |||
|
17 | #----------------------------------------------------------------------------- | |||
|
18 | ||||
|
19 | from __future__ import with_statement | |||
|
20 | ||||
|
21 | import os | |||
|
22 | import re | |||
|
23 | ||||
|
24 | from xml.etree import ElementTree as ET | |||
|
25 | from xml.dom import minidom | |||
|
26 | ||||
|
27 | from IPython.core.component import Component | |||
|
28 | from IPython.external import Itpl | |||
|
29 | from IPython.utils.traitlets import ( | |||
|
30 | Str, Int, List, Unicode, Instance, | |||
|
31 | Enum, Bool | |||
|
32 | ) | |||
|
33 | ||||
|
34 | #----------------------------------------------------------------------------- | |||
|
35 | # Job and Task Component | |||
|
36 | #----------------------------------------------------------------------------- | |||
|
37 | ||||
|
38 | ||||
|
39 | def as_str(value): | |||
|
40 | if isinstance(value, str): | |||
|
41 | return value | |||
|
42 | elif isinstance(value, bool): | |||
|
43 | if value: | |||
|
44 | return 'true' | |||
|
45 | else: | |||
|
46 | return 'false' | |||
|
47 | elif isinstance(value, (int, float)): | |||
|
48 | return repr(value) | |||
|
49 | else: | |||
|
50 | return value | |||
|
51 | ||||
|
52 | ||||
|
53 | def indent(elem, level=0): | |||
|
54 | i = "\n" + level*" " | |||
|
55 | if len(elem): | |||
|
56 | if not elem.text or not elem.text.strip(): | |||
|
57 | elem.text = i + " " | |||
|
58 | if not elem.tail or not elem.tail.strip(): | |||
|
59 | elem.tail = i | |||
|
60 | for elem in elem: | |||
|
61 | indent(elem, level+1) | |||
|
62 | if not elem.tail or not elem.tail.strip(): | |||
|
63 | elem.tail = i | |||
|
64 | else: | |||
|
65 | if level and (not elem.tail or not elem.tail.strip()): | |||
|
66 | elem.tail = i | |||
|
67 | ||||
|
68 | ||||
|
69 | class WinHPCJob(Component): | |||
|
70 | ||||
|
71 | job_id = Str('') | |||
|
72 | job_name = Str('MyJob', config=True) | |||
|
73 | min_cores = Int(1, config=True) | |||
|
74 | max_cores = Int(1, config=True) | |||
|
75 | min_sockets = Int(1, config=True) | |||
|
76 | max_sockets = Int(1, config=True) | |||
|
77 | min_nodes = Int(1, config=True) | |||
|
78 | max_nodes = Int(1, config=True) | |||
|
79 | unit_type = Str("Core", config=True) | |||
|
80 | auto_calculate_min = Bool(True, config=True) | |||
|
81 | auto_calculate_max = Bool(True, config=True) | |||
|
82 | run_until_canceled = Bool(False, config=True) | |||
|
83 | is_exclusive = Bool(False, config=True) | |||
|
84 | username = Str(os.environ.get('USERNAME', ''), config=True) | |||
|
85 | owner = Str('', config=True) | |||
|
86 | job_type = Str('Batch', config=True) | |||
|
87 | priority = Enum(('Lowest','BelowNormal','Normal','AboveNormal','Highest'), | |||
|
88 | default_value='Highest', config=True) | |||
|
89 | requested_nodes = Str('', config=True) | |||
|
90 | project = Str('IPython', config=True) | |||
|
91 | xmlns = Str('http://schemas.microsoft.com/HPCS2008/scheduler/') | |||
|
92 | version = Str("2.000") | |||
|
93 | tasks = List([]) | |||
|
94 | ||||
|
95 | def _username_changed(self, name, old, new): | |||
|
96 | self.owner = new | |||
|
97 | ||||
|
98 | def _write_attr(self, root, attr, key): | |||
|
99 | s = as_str(getattr(self, attr, '')) | |||
|
100 | if s: | |||
|
101 | root.set(key, s) | |||
|
102 | ||||
|
103 | def as_element(self): | |||
|
104 | # We have to add _A_ type things to get the right order than | |||
|
105 | # the MSFT XML parser expects. | |||
|
106 | root = ET.Element('Job') | |||
|
107 | self._write_attr(root, 'version', '_A_Version') | |||
|
108 | self._write_attr(root, 'job_name', '_B_Name') | |||
|
109 | self._write_attr(root, 'unit_type', '_C_UnitType') | |||
|
110 | self._write_attr(root, 'min_cores', '_D_MinCores') | |||
|
111 | self._write_attr(root, 'max_cores', '_E_MaxCores') | |||
|
112 | self._write_attr(root, 'min_sockets', '_F_MinSockets') | |||
|
113 | self._write_attr(root, 'max_sockets', '_G_MaxSockets') | |||
|
114 | self._write_attr(root, 'min_nodes', '_H_MinNodes') | |||
|
115 | self._write_attr(root, 'max_nodes', '_I_MaxNodes') | |||
|
116 | self._write_attr(root, 'run_until_canceled', '_J_RunUntilCanceled') | |||
|
117 | self._write_attr(root, 'is_exclusive', '_K_IsExclusive') | |||
|
118 | self._write_attr(root, 'username', '_L_UserName') | |||
|
119 | self._write_attr(root, 'job_type', '_M_JobType') | |||
|
120 | self._write_attr(root, 'priority', '_N_Priority') | |||
|
121 | self._write_attr(root, 'requested_nodes', '_O_RequestedNodes') | |||
|
122 | self._write_attr(root, 'auto_calculate_max', '_P_AutoCalculateMax') | |||
|
123 | self._write_attr(root, 'auto_calculate_min', '_Q_AutoCalculateMin') | |||
|
124 | self._write_attr(root, 'project', '_R_Project') | |||
|
125 | self._write_attr(root, 'owner', '_S_Owner') | |||
|
126 | self._write_attr(root, 'xmlns', '_T_xmlns') | |||
|
127 | dependencies = ET.SubElement(root, "Dependencies") | |||
|
128 | etasks = ET.SubElement(root, "Tasks") | |||
|
129 | for t in self.tasks: | |||
|
130 | etasks.append(t.as_element()) | |||
|
131 | return root | |||
|
132 | ||||
|
133 | def tostring(self): | |||
|
134 | """Return the string representation of the job description XML.""" | |||
|
135 | root = self.as_element() | |||
|
136 | indent(root) | |||
|
137 | txt = ET.tostring(root, encoding="utf-8") | |||
|
138 | # Now remove the tokens used to order the attributes. | |||
|
139 | txt = re.sub(r'_[A-Z]_','',txt) | |||
|
140 | txt = '<?xml version="1.0" encoding="utf-8"?>\n' + txt | |||
|
141 | return txt | |||
|
142 | ||||
|
143 | def write(self, filename): | |||
|
144 | """Write the XML job description to a file.""" | |||
|
145 | txt = self.tostring() | |||
|
146 | with open(filename, 'w') as f: | |||
|
147 | f.write(txt) | |||
|
148 | ||||
|
149 | def add_task(self, task): | |||
|
150 | """Add a task to the job. | |||
|
151 | ||||
|
152 | Parameters | |||
|
153 | ---------- | |||
|
154 | task : :class:`WinHPCTask` | |||
|
155 | The task object to add. | |||
|
156 | """ | |||
|
157 | self.tasks.append(task) | |||
|
158 | ||||
|
159 | ||||
|
160 | class WinHPCTask(Component): | |||
|
161 | ||||
|
162 | task_id = Str('') | |||
|
163 | task_name = Str('') | |||
|
164 | version = Str("2.000") | |||
|
165 | min_cores = Int(1, config=True) | |||
|
166 | max_cores = Int(1, config=True) | |||
|
167 | min_sockets = Int(1, config=True) | |||
|
168 | max_sockets = Int(1, config=True) | |||
|
169 | min_nodes = Int(1, config=True) | |||
|
170 | max_nodes = Int(1, config=True) | |||
|
171 | unit_type = Str("Core", config=True) | |||
|
172 | command_line = Str('', config=True) | |||
|
173 | work_directory = Str('', config=True) | |||
|
174 | is_rerunnaable = Bool(True, config=True) | |||
|
175 | std_out_file_path = Str('', config=True) | |||
|
176 | std_err_file_path = Str('', config=True) | |||
|
177 | is_parametric = Bool(False, config=True) | |||
|
178 | environment_variables = Instance(dict, args=()) | |||
|
179 | ||||
|
180 | def _write_attr(self, root, attr, key): | |||
|
181 | s = as_str(getattr(self, attr, '')) | |||
|
182 | if s: | |||
|
183 | root.set(key, s) | |||
|
184 | ||||
|
185 | def as_element(self): | |||
|
186 | root = ET.Element('Task') | |||
|
187 | self._write_attr(root, 'version', '_A_Version') | |||
|
188 | self._write_attr(root, 'task_name', '_B_Name') | |||
|
189 | self._write_attr(root, 'min_cores', '_C_MinCores') | |||
|
190 | self._write_attr(root, 'max_cores', '_D_MaxCores') | |||
|
191 | self._write_attr(root, 'min_sockets', '_E_MinSockets') | |||
|
192 | self._write_attr(root, 'max_sockets', '_F_MaxSockets') | |||
|
193 | self._write_attr(root, 'min_nodes', '_G_MinNodes') | |||
|
194 | self._write_attr(root, 'max_nodes', '_H_MaxNodes') | |||
|
195 | self._write_attr(root, 'command_line', '_I_CommandLine') | |||
|
196 | self._write_attr(root, 'work_directory', '_J_WorkDirectory') | |||
|
197 | self._write_attr(root, 'is_rerunnaable', '_K_IsRerunnable') | |||
|
198 | self._write_attr(root, 'std_out_file_path', '_L_StdOutFilePath') | |||
|
199 | self._write_attr(root, 'std_err_file_path', '_M_StdErrFilePath') | |||
|
200 | self._write_attr(root, 'is_parametric', '_N_IsParametric') | |||
|
201 | self._write_attr(root, 'unit_type', '_O_UnitType') | |||
|
202 | root.append(self.get_env_vars()) | |||
|
203 | return root | |||
|
204 | ||||
|
205 | def get_env_vars(self): | |||
|
206 | env_vars = ET.Element('EnvironmentVariables') | |||
|
207 | for k, v in self.environment_variables.items(): | |||
|
208 | variable = ET.SubElement(env_vars, "Variable") | |||
|
209 | name = ET.SubElement(variable, "Name") | |||
|
210 | name.text = k | |||
|
211 | value = ET.SubElement(variable, "Value") | |||
|
212 | value.text = v | |||
|
213 | return env_vars | |||
|
214 | ||||
|
215 | ||||
|
216 | # j = WinHPCJob(None) | |||
|
217 | # j.job_name = 'IPCluster' | |||
|
218 | # j.username = 'GNET\\bgranger' | |||
|
219 | # j.requested_nodes = 'GREEN' | |||
|
220 | # | |||
|
221 | # t = WinHPCTask(None) | |||
|
222 | # t.task_name = 'Controller' | |||
|
223 | # t.command_line = r"\\blue\domainusers$\bgranger\Python\Python25\Scripts\ipcontroller.exe --log-to-file -p default --log-level 10" | |||
|
224 | # t.work_directory = r"\\blue\domainusers$\bgranger\.ipython\cluster_default" | |||
|
225 | # t.std_out_file_path = 'controller-out.txt' | |||
|
226 | # t.std_err_file_path = 'controller-err.txt' | |||
|
227 | # t.environment_variables['PYTHONPATH'] = r"\\blue\domainusers$\bgranger\Python\Python25\Lib\site-packages" | |||
|
228 | # j.add_task(t) | |||
|
229 |
General Comments 0
You need to be logged in to leave comments.
Login now