jobfile.py (5618:1abb23c038d5) jobfile.py (6654:4c84e771cca7)
1# Copyright (c) 2005-2006 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution;
11# neither the name of the copyright holders nor the names of its
12# contributors may be used to endorse or promote products derived from
13# this software without specific prior written permission.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: Nathan Binkert
28
29import sys
30
1# Copyright (c) 2005-2006 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution;
11# neither the name of the copyright holders nor the names of its
12# contributors may be used to endorse or promote products derived from
13# this software without specific prior written permission.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: Nathan Binkert
28
29import sys
30
31from attrdict import optiondict
32from misc import crossproduct
33
34class Data(object):
35 def __init__(self, name, desc, **kwargs):
36 self.name = name
37 self.desc = desc
38 self.__dict__.update(kwargs)
39
40 def update(self, obj):
41 if not isinstance(obj, Data):
42 raise AttributeError, "can only update from Data object"
43
44 for key,val in obj.__dict__.iteritems():
45 if key.startswith('_') or key in ('name', 'desc'):
46 continue
47
48 if key not in self.__dict__:
49 self.__dict__[key] = val
50 continue
51
52 if not isinstance(val, dict):
53 if self.__dict__[key] == val:
54 continue
55
56 raise AttributeError, \
57 "%s specified more than once old: %s new: %s" % \
58 (key, self.__dict__[key], val)
59
60 d = self.__dict__[key]
61 for k,v in val.iteritems():
62 if k in d:
63 raise AttributeError, \
64 "%s specified more than once in %s" % (k, key)
65 d[k] = v
66
67 if hasattr(self, 'system') and hasattr(obj, 'system'):
68 if self.system != obj.system:
69 raise AttributeError, \
70 "conflicting values for system: '%s'/'%s'" % \
71 (self.system, obj.system)
72
73 def printinfo(self):
74 if self.name:
75 print 'name: %s' % self.name
76 if self.desc:
77 print 'desc: %s' % self.desc
78 try:
79 if self.system:
80 print 'system: %s' % self.system
81 except AttributeError:
82 pass
83
84 def printverbose(self):
85 for key in self:
86 val = self[key]
87 if isinstance(val, dict):
88 import pprint
89 val = pprint.pformat(val)
90 print '%-20s = %s' % (key, val)
91 print
92
93 def __contains__(self, attr):
94 if attr.startswith('_'):
95 return False
96 return attr in self.__dict__
97
98 def __getitem__(self, key):
99 if key.startswith('_'):
100 raise KeyError, "Key '%s' not found" % attr
101 return self.__dict__[key]
102
103 def __iter__(self):
104 keys = self.__dict__.keys()
105 keys.sort()
106 for key in keys:
107 if not key.startswith('_'):
108 yield key
109
110 def optiondict(self):
31class Data(object):
32 def __init__(self, name, desc, **kwargs):
33 self.name = name
34 self.desc = desc
35 self.__dict__.update(kwargs)
36
37 def update(self, obj):
38 if not isinstance(obj, Data):
39 raise AttributeError, "can only update from Data object"
40
41 for key,val in obj.__dict__.iteritems():
42 if key.startswith('_') or key in ('name', 'desc'):
43 continue
44
45 if key not in self.__dict__:
46 self.__dict__[key] = val
47 continue
48
49 if not isinstance(val, dict):
50 if self.__dict__[key] == val:
51 continue
52
53 raise AttributeError, \
54 "%s specified more than once old: %s new: %s" % \
55 (key, self.__dict__[key], val)
56
57 d = self.__dict__[key]
58 for k,v in val.iteritems():
59 if k in d:
60 raise AttributeError, \
61 "%s specified more than once in %s" % (k, key)
62 d[k] = v
63
64 if hasattr(self, 'system') and hasattr(obj, 'system'):
65 if self.system != obj.system:
66 raise AttributeError, \
67 "conflicting values for system: '%s'/'%s'" % \
68 (self.system, obj.system)
69
70 def printinfo(self):
71 if self.name:
72 print 'name: %s' % self.name
73 if self.desc:
74 print 'desc: %s' % self.desc
75 try:
76 if self.system:
77 print 'system: %s' % self.system
78 except AttributeError:
79 pass
80
81 def printverbose(self):
82 for key in self:
83 val = self[key]
84 if isinstance(val, dict):
85 import pprint
86 val = pprint.pformat(val)
87 print '%-20s = %s' % (key, val)
88 print
89
90 def __contains__(self, attr):
91 if attr.startswith('_'):
92 return False
93 return attr in self.__dict__
94
95 def __getitem__(self, key):
96 if key.startswith('_'):
97 raise KeyError, "Key '%s' not found" % attr
98 return self.__dict__[key]
99
100 def __iter__(self):
101 keys = self.__dict__.keys()
102 keys.sort()
103 for key in keys:
104 if not key.startswith('_'):
105 yield key
106
107 def optiondict(self):
111 result = optiondict()
108 import m5.util
109 result = m5.util.optiondict()
112 for key in self:
113 result[key] = self[key]
114 return result
115
116 def __repr__(self):
117 d = {}
118 for key,value in self.__dict__.iteritems():
119 if not key.startswith('_'):
120 d[key] = value
121
122 return "<%s: %s>" % (type(self).__name__, d)
123
124 def __str__(self):
125 return self.name
126
127class Job(Data):
128 def __init__(self, options):
129 super(Job, self).__init__('', '')
130
131 config = options[0]._config
132 for opt in options:
133 if opt._config != config:
134 raise AttributeError, \
135 "All options are not from the same Configuration"
136
137 self._config = config
138 self._groups = [ opt._group for opt in options ]
139 self._options = options
140
141 self.update(self._config)
142 for group in self._groups:
143 self.update(group)
144
145 self._is_checkpoint = True
146
147 for option in self._options:
148 self.update(option)
149 if not option._group._checkpoint:
150 self._is_checkpoint = False
151
152 if option._suboption:
153 self.update(option._suboption)
154 self._is_checkpoint = False
155
156 names = [ ]
157 for opt in self._options:
158 if opt.name:
159 names.append(opt.name)
160 self.name = ':'.join(names)
161
162 descs = [ ]
163 for opt in self._options:
164 if opt.desc:
165 descs.append(opt.desc)
166 self.desc = ', '.join(descs)
167
168 self._checkpoint = None
169 if not self._is_checkpoint:
170 opts = []
171 for opt in options:
172 cpt = opt._group._checkpoint
173 if not cpt:
174 continue
175 if isinstance(cpt, Option):
176 opt = cpt.clone(suboptions=False)
177 else:
178 opt = opt.clone(suboptions=False)
179
180 opts.append(opt)
181
182 if opts:
183 self._checkpoint = Job(opts)
184
185 def clone(self):
186 return Job(self._options)
187
188 def printinfo(self):
189 super(Job, self).printinfo()
190 if self._checkpoint:
191 print 'checkpoint: %s' % self._checkpoint.name
192 print 'config: %s' % self._config.name
193 print 'groups: %s' % [ g.name for g in self._groups ]
194 print 'options: %s' % [ o.name for o in self._options ]
195 super(Job, self).printverbose()
196
197class SubOption(Data):
198 def __init__(self, name, desc, **kwargs):
199 super(SubOption, self).__init__(name, desc, **kwargs)
200 self._number = None
201
202class Option(Data):
203 def __init__(self, name, desc, **kwargs):
204 super(Option, self).__init__(name, desc, **kwargs)
205 self._suboptions = []
206 self._suboption = None
207 self._number = None
208
209 def __getattribute__(self, attr):
210 if attr == 'name':
211 name = self.__dict__[attr]
212 if self._suboption is not None:
213 name = '%s:%s' % (name, self._suboption.name)
214 return name
215
216 if attr == 'desc':
217 desc = [ self.__dict__[attr] ]
218 if self._suboption is not None and self._suboption.desc:
219 desc.append(self._suboption.desc)
220 return ', '.join(desc)
221
222 return super(Option, self).__getattribute__(attr)
223
224 def suboption(self, name, desc, **kwargs):
225 subo = SubOption(name, desc, **kwargs)
226 subo._config = self._config
227 subo._group = self._group
228 subo._option = self
229 subo._number = len(self._suboptions)
230 self._suboptions.append(subo)
231 return subo
232
233 def clone(self, suboptions=True):
234 option = Option(self.__dict__['name'], self.__dict__['desc'])
235 option.update(self)
236 option._group = self._group
237 option._config = self._config
238 option._number = self._number
239 if suboptions:
240 option._suboptions.extend(self._suboptions)
241 option._suboption = self._suboption
242 return option
243
244 def subopts(self):
245 if not self._suboptions:
246 return [ self ]
247
248 subopts = []
249 for subo in self._suboptions:
250 option = self.clone()
251 option._suboption = subo
252 subopts.append(option)
253
254 return subopts
255
256 def printinfo(self):
257 super(Option, self).printinfo()
258 print 'config: %s' % self._config.name
259 super(Option, self).printverbose()
260
261class Group(Data):
262 def __init__(self, name, desc, **kwargs):
263 super(Group, self).__init__(name, desc, **kwargs)
264 self._options = []
265 self._number = None
266 self._checkpoint = False
267
268 def option(self, name, desc, **kwargs):
269 opt = Option(name, desc, **kwargs)
270 opt._config = self._config
271 opt._group = self
272 opt._number = len(self._options)
273 self._options.append(opt)
274 return opt
275
276 def options(self):
277 return self._options
278
279 def subopts(self):
280 subopts = []
281 for opt in self._options:
282 for subo in opt.subopts():
283 subopts.append(subo)
284 return subopts
285
286 def printinfo(self):
287 super(Group, self).printinfo()
288 print 'config: %s' % self._config.name
289 print 'options: %s' % [ o.name for o in self._options ]
290 super(Group, self).printverbose()
291
292class Configuration(Data):
293 def __init__(self, name, desc, **kwargs):
294 super(Configuration, self).__init__(name, desc, **kwargs)
295 self._groups = []
296 self._posfilters = []
297 self._negfilters = []
298
299 def group(self, name, desc, **kwargs):
300 grp = Group(name, desc, **kwargs)
301 grp._config = self
302 grp._number = len(self._groups)
303 self._groups.append(grp)
304 return grp
305
306 def groups(self):
307 return self._groups
308
309 def checkchildren(self, kids):
310 for kid in kids:
311 if kid._config != self:
312 raise AttributeError, "child from the wrong configuration"
313
314 def sortgroups(self, groups):
315 groups = [ (grp._number, grp) for grp in groups ]
316 groups.sort()
317 return [ grp[1] for grp in groups ]
318
319 def options(self, groups=None, checkpoint=False):
320 if groups is None:
321 groups = self._groups
322 self.checkchildren(groups)
323 groups = self.sortgroups(groups)
324 if checkpoint:
325 groups = [ grp for grp in groups if grp._checkpoint ]
326 optgroups = [ g.options() for g in groups ]
327 else:
328 optgroups = [ g.subopts() for g in groups ]
329 if not optgroups:
330 return
110 for key in self:
111 result[key] = self[key]
112 return result
113
114 def __repr__(self):
115 d = {}
116 for key,value in self.__dict__.iteritems():
117 if not key.startswith('_'):
118 d[key] = value
119
120 return "<%s: %s>" % (type(self).__name__, d)
121
122 def __str__(self):
123 return self.name
124
125class Job(Data):
126 def __init__(self, options):
127 super(Job, self).__init__('', '')
128
129 config = options[0]._config
130 for opt in options:
131 if opt._config != config:
132 raise AttributeError, \
133 "All options are not from the same Configuration"
134
135 self._config = config
136 self._groups = [ opt._group for opt in options ]
137 self._options = options
138
139 self.update(self._config)
140 for group in self._groups:
141 self.update(group)
142
143 self._is_checkpoint = True
144
145 for option in self._options:
146 self.update(option)
147 if not option._group._checkpoint:
148 self._is_checkpoint = False
149
150 if option._suboption:
151 self.update(option._suboption)
152 self._is_checkpoint = False
153
154 names = [ ]
155 for opt in self._options:
156 if opt.name:
157 names.append(opt.name)
158 self.name = ':'.join(names)
159
160 descs = [ ]
161 for opt in self._options:
162 if opt.desc:
163 descs.append(opt.desc)
164 self.desc = ', '.join(descs)
165
166 self._checkpoint = None
167 if not self._is_checkpoint:
168 opts = []
169 for opt in options:
170 cpt = opt._group._checkpoint
171 if not cpt:
172 continue
173 if isinstance(cpt, Option):
174 opt = cpt.clone(suboptions=False)
175 else:
176 opt = opt.clone(suboptions=False)
177
178 opts.append(opt)
179
180 if opts:
181 self._checkpoint = Job(opts)
182
183 def clone(self):
184 return Job(self._options)
185
186 def printinfo(self):
187 super(Job, self).printinfo()
188 if self._checkpoint:
189 print 'checkpoint: %s' % self._checkpoint.name
190 print 'config: %s' % self._config.name
191 print 'groups: %s' % [ g.name for g in self._groups ]
192 print 'options: %s' % [ o.name for o in self._options ]
193 super(Job, self).printverbose()
194
195class SubOption(Data):
196 def __init__(self, name, desc, **kwargs):
197 super(SubOption, self).__init__(name, desc, **kwargs)
198 self._number = None
199
200class Option(Data):
201 def __init__(self, name, desc, **kwargs):
202 super(Option, self).__init__(name, desc, **kwargs)
203 self._suboptions = []
204 self._suboption = None
205 self._number = None
206
207 def __getattribute__(self, attr):
208 if attr == 'name':
209 name = self.__dict__[attr]
210 if self._suboption is not None:
211 name = '%s:%s' % (name, self._suboption.name)
212 return name
213
214 if attr == 'desc':
215 desc = [ self.__dict__[attr] ]
216 if self._suboption is not None and self._suboption.desc:
217 desc.append(self._suboption.desc)
218 return ', '.join(desc)
219
220 return super(Option, self).__getattribute__(attr)
221
222 def suboption(self, name, desc, **kwargs):
223 subo = SubOption(name, desc, **kwargs)
224 subo._config = self._config
225 subo._group = self._group
226 subo._option = self
227 subo._number = len(self._suboptions)
228 self._suboptions.append(subo)
229 return subo
230
231 def clone(self, suboptions=True):
232 option = Option(self.__dict__['name'], self.__dict__['desc'])
233 option.update(self)
234 option._group = self._group
235 option._config = self._config
236 option._number = self._number
237 if suboptions:
238 option._suboptions.extend(self._suboptions)
239 option._suboption = self._suboption
240 return option
241
242 def subopts(self):
243 if not self._suboptions:
244 return [ self ]
245
246 subopts = []
247 for subo in self._suboptions:
248 option = self.clone()
249 option._suboption = subo
250 subopts.append(option)
251
252 return subopts
253
254 def printinfo(self):
255 super(Option, self).printinfo()
256 print 'config: %s' % self._config.name
257 super(Option, self).printverbose()
258
259class Group(Data):
260 def __init__(self, name, desc, **kwargs):
261 super(Group, self).__init__(name, desc, **kwargs)
262 self._options = []
263 self._number = None
264 self._checkpoint = False
265
266 def option(self, name, desc, **kwargs):
267 opt = Option(name, desc, **kwargs)
268 opt._config = self._config
269 opt._group = self
270 opt._number = len(self._options)
271 self._options.append(opt)
272 return opt
273
274 def options(self):
275 return self._options
276
277 def subopts(self):
278 subopts = []
279 for opt in self._options:
280 for subo in opt.subopts():
281 subopts.append(subo)
282 return subopts
283
284 def printinfo(self):
285 super(Group, self).printinfo()
286 print 'config: %s' % self._config.name
287 print 'options: %s' % [ o.name for o in self._options ]
288 super(Group, self).printverbose()
289
290class Configuration(Data):
291 def __init__(self, name, desc, **kwargs):
292 super(Configuration, self).__init__(name, desc, **kwargs)
293 self._groups = []
294 self._posfilters = []
295 self._negfilters = []
296
297 def group(self, name, desc, **kwargs):
298 grp = Group(name, desc, **kwargs)
299 grp._config = self
300 grp._number = len(self._groups)
301 self._groups.append(grp)
302 return grp
303
304 def groups(self):
305 return self._groups
306
307 def checkchildren(self, kids):
308 for kid in kids:
309 if kid._config != self:
310 raise AttributeError, "child from the wrong configuration"
311
312 def sortgroups(self, groups):
313 groups = [ (grp._number, grp) for grp in groups ]
314 groups.sort()
315 return [ grp[1] for grp in groups ]
316
317 def options(self, groups=None, checkpoint=False):
318 if groups is None:
319 groups = self._groups
320 self.checkchildren(groups)
321 groups = self.sortgroups(groups)
322 if checkpoint:
323 groups = [ grp for grp in groups if grp._checkpoint ]
324 optgroups = [ g.options() for g in groups ]
325 else:
326 optgroups = [ g.subopts() for g in groups ]
327 if not optgroups:
328 return
331 for options in crossproduct(optgroups):
329
330 import m5.util
331 for options in m5.util.crossproduct(optgroups):
332 for opt in options:
333 cpt = opt._group._checkpoint
334 if not isinstance(cpt, bool) and cpt != opt:
335 if checkpoint:
336 break
337 else:
338 yield options
339 else:
340 if checkpoint:
341 yield options
342
343 def addfilter(self, filt, pos=True):
344 import re
345 filt = re.compile(filt)
346 if pos:
347 self._posfilters.append(filt)
348 else:
349 self._negfilters.append(filt)
350
351 def jobfilter(self, job):
352 for filt in self._negfilters:
353 if filt.match(job.name):
354 return False
355
356 if not self._posfilters:
357 return True
358
359 for filt in self._posfilters:
360 if filt.match(job.name):
361 return True
362
363 return False
364
365 def checkpoints(self, groups=None):
366 for options in self.options(groups, True):
367 job = Job(options)
368 if self.jobfilter(job):
369 yield job
370
371 def jobs(self, groups=None):
372 for options in self.options(groups, False):
373 job = Job(options)
374 if self.jobfilter(job):
375 yield job
376
377 def alljobs(self, groups=None):
378 for options in self.options(groups, True):
379 yield Job(options)
380 for options in self.options(groups, False):
381 yield Job(options)
382
383 def find(self, jobname):
384 for job in self.alljobs():
385 if job.name == jobname:
386 return job
387 else:
388 raise AttributeError, "job '%s' not found" % jobname
389
390 def job(self, options):
391 self.checkchildren(options)
392 options = [ (opt._group._number, opt) for opt in options ]
393 options.sort()
394 options = [ opt[1] for opt in options ]
395 job = Job(options)
396 return job
397
398 def printinfo(self):
399 super(Configuration, self).printinfo()
400 print 'groups: %s' % [ g.name for g in self._groups ]
401 super(Configuration, self).printverbose()
402
403def JobFile(jobfile):
404 from os.path import expanduser, isfile, join as joinpath
405 filename = expanduser(jobfile)
406
407 # Can't find filename in the current path, search sys.path
408 if not isfile(filename):
409 for path in sys.path:
410 testname = joinpath(path, filename)
411 if isfile(testname):
412 filename = testname
413 break
414 else:
415 raise AttributeError, \
416 "Could not find file '%s'" % jobfile
417
418 data = {}
419 execfile(filename, data)
420 if 'conf' not in data:
421 raise ImportError, 'cannot import name conf from %s' % jobfile
422 return data['conf']
423
424def main(conf=None):
425 usage = 'Usage: %s [-b] [-c] [-v]' % sys.argv[0]
426 if conf is None:
427 usage += ' <jobfile>'
428
429 try:
430 import getopt
431 opts, args = getopt.getopt(sys.argv[1:], '-bcv')
432 except getopt.GetoptError:
433 sys.exit(usage)
434
435 both = False
436 checkpoint = False
437 verbose = False
438 for opt,arg in opts:
439 if opt == '-b':
440 both = True
441 checkpoint = True
442 if opt == '-c':
443 checkpoint = True
444 if opt == '-v':
445 verbose = True
446
447 if conf is None:
448 if len(args) != 1:
449 raise AttributeError, usage
450 conf = JobFile(args[0])
451 else:
452 if len(args) != 0:
453 raise AttributeError, usage
454
455 if both:
456 jobs = conf.alljobs()
457 elif checkpoint:
458 jobs = conf.checkpoints()
459 else:
460 jobs = conf.jobs()
461
462 for job in jobs:
463 if verbose:
464 job.printinfo()
465 else:
466 cpt = ''
467 if job._checkpoint:
468 cpt = job._checkpoint.name
469 print job.name, cpt
470
471if __name__ == '__main__':
472 main()
332 for opt in options:
333 cpt = opt._group._checkpoint
334 if not isinstance(cpt, bool) and cpt != opt:
335 if checkpoint:
336 break
337 else:
338 yield options
339 else:
340 if checkpoint:
341 yield options
342
343 def addfilter(self, filt, pos=True):
344 import re
345 filt = re.compile(filt)
346 if pos:
347 self._posfilters.append(filt)
348 else:
349 self._negfilters.append(filt)
350
351 def jobfilter(self, job):
352 for filt in self._negfilters:
353 if filt.match(job.name):
354 return False
355
356 if not self._posfilters:
357 return True
358
359 for filt in self._posfilters:
360 if filt.match(job.name):
361 return True
362
363 return False
364
365 def checkpoints(self, groups=None):
366 for options in self.options(groups, True):
367 job = Job(options)
368 if self.jobfilter(job):
369 yield job
370
371 def jobs(self, groups=None):
372 for options in self.options(groups, False):
373 job = Job(options)
374 if self.jobfilter(job):
375 yield job
376
377 def alljobs(self, groups=None):
378 for options in self.options(groups, True):
379 yield Job(options)
380 for options in self.options(groups, False):
381 yield Job(options)
382
383 def find(self, jobname):
384 for job in self.alljobs():
385 if job.name == jobname:
386 return job
387 else:
388 raise AttributeError, "job '%s' not found" % jobname
389
390 def job(self, options):
391 self.checkchildren(options)
392 options = [ (opt._group._number, opt) for opt in options ]
393 options.sort()
394 options = [ opt[1] for opt in options ]
395 job = Job(options)
396 return job
397
398 def printinfo(self):
399 super(Configuration, self).printinfo()
400 print 'groups: %s' % [ g.name for g in self._groups ]
401 super(Configuration, self).printverbose()
402
403def JobFile(jobfile):
404 from os.path import expanduser, isfile, join as joinpath
405 filename = expanduser(jobfile)
406
407 # Can't find filename in the current path, search sys.path
408 if not isfile(filename):
409 for path in sys.path:
410 testname = joinpath(path, filename)
411 if isfile(testname):
412 filename = testname
413 break
414 else:
415 raise AttributeError, \
416 "Could not find file '%s'" % jobfile
417
418 data = {}
419 execfile(filename, data)
420 if 'conf' not in data:
421 raise ImportError, 'cannot import name conf from %s' % jobfile
422 return data['conf']
423
424def main(conf=None):
425 usage = 'Usage: %s [-b] [-c] [-v]' % sys.argv[0]
426 if conf is None:
427 usage += ' <jobfile>'
428
429 try:
430 import getopt
431 opts, args = getopt.getopt(sys.argv[1:], '-bcv')
432 except getopt.GetoptError:
433 sys.exit(usage)
434
435 both = False
436 checkpoint = False
437 verbose = False
438 for opt,arg in opts:
439 if opt == '-b':
440 both = True
441 checkpoint = True
442 if opt == '-c':
443 checkpoint = True
444 if opt == '-v':
445 verbose = True
446
447 if conf is None:
448 if len(args) != 1:
449 raise AttributeError, usage
450 conf = JobFile(args[0])
451 else:
452 if len(args) != 0:
453 raise AttributeError, usage
454
455 if both:
456 jobs = conf.alljobs()
457 elif checkpoint:
458 jobs = conf.checkpoints()
459 else:
460 jobs = conf.jobs()
461
462 for job in jobs:
463 if verbose:
464 job.printinfo()
465 else:
466 cpt = ''
467 if job._checkpoint:
468 cpt = job._checkpoint.name
469 print job.name, cpt
470
471if __name__ == '__main__':
472 main()