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