##// END OF EJS Templates
passthrough kwargs in WinHPCTask `__init__` methods
MinRK -
Show More
@@ -1,319 +1,319 b''
1 1 # encoding: utf-8
2 2 """
3 3 Job and task components for writing .xml files that the Windows HPC Server
4 4 2008 can use to start jobs.
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * MinRK
10 10
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Copyright (C) 2008-2011 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Imports
22 22 #-----------------------------------------------------------------------------
23 23
24 24 import os
25 25 import re
26 26 import uuid
27 27
28 28 from xml.etree import ElementTree as ET
29 29
30 30 from IPython.config.configurable import Configurable
31 31 from IPython.utils.traitlets import (
32 32 Unicode, Integer, List, Instance,
33 33 Enum, Bool
34 34 )
35 35
36 36 #-----------------------------------------------------------------------------
37 37 # Job and Task classes
38 38 #-----------------------------------------------------------------------------
39 39
40 40
41 41 def as_str(value):
42 42 if isinstance(value, str):
43 43 return value
44 44 elif isinstance(value, bool):
45 45 if value:
46 46 return 'true'
47 47 else:
48 48 return 'false'
49 49 elif isinstance(value, (int, float)):
50 50 return repr(value)
51 51 else:
52 52 return value
53 53
54 54
55 55 def indent(elem, level=0):
56 56 i = "\n" + level*" "
57 57 if len(elem):
58 58 if not elem.text or not elem.text.strip():
59 59 elem.text = i + " "
60 60 if not elem.tail or not elem.tail.strip():
61 61 elem.tail = i
62 62 for elem in elem:
63 63 indent(elem, level+1)
64 64 if not elem.tail or not elem.tail.strip():
65 65 elem.tail = i
66 66 else:
67 67 if level and (not elem.tail or not elem.tail.strip()):
68 68 elem.tail = i
69 69
70 70
71 71 def find_username():
72 72 domain = os.environ.get('USERDOMAIN')
73 73 username = os.environ.get('USERNAME','')
74 74 if domain is None:
75 75 return username
76 76 else:
77 77 return '%s\\%s' % (domain, username)
78 78
79 79
80 80 class WinHPCJob(Configurable):
81 81
82 82 job_id = Unicode('')
83 83 job_name = Unicode('MyJob', config=True)
84 84 min_cores = Integer(1, config=True)
85 85 max_cores = Integer(1, config=True)
86 86 min_sockets = Integer(1, config=True)
87 87 max_sockets = Integer(1, config=True)
88 88 min_nodes = Integer(1, config=True)
89 89 max_nodes = Integer(1, config=True)
90 90 unit_type = Unicode("Core", config=True)
91 91 auto_calculate_min = Bool(True, config=True)
92 92 auto_calculate_max = Bool(True, config=True)
93 93 run_until_canceled = Bool(False, config=True)
94 94 is_exclusive = Bool(False, config=True)
95 95 username = Unicode(find_username(), config=True)
96 96 job_type = Unicode('Batch', config=True)
97 97 priority = Enum(('Lowest','BelowNormal','Normal','AboveNormal','Highest'),
98 98 default_value='Highest', config=True)
99 99 requested_nodes = Unicode('', config=True)
100 100 project = Unicode('IPython', config=True)
101 101 xmlns = Unicode('http://schemas.microsoft.com/HPCS2008/scheduler/')
102 102 version = Unicode("2.000")
103 103 tasks = List([])
104 104
105 105 @property
106 106 def owner(self):
107 107 return self.username
108 108
109 109 def _write_attr(self, root, attr, key):
110 110 s = as_str(getattr(self, attr, ''))
111 111 if s:
112 112 root.set(key, s)
113 113
114 114 def as_element(self):
115 115 # We have to add _A_ type things to get the right order than
116 116 # the MSFT XML parser expects.
117 117 root = ET.Element('Job')
118 118 self._write_attr(root, 'version', '_A_Version')
119 119 self._write_attr(root, 'job_name', '_B_Name')
120 120 self._write_attr(root, 'unit_type', '_C_UnitType')
121 121 self._write_attr(root, 'min_cores', '_D_MinCores')
122 122 self._write_attr(root, 'max_cores', '_E_MaxCores')
123 123 self._write_attr(root, 'min_sockets', '_F_MinSockets')
124 124 self._write_attr(root, 'max_sockets', '_G_MaxSockets')
125 125 self._write_attr(root, 'min_nodes', '_H_MinNodes')
126 126 self._write_attr(root, 'max_nodes', '_I_MaxNodes')
127 127 self._write_attr(root, 'run_until_canceled', '_J_RunUntilCanceled')
128 128 self._write_attr(root, 'is_exclusive', '_K_IsExclusive')
129 129 self._write_attr(root, 'username', '_L_UserName')
130 130 self._write_attr(root, 'job_type', '_M_JobType')
131 131 self._write_attr(root, 'priority', '_N_Priority')
132 132 self._write_attr(root, 'requested_nodes', '_O_RequestedNodes')
133 133 self._write_attr(root, 'auto_calculate_max', '_P_AutoCalculateMax')
134 134 self._write_attr(root, 'auto_calculate_min', '_Q_AutoCalculateMin')
135 135 self._write_attr(root, 'project', '_R_Project')
136 136 self._write_attr(root, 'owner', '_S_Owner')
137 137 self._write_attr(root, 'xmlns', '_T_xmlns')
138 138 dependencies = ET.SubElement(root, "Dependencies")
139 139 etasks = ET.SubElement(root, "Tasks")
140 140 for t in self.tasks:
141 141 etasks.append(t.as_element())
142 142 return root
143 143
144 144 def tostring(self):
145 145 """Return the string representation of the job description XML."""
146 146 root = self.as_element()
147 147 indent(root)
148 148 txt = ET.tostring(root, encoding="utf-8").decode('utf-8')
149 149 # Now remove the tokens used to order the attributes.
150 150 txt = re.sub(r'_[A-Z]_','',txt)
151 151 txt = '<?xml version="1.0" encoding="utf-8"?>\n' + txt
152 152 return txt
153 153
154 154 def write(self, filename):
155 155 """Write the XML job description to a file."""
156 156 txt = self.tostring()
157 157 with open(filename, 'w') as f:
158 158 f.write(txt)
159 159
160 160 def add_task(self, task):
161 161 """Add a task to the job.
162 162
163 163 Parameters
164 164 ----------
165 165 task : :class:`WinHPCTask`
166 166 The task object to add.
167 167 """
168 168 self.tasks.append(task)
169 169
170 170
171 171 class WinHPCTask(Configurable):
172 172
173 173 task_id = Unicode('')
174 174 task_name = Unicode('')
175 175 version = Unicode("2.000")
176 176 min_cores = Integer(1, config=True)
177 177 max_cores = Integer(1, config=True)
178 178 min_sockets = Integer(1, config=True)
179 179 max_sockets = Integer(1, config=True)
180 180 min_nodes = Integer(1, config=True)
181 181 max_nodes = Integer(1, config=True)
182 182 unit_type = Unicode("Core", config=True)
183 183 command_line = Unicode('', config=True)
184 184 work_directory = Unicode('', config=True)
185 185 is_rerunnaable = Bool(True, config=True)
186 186 std_out_file_path = Unicode('', config=True)
187 187 std_err_file_path = Unicode('', config=True)
188 188 is_parametric = Bool(False, config=True)
189 189 environment_variables = Instance(dict, args=(), config=True)
190 190
191 191 def _write_attr(self, root, attr, key):
192 192 s = as_str(getattr(self, attr, ''))
193 193 if s:
194 194 root.set(key, s)
195 195
196 196 def as_element(self):
197 197 root = ET.Element('Task')
198 198 self._write_attr(root, 'version', '_A_Version')
199 199 self._write_attr(root, 'task_name', '_B_Name')
200 200 self._write_attr(root, 'min_cores', '_C_MinCores')
201 201 self._write_attr(root, 'max_cores', '_D_MaxCores')
202 202 self._write_attr(root, 'min_sockets', '_E_MinSockets')
203 203 self._write_attr(root, 'max_sockets', '_F_MaxSockets')
204 204 self._write_attr(root, 'min_nodes', '_G_MinNodes')
205 205 self._write_attr(root, 'max_nodes', '_H_MaxNodes')
206 206 self._write_attr(root, 'command_line', '_I_CommandLine')
207 207 self._write_attr(root, 'work_directory', '_J_WorkDirectory')
208 208 self._write_attr(root, 'is_rerunnaable', '_K_IsRerunnable')
209 209 self._write_attr(root, 'std_out_file_path', '_L_StdOutFilePath')
210 210 self._write_attr(root, 'std_err_file_path', '_M_StdErrFilePath')
211 211 self._write_attr(root, 'is_parametric', '_N_IsParametric')
212 212 self._write_attr(root, 'unit_type', '_O_UnitType')
213 213 root.append(self.get_env_vars())
214 214 return root
215 215
216 216 def get_env_vars(self):
217 217 env_vars = ET.Element('EnvironmentVariables')
218 218 for k, v in self.environment_variables.iteritems():
219 219 variable = ET.SubElement(env_vars, "Variable")
220 220 name = ET.SubElement(variable, "Name")
221 221 name.text = k
222 222 value = ET.SubElement(variable, "Value")
223 223 value.text = v
224 224 return env_vars
225 225
226 226
227 227
228 228 # By declaring these, we can configure the controller and engine separately!
229 229
230 230 class IPControllerJob(WinHPCJob):
231 231 job_name = Unicode('IPController', config=False)
232 232 is_exclusive = Bool(False, config=True)
233 233 username = Unicode(find_username(), config=True)
234 234 priority = Enum(('Lowest','BelowNormal','Normal','AboveNormal','Highest'),
235 235 default_value='Highest', config=True)
236 236 requested_nodes = Unicode('', config=True)
237 237 project = Unicode('IPython', config=True)
238 238
239 239
240 240 class IPEngineSetJob(WinHPCJob):
241 241 job_name = Unicode('IPEngineSet', config=False)
242 242 is_exclusive = Bool(False, config=True)
243 243 username = Unicode(find_username(), config=True)
244 244 priority = Enum(('Lowest','BelowNormal','Normal','AboveNormal','Highest'),
245 245 default_value='Highest', config=True)
246 246 requested_nodes = Unicode('', config=True)
247 247 project = Unicode('IPython', config=True)
248 248
249 249
250 250 class IPControllerTask(WinHPCTask):
251 251
252 252 task_name = Unicode('IPController', config=True)
253 253 controller_cmd = List(['ipcontroller.exe'], config=True)
254 254 controller_args = List(['--log-to-file', '--log-level=40'], config=True)
255 255 # I don't want these to be configurable
256 256 std_out_file_path = Unicode('', config=False)
257 257 std_err_file_path = Unicode('', config=False)
258 258 min_cores = Integer(1, config=False)
259 259 max_cores = Integer(1, config=False)
260 260 min_sockets = Integer(1, config=False)
261 261 max_sockets = Integer(1, config=False)
262 262 min_nodes = Integer(1, config=False)
263 263 max_nodes = Integer(1, config=False)
264 264 unit_type = Unicode("Core", config=False)
265 265 work_directory = Unicode('', config=False)
266 266
267 def __init__(self, config=None):
268 super(IPControllerTask, self).__init__(config=config)
267 def __init__(self, **kwargs):
268 super(IPControllerTask, self).__init__(**kwargs)
269 269 the_uuid = uuid.uuid1()
270 270 self.std_out_file_path = os.path.join('log','ipcontroller-%s.out' % the_uuid)
271 271 self.std_err_file_path = os.path.join('log','ipcontroller-%s.err' % the_uuid)
272 272
273 273 @property
274 274 def command_line(self):
275 275 return ' '.join(self.controller_cmd + self.controller_args)
276 276
277 277
278 278 class IPEngineTask(WinHPCTask):
279 279
280 280 task_name = Unicode('IPEngine', config=True)
281 281 engine_cmd = List(['ipengine.exe'], config=True)
282 282 engine_args = List(['--log-to-file', '--log-level=40'], config=True)
283 283 # I don't want these to be configurable
284 284 std_out_file_path = Unicode('', config=False)
285 285 std_err_file_path = Unicode('', config=False)
286 286 min_cores = Integer(1, config=False)
287 287 max_cores = Integer(1, config=False)
288 288 min_sockets = Integer(1, config=False)
289 289 max_sockets = Integer(1, config=False)
290 290 min_nodes = Integer(1, config=False)
291 291 max_nodes = Integer(1, config=False)
292 292 unit_type = Unicode("Core", config=False)
293 293 work_directory = Unicode('', config=False)
294 294
295 def __init__(self, config=None):
296 super(IPEngineTask,self).__init__(config=config)
295 def __init__(self, **kwargs):
296 super(IPEngineTask,self).__init__(**kwargs)
297 297 the_uuid = uuid.uuid1()
298 298 self.std_out_file_path = os.path.join('log','ipengine-%s.out' % the_uuid)
299 299 self.std_err_file_path = os.path.join('log','ipengine-%s.err' % the_uuid)
300 300
301 301 @property
302 302 def command_line(self):
303 303 return ' '.join(self.engine_cmd + self.engine_args)
304 304
305 305
306 306 # j = WinHPCJob(None)
307 307 # j.job_name = 'IPCluster'
308 308 # j.username = 'GNET\\bgranger'
309 309 # j.requested_nodes = 'GREEN'
310 310 #
311 311 # t = WinHPCTask(None)
312 312 # t.task_name = 'Controller'
313 313 # t.command_line = r"\\blue\domainusers$\bgranger\Python\Python25\Scripts\ipcontroller.exe --log-to-file -p default --log-level 10"
314 314 # t.work_directory = r"\\blue\domainusers$\bgranger\.ipython\cluster_default"
315 315 # t.std_out_file_path = 'controller-out.txt'
316 316 # t.std_err_file_path = 'controller-err.txt'
317 317 # t.environment_variables['PYTHONPATH'] = r"\\blue\domainusers$\bgranger\Python\Python25\Lib\site-packages"
318 318 # j.add_task(t)
319 319
General Comments 0
You need to be logged in to leave comments. Login now