1 # Copyright (c) 2005-2006 The Regents of The University of Michigan
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.
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.
27 # Authors: Nathan Binkert
32 def __init__(self
, name
, desc
, **kwargs
):
35 self
.__dict
__.update(kwargs
)
37 def update(self
, obj
):
38 if not isinstance(obj
, Data
):
39 raise AttributeError, "can only update from Data object"
41 for key
,val
in obj
.__dict
__.iteritems():
42 if key
.startswith('_') or key
in ('name', 'desc'):
45 if key
not in self
.__dict
__:
46 self
.__dict
__[key
] = val
49 if not isinstance(val
, dict):
50 if self
.__dict
__[key
] == val
:
53 raise AttributeError, \
54 "%s specified more than once old: %s new: %s" % \
55 (key
, self
.__dict
__[key
], val
)
57 d
= self
.__dict
__[key
]
58 for k
,v
in val
.iteritems():
60 raise AttributeError, \
61 "%s specified more than once in %s" % (k
, key
)
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
)
72 print 'name: %s' % self
.name
74 print 'desc: %s' % self
.desc
77 print 'system: %s' % self
.system
78 except AttributeError:
81 def printverbose(self
):
84 if isinstance(val
, dict):
86 val
= pprint
.pformat(val
)
87 print '%-20s = %s' % (key
, val
)
90 def __contains__(self
, attr
):
91 if attr
.startswith('_'):
93 return attr
in self
.__dict
__
95 def __getitem__(self
, key
):
96 if key
.startswith('_'):
97 raise KeyError, "Key '%s' not found" % attr
98 return self
.__dict
__[key
]
101 keys
= self
.__dict
__.keys()
104 if not key
.startswith('_'):
107 def optiondict(self
):
109 result
= m5
.util
.optiondict()
111 result
[key
] = self
[key
]
116 for key
,value
in self
.__dict
__.iteritems():
117 if not key
.startswith('_'):
120 return "<%s: %s>" % (type(self
).__name
__, d
)
126 def __init__(self
, options
):
127 super(Job
, self
).__init
__('', '')
129 config
= options
[0]._config
131 if opt
._config
!= config
:
132 raise AttributeError, \
133 "All options are not from the same Configuration"
135 self
._config
= config
136 self
._groups
= [ opt
._group
for opt
in options
]
137 self
._options
= options
139 self
.update(self
._config
)
140 for group
in self
._groups
:
143 self
._is
_checkpoint
= True
145 for option
in self
._options
:
147 if not option
._group
._checkpoint
:
148 self
._is
_checkpoint
= False
150 if option
._suboption
:
151 self
.update(option
._suboption
)
152 self
._is
_checkpoint
= False
155 for opt
in self
._options
:
157 names
.append(opt
.name
)
158 self
.name
= ':'.join(names
)
161 for opt
in self
._options
:
163 descs
.append(opt
.desc
)
164 self
.desc
= ', '.join(descs
)
166 self
._checkpoint
= None
167 if not self
._is
_checkpoint
:
170 cpt
= opt
._group
._checkpoint
173 if isinstance(cpt
, Option
):
174 opt
= cpt
.clone(suboptions
=False)
176 opt
= opt
.clone(suboptions
=False)
181 self
._checkpoint
= Job(opts
)
184 return Job(self
._options
)
187 super(Job
, self
).printinfo()
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()
195 class SubOption(Data
):
196 def __init__(self
, name
, desc
, **kwargs
):
197 super(SubOption
, self
).__init
__(name
, desc
, **kwargs
)
201 def __init__(self
, name
, desc
, **kwargs
):
202 super(Option
, self
).__init
__(name
, desc
, **kwargs
)
203 self
._suboptions
= []
204 self
._suboption
= None
207 def __getattribute__(self
, attr
):
209 name
= self
.__dict
__[attr
]
210 if self
._suboption
is not None:
211 name
= '%s:%s' % (name
, self
._suboption
.name
)
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
)
220 return super(Option
, self
).__getattribute
__(attr
)
222 def suboption(self
, name
, desc
, **kwargs
):
223 subo
= SubOption(name
, desc
, **kwargs
)
224 subo
._config
= self
._config
225 subo
._group
= self
._group
227 subo
._number
= len(self
._suboptions
)
228 self
._suboptions
.append(subo
)
231 def clone(self
, suboptions
=True):
232 option
= Option(self
.__dict
__['name'], self
.__dict
__['desc'])
234 option
._group
= self
._group
235 option
._config
= self
._config
236 option
._number
= self
._number
238 option
._suboptions
.extend(self
._suboptions
)
239 option
._suboption
= self
._suboption
243 if not self
._suboptions
:
247 for subo
in self
._suboptions
:
248 option
= self
.clone()
249 option
._suboption
= subo
250 subopts
.append(option
)
255 super(Option
, self
).printinfo()
256 print 'config: %s' % self
._config
.name
257 super(Option
, self
).printverbose()
260 def __init__(self
, name
, desc
, **kwargs
):
261 super(Group
, self
).__init
__(name
, desc
, **kwargs
)
264 self
._checkpoint
= False
266 def option(self
, name
, desc
, **kwargs
):
267 opt
= Option(name
, desc
, **kwargs
)
268 opt
._config
= self
._config
270 opt
._number
= len(self
._options
)
271 self
._options
.append(opt
)
279 for opt
in self
._options
:
280 for subo
in opt
.subopts():
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()
290 class Configuration(Data
):
291 def __init__(self
, name
, desc
, **kwargs
):
292 super(Configuration
, self
).__init
__(name
, desc
, **kwargs
)
294 self
._posfilters
= []
295 self
._negfilters
= []
297 def group(self
, name
, desc
, **kwargs
):
298 grp
= Group(name
, desc
, **kwargs
)
300 grp
._number
= len(self
._groups
)
301 self
._groups
.append(grp
)
307 def checkchildren(self
, kids
):
309 if kid
._config
!= self
:
310 raise AttributeError, "child from the wrong configuration"
312 def sortgroups(self
, groups
):
313 groups
= [ (grp
._number
, grp
) for grp
in groups
]
315 return [ grp
[1] for grp
in groups
]
317 def options(self
, groups
=None, checkpoint
=False):
319 groups
= self
._groups
320 self
.checkchildren(groups
)
321 groups
= self
.sortgroups(groups
)
323 groups
= [ grp
for grp
in groups
if grp
._checkpoint
]
324 optgroups
= [ g
.options() for g
in groups
]
326 optgroups
= [ g
.subopts() for g
in groups
]
331 for options
in m5
.util
.crossproduct(optgroups
):
333 cpt
= opt
._group
._checkpoint
334 if not isinstance(cpt
, bool) and cpt
!= opt
:
343 def addfilter(self
, filt
, pos
=True):
345 filt
= re
.compile(filt
)
347 self
._posfilters
.append(filt
)
349 self
._negfilters
.append(filt
)
351 def jobfilter(self
, job
):
352 for filt
in self
._negfilters
:
353 if filt
.match(job
.name
):
356 if not self
._posfilters
:
359 for filt
in self
._posfilters
:
360 if filt
.match(job
.name
):
365 def checkpoints(self
, groups
=None):
366 for options
in self
.options(groups
, True):
368 if self
.jobfilter(job
):
371 def jobs(self
, groups
=None):
372 for options
in self
.options(groups
, False):
374 if self
.jobfilter(job
):
377 def alljobs(self
, groups
=None):
378 for options
in self
.options(groups
, True):
380 for options
in self
.options(groups
, False):
383 def find(self
, jobname
):
384 for job
in self
.alljobs():
385 if job
.name
== jobname
:
388 raise AttributeError, "job '%s' not found" % jobname
390 def job(self
, options
):
391 self
.checkchildren(options
)
392 options
= [ (opt
._group
._number
, opt
) for opt
in options
]
394 options
= [ opt
[1] for opt
in options
]
399 super(Configuration
, self
).printinfo()
400 print 'groups: %s' % [ g
.name
for g
in self
._groups
]
401 super(Configuration
, self
).printverbose()
403 def JobFile(jobfile
):
404 from os
.path
import expanduser
, isfile
, join
as joinpath
405 filename
= expanduser(jobfile
)
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
)
415 raise AttributeError, \
416 "Could not find file '%s'" % jobfile
419 execfile(filename
, data
)
420 if 'conf' not in data
:
421 raise ImportError, 'cannot import name conf from %s' % jobfile
425 usage
= 'Usage: %s [-b] [-c] [-v]' % sys
.argv
[0]
427 usage
+= ' <jobfile>'
431 opts
, args
= getopt
.getopt(sys
.argv
[1:], '-bcv')
432 except getopt
.GetoptError
:
449 raise AttributeError, usage
450 conf
= JobFile(args
[0])
453 raise AttributeError, usage
456 jobs
= conf
.alljobs()
458 jobs
= conf
.checkpoints()
468 cpt
= job
._checkpoint
.name
471 if __name__
== '__main__':