jobfile.py revision 13663
12141SN/A# Copyright (c) 2005-2006 The Regents of The University of Michigan 21376SN/A# All rights reserved. 31376SN/A# 41376SN/A# Redistribution and use in source and binary forms, with or without 51376SN/A# modification, are permitted provided that the following conditions are 61376SN/A# met: redistributions of source code must retain the above copyright 71376SN/A# notice, this list of conditions and the following disclaimer; 81376SN/A# redistributions in binary form must reproduce the above copyright 91376SN/A# notice, this list of conditions and the following disclaimer in the 101376SN/A# documentation and/or other materials provided with the distribution; 111376SN/A# neither the name of the copyright holders nor the names of its 121376SN/A# contributors may be used to endorse or promote products derived from 131376SN/A# this software without specific prior written permission. 141376SN/A# 151376SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 161376SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 171376SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 181376SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 191376SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 201376SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 211376SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 221376SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 231376SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 241376SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 251376SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 261376SN/A# 271376SN/A# Authors: Nathan Binkert 281376SN/A 2912563Sgabeblack@google.comfrom __future__ import print_function 3012563Sgabeblack@google.com 311428SN/Aimport sys 321428SN/A 331881SN/Aclass Data(object): 341881SN/A def __init__(self, name, desc, **kwargs): 351881SN/A self.name = name 361881SN/A self.desc = desc 375467Snate@binkert.org self.__dict__.update(kwargs) 381881SN/A 391881SN/A def update(self, obj): 401881SN/A if not isinstance(obj, Data): 4113663Sandreas.sandberg@arm.com raise AttributeError("can only update from Data object") 421881SN/A 435618Snate@binkert.org for key,val in obj.__dict__.iteritems(): 445618Snate@binkert.org if key.startswith('_') or key in ('name', 'desc'): 455618Snate@binkert.org continue 465618Snate@binkert.org 475618Snate@binkert.org if key not in self.__dict__: 485618Snate@binkert.org self.__dict__[key] = val 495618Snate@binkert.org continue 505618Snate@binkert.org 515618Snate@binkert.org if not isinstance(val, dict): 525618Snate@binkert.org if self.__dict__[key] == val: 535618Snate@binkert.org continue 545618Snate@binkert.org 5513663Sandreas.sandberg@arm.com raise AttributeError( 5613663Sandreas.sandberg@arm.com "%s specified more than once old: %s new: %s" % \ 5713663Sandreas.sandberg@arm.com (key, self.__dict__[key], val)) 585618Snate@binkert.org 595618Snate@binkert.org d = self.__dict__[key] 605618Snate@binkert.org for k,v in val.iteritems(): 615618Snate@binkert.org if k in d: 6213663Sandreas.sandberg@arm.com raise AttributeError( 6313663Sandreas.sandberg@arm.com "%s specified more than once in %s" % (k, key)) 645618Snate@binkert.org d[k] = v 655618Snate@binkert.org 665467Snate@binkert.org if hasattr(self, 'system') and hasattr(obj, 'system'): 675467Snate@binkert.org if self.system != obj.system: 6813663Sandreas.sandberg@arm.com raise AttributeError( 6913663Sandreas.sandberg@arm.com "conflicting values for system: '%s'/'%s'" % \ 7013663Sandreas.sandberg@arm.com (self.system, obj.system)) 711881SN/A 721881SN/A def printinfo(self): 731881SN/A if self.name: 7412563Sgabeblack@google.com print('name: %s' % self.name) 751881SN/A if self.desc: 7612563Sgabeblack@google.com print('desc: %s' % self.desc) 775467Snate@binkert.org try: 785467Snate@binkert.org if self.system: 7912563Sgabeblack@google.com print('system: %s' % self.system) 805467Snate@binkert.org except AttributeError: 815467Snate@binkert.org pass 821881SN/A 831881SN/A def printverbose(self): 845467Snate@binkert.org for key in self: 855467Snate@binkert.org val = self[key] 865467Snate@binkert.org if isinstance(val, dict): 875467Snate@binkert.org import pprint 885467Snate@binkert.org val = pprint.pformat(val) 8912563Sgabeblack@google.com print('%-20s = %s' % (key, val)) 9012563Sgabeblack@google.com print() 915467Snate@binkert.org 925467Snate@binkert.org def __contains__(self, attr): 935467Snate@binkert.org if attr.startswith('_'): 945467Snate@binkert.org return False 955467Snate@binkert.org return attr in self.__dict__ 965467Snate@binkert.org 975467Snate@binkert.org def __getitem__(self, key): 985467Snate@binkert.org if key.startswith('_'): 9913663Sandreas.sandberg@arm.com raise KeyError("Key '%s' not found" % attr) 1005467Snate@binkert.org return self.__dict__[key] 1015467Snate@binkert.org 1025467Snate@binkert.org def __iter__(self): 1035467Snate@binkert.org keys = self.__dict__.keys() 1041881SN/A keys.sort() 1051881SN/A for key in keys: 1065467Snate@binkert.org if not key.startswith('_'): 1075467Snate@binkert.org yield key 1085467Snate@binkert.org 1095467Snate@binkert.org def optiondict(self): 1106654Snate@binkert.org import m5.util 1116654Snate@binkert.org result = m5.util.optiondict() 1125467Snate@binkert.org for key in self: 1135467Snate@binkert.org result[key] = self[key] 1145467Snate@binkert.org return result 1151881SN/A 1165618Snate@binkert.org def __repr__(self): 1175618Snate@binkert.org d = {} 1185618Snate@binkert.org for key,value in self.__dict__.iteritems(): 1195618Snate@binkert.org if not key.startswith('_'): 1205618Snate@binkert.org d[key] = value 1215618Snate@binkert.org 1225618Snate@binkert.org return "<%s: %s>" % (type(self).__name__, d) 1235618Snate@binkert.org 1241881SN/A def __str__(self): 1251881SN/A return self.name 1261881SN/A 1271881SN/Aclass Job(Data): 1281881SN/A def __init__(self, options): 1291881SN/A super(Job, self).__init__('', '') 1301881SN/A 1315467Snate@binkert.org config = options[0]._config 1321881SN/A for opt in options: 1335467Snate@binkert.org if opt._config != config: 13413663Sandreas.sandberg@arm.com raise AttributeError( 13513663Sandreas.sandberg@arm.com "All options are not from the same Configuration") 1361881SN/A 1375467Snate@binkert.org self._config = config 1385467Snate@binkert.org self._groups = [ opt._group for opt in options ] 1395467Snate@binkert.org self._options = options 1401881SN/A 1415467Snate@binkert.org self.update(self._config) 1425467Snate@binkert.org for group in self._groups: 1431881SN/A self.update(group) 1441881SN/A 1455467Snate@binkert.org self._is_checkpoint = True 1465467Snate@binkert.org 1475467Snate@binkert.org for option in self._options: 1481881SN/A self.update(option) 1495467Snate@binkert.org if not option._group._checkpoint: 1505467Snate@binkert.org self._is_checkpoint = False 1515467Snate@binkert.org 1521881SN/A if option._suboption: 1531881SN/A self.update(option._suboption) 1545467Snate@binkert.org self._is_checkpoint = False 1555467Snate@binkert.org 1565467Snate@binkert.org names = [ ] 1575467Snate@binkert.org for opt in self._options: 1585467Snate@binkert.org if opt.name: 1595467Snate@binkert.org names.append(opt.name) 1605467Snate@binkert.org self.name = ':'.join(names) 1615467Snate@binkert.org 1625467Snate@binkert.org descs = [ ] 1635467Snate@binkert.org for opt in self._options: 1645467Snate@binkert.org if opt.desc: 1655467Snate@binkert.org descs.append(opt.desc) 1665467Snate@binkert.org self.desc = ', '.join(descs) 1675467Snate@binkert.org 1685467Snate@binkert.org self._checkpoint = None 1695467Snate@binkert.org if not self._is_checkpoint: 1705467Snate@binkert.org opts = [] 1715467Snate@binkert.org for opt in options: 1725467Snate@binkert.org cpt = opt._group._checkpoint 1735467Snate@binkert.org if not cpt: 1745467Snate@binkert.org continue 1755467Snate@binkert.org if isinstance(cpt, Option): 1765467Snate@binkert.org opt = cpt.clone(suboptions=False) 1775467Snate@binkert.org else: 1785467Snate@binkert.org opt = opt.clone(suboptions=False) 1795467Snate@binkert.org 1805467Snate@binkert.org opts.append(opt) 1815467Snate@binkert.org 1825467Snate@binkert.org if opts: 1835467Snate@binkert.org self._checkpoint = Job(opts) 1845467Snate@binkert.org 1855467Snate@binkert.org def clone(self): 1865467Snate@binkert.org return Job(self._options) 1871881SN/A 1881881SN/A def printinfo(self): 1891881SN/A super(Job, self).printinfo() 1905467Snate@binkert.org if self._checkpoint: 19112563Sgabeblack@google.com print('checkpoint: %s' % self._checkpoint.name) 19212563Sgabeblack@google.com print('config: %s' % self._config.name) 19312563Sgabeblack@google.com print('groups: %s' % [ g.name for g in self._groups ]) 19412563Sgabeblack@google.com print('options: %s' % [ o.name for o in self._options ]) 1951881SN/A super(Job, self).printverbose() 1961881SN/A 1971881SN/Aclass SubOption(Data): 1981881SN/A def __init__(self, name, desc, **kwargs): 1991881SN/A super(SubOption, self).__init__(name, desc, **kwargs) 2005467Snate@binkert.org self._number = None 2011881SN/A 2021881SN/Aclass Option(Data): 2031881SN/A def __init__(self, name, desc, **kwargs): 2041881SN/A super(Option, self).__init__(name, desc, **kwargs) 2051881SN/A self._suboptions = [] 2061881SN/A self._suboption = None 2075467Snate@binkert.org self._number = None 2081881SN/A 2091881SN/A def __getattribute__(self, attr): 2101881SN/A if attr == 'name': 2111881SN/A name = self.__dict__[attr] 2121881SN/A if self._suboption is not None: 2131881SN/A name = '%s:%s' % (name, self._suboption.name) 2141881SN/A return name 2151881SN/A 2161881SN/A if attr == 'desc': 2172142SN/A desc = [ self.__dict__[attr] ] 2182142SN/A if self._suboption is not None and self._suboption.desc: 2192142SN/A desc.append(self._suboption.desc) 2202142SN/A return ', '.join(desc) 2212142SN/A 2221881SN/A return super(Option, self).__getattribute__(attr) 2231881SN/A 2241881SN/A def suboption(self, name, desc, **kwargs): 2251881SN/A subo = SubOption(name, desc, **kwargs) 2265467Snate@binkert.org subo._config = self._config 2275467Snate@binkert.org subo._group = self._group 2285467Snate@binkert.org subo._option = self 2295467Snate@binkert.org subo._number = len(self._suboptions) 2301881SN/A self._suboptions.append(subo) 2311881SN/A return subo 2321881SN/A 2331881SN/A def clone(self, suboptions=True): 2341881SN/A option = Option(self.__dict__['name'], self.__dict__['desc']) 2351881SN/A option.update(self) 2365467Snate@binkert.org option._group = self._group 2375467Snate@binkert.org option._config = self._config 2385467Snate@binkert.org option._number = self._number 2391881SN/A if suboptions: 2401881SN/A option._suboptions.extend(self._suboptions) 2411881SN/A option._suboption = self._suboption 2421881SN/A return option 2431881SN/A 2441881SN/A def subopts(self): 2451881SN/A if not self._suboptions: 2461881SN/A return [ self ] 2471881SN/A 2481881SN/A subopts = [] 2491881SN/A for subo in self._suboptions: 2501881SN/A option = self.clone() 2511881SN/A option._suboption = subo 2521881SN/A subopts.append(option) 2531881SN/A 2541881SN/A return subopts 2551881SN/A 2561881SN/A def printinfo(self): 2571881SN/A super(Option, self).printinfo() 25812563Sgabeblack@google.com print('config: %s' % self._config.name) 2591881SN/A super(Option, self).printverbose() 2601881SN/A 2611881SN/Aclass Group(Data): 2621881SN/A def __init__(self, name, desc, **kwargs): 2631881SN/A super(Group, self).__init__(name, desc, **kwargs) 2641881SN/A self._options = [] 2655467Snate@binkert.org self._number = None 2665467Snate@binkert.org self._checkpoint = False 2671881SN/A 2681881SN/A def option(self, name, desc, **kwargs): 2691881SN/A opt = Option(name, desc, **kwargs) 2705467Snate@binkert.org opt._config = self._config 2715467Snate@binkert.org opt._group = self 2725467Snate@binkert.org opt._number = len(self._options) 2731881SN/A self._options.append(opt) 2741881SN/A return opt 2751881SN/A 2761881SN/A def options(self): 2771881SN/A return self._options 2781881SN/A 2791881SN/A def subopts(self): 2801881SN/A subopts = [] 2811881SN/A for opt in self._options: 2821881SN/A for subo in opt.subopts(): 2831881SN/A subopts.append(subo) 2841881SN/A return subopts 2851881SN/A 2861881SN/A def printinfo(self): 2871881SN/A super(Group, self).printinfo() 28812563Sgabeblack@google.com print('config: %s' % self._config.name) 28912563Sgabeblack@google.com print('options: %s' % [ o.name for o in self._options ]) 2901881SN/A super(Group, self).printverbose() 2911881SN/A 2921881SN/Aclass Configuration(Data): 2931881SN/A def __init__(self, name, desc, **kwargs): 2941881SN/A super(Configuration, self).__init__(name, desc, **kwargs) 2951881SN/A self._groups = [] 2962141SN/A self._posfilters = [] 2972141SN/A self._negfilters = [] 2981881SN/A 2991881SN/A def group(self, name, desc, **kwargs): 3001881SN/A grp = Group(name, desc, **kwargs) 3015467Snate@binkert.org grp._config = self 3025467Snate@binkert.org grp._number = len(self._groups) 3031881SN/A self._groups.append(grp) 3041881SN/A return grp 3051881SN/A 3065467Snate@binkert.org def groups(self): 3075467Snate@binkert.org return self._groups 3081881SN/A 3091881SN/A def checkchildren(self, kids): 3101881SN/A for kid in kids: 3115467Snate@binkert.org if kid._config != self: 31213663Sandreas.sandberg@arm.com raise AttributeError("child from the wrong configuration") 3131881SN/A 3141881SN/A def sortgroups(self, groups): 3155467Snate@binkert.org groups = [ (grp._number, grp) for grp in groups ] 3161881SN/A groups.sort() 3171881SN/A return [ grp[1] for grp in groups ] 3181881SN/A 3195467Snate@binkert.org def options(self, groups=None, checkpoint=False): 3201881SN/A if groups is None: 3211881SN/A groups = self._groups 3221881SN/A self.checkchildren(groups) 3231881SN/A groups = self.sortgroups(groups) 3241881SN/A if checkpoint: 3255467Snate@binkert.org groups = [ grp for grp in groups if grp._checkpoint ] 3261881SN/A optgroups = [ g.options() for g in groups ] 3271881SN/A else: 3281881SN/A optgroups = [ g.subopts() for g in groups ] 3295467Snate@binkert.org if not optgroups: 3305467Snate@binkert.org return 3316654Snate@binkert.org 3326654Snate@binkert.org import m5.util 3336654Snate@binkert.org for options in m5.util.crossproduct(optgroups): 3341881SN/A for opt in options: 3355467Snate@binkert.org cpt = opt._group._checkpoint 3361881SN/A if not isinstance(cpt, bool) and cpt != opt: 3371881SN/A if checkpoint: 3381881SN/A break 3391881SN/A else: 3401881SN/A yield options 3411881SN/A else: 3421881SN/A if checkpoint: 3431881SN/A yield options 3441881SN/A 3452141SN/A def addfilter(self, filt, pos=True): 3462141SN/A import re 3472141SN/A filt = re.compile(filt) 3482141SN/A if pos: 3492141SN/A self._posfilters.append(filt) 3502141SN/A else: 3512141SN/A self._negfilters.append(filt) 3522141SN/A 3532141SN/A def jobfilter(self, job): 3542141SN/A for filt in self._negfilters: 3552141SN/A if filt.match(job.name): 3562141SN/A return False 3572141SN/A 3582141SN/A if not self._posfilters: 3592141SN/A return True 3602141SN/A 3612141SN/A for filt in self._posfilters: 3622141SN/A if filt.match(job.name): 3632141SN/A return True 3642141SN/A 3652141SN/A return False 3662141SN/A 3675467Snate@binkert.org def checkpoints(self, groups=None): 3681881SN/A for options in self.options(groups, True): 3692141SN/A job = Job(options) 3702141SN/A if self.jobfilter(job): 3712141SN/A yield job 3721881SN/A 3735467Snate@binkert.org def jobs(self, groups=None): 3741881SN/A for options in self.options(groups, False): 3752141SN/A job = Job(options) 3762141SN/A if self.jobfilter(job): 3772141SN/A yield job 3781881SN/A 3795467Snate@binkert.org def alljobs(self, groups=None): 3801881SN/A for options in self.options(groups, True): 3811881SN/A yield Job(options) 3821881SN/A for options in self.options(groups, False): 3831881SN/A yield Job(options) 3841881SN/A 3851881SN/A def find(self, jobname): 3861881SN/A for job in self.alljobs(): 3871881SN/A if job.name == jobname: 3881881SN/A return job 3891881SN/A else: 39013663Sandreas.sandberg@arm.com raise AttributeError("job '%s' not found" % jobname) 3911881SN/A 3921881SN/A def job(self, options): 3931881SN/A self.checkchildren(options) 3945467Snate@binkert.org options = [ (opt._group._number, opt) for opt in options ] 3951881SN/A options.sort() 3961881SN/A options = [ opt[1] for opt in options ] 3971881SN/A job = Job(options) 3981881SN/A return job 3991881SN/A 4001881SN/A def printinfo(self): 4011881SN/A super(Configuration, self).printinfo() 40212563Sgabeblack@google.com print('groups: %s' % [ g.name for g in self._groups ]) 4031881SN/A super(Configuration, self).printverbose() 4041881SN/A 4051881SN/Adef JobFile(jobfile): 4061881SN/A from os.path import expanduser, isfile, join as joinpath 4071881SN/A filename = expanduser(jobfile) 4081881SN/A 4091881SN/A # Can't find filename in the current path, search sys.path 4101881SN/A if not isfile(filename): 4111881SN/A for path in sys.path: 4121881SN/A testname = joinpath(path, filename) 4131881SN/A if isfile(testname): 4141881SN/A filename = testname 4151881SN/A break 4161881SN/A else: 41713663Sandreas.sandberg@arm.com raise AttributeError("Could not find file '%s'" % jobfile) 4181881SN/A 4191881SN/A data = {} 4201881SN/A execfile(filename, data) 4211881SN/A if 'conf' not in data: 42213663Sandreas.sandberg@arm.com raise ImportError('cannot import name conf from %s' % jobfile) 4235618Snate@binkert.org return data['conf'] 4241881SN/A 4255467Snate@binkert.orgdef main(conf=None): 4265618Snate@binkert.org usage = 'Usage: %s [-b] [-c] [-v]' % sys.argv[0] 4275618Snate@binkert.org if conf is None: 4285618Snate@binkert.org usage += ' <jobfile>' 4291881SN/A 4301881SN/A try: 4311881SN/A import getopt 4321881SN/A opts, args = getopt.getopt(sys.argv[1:], '-bcv') 4331881SN/A except getopt.GetoptError: 4341881SN/A sys.exit(usage) 4351881SN/A 4361881SN/A both = False 4371881SN/A checkpoint = False 4381881SN/A verbose = False 4391881SN/A for opt,arg in opts: 4401881SN/A if opt == '-b': 4411881SN/A both = True 4421881SN/A checkpoint = True 4431881SN/A if opt == '-c': 4441881SN/A checkpoint = True 4451881SN/A if opt == '-v': 4461881SN/A verbose = True 4471881SN/A 4485467Snate@binkert.org if conf is None: 4495467Snate@binkert.org if len(args) != 1: 45013663Sandreas.sandberg@arm.com raise AttributeError(usage) 4515467Snate@binkert.org conf = JobFile(args[0]) 4525467Snate@binkert.org else: 4535467Snate@binkert.org if len(args) != 0: 45413663Sandreas.sandberg@arm.com raise AttributeError(usage) 4551881SN/A 4561881SN/A if both: 4575467Snate@binkert.org jobs = conf.alljobs() 4581881SN/A elif checkpoint: 4595467Snate@binkert.org jobs = conf.checkpoints() 4601881SN/A else: 4615467Snate@binkert.org jobs = conf.jobs() 4621881SN/A 4635467Snate@binkert.org for job in jobs: 4645467Snate@binkert.org if verbose: 4655467Snate@binkert.org job.printinfo() 4665467Snate@binkert.org else: 4671881SN/A cpt = '' 4685467Snate@binkert.org if job._checkpoint: 4695467Snate@binkert.org cpt = job._checkpoint.name 47012563Sgabeblack@google.com print(job.name, cpt) 4715467Snate@binkert.org 4725467Snate@binkert.orgif __name__ == '__main__': 4735467Snate@binkert.org main() 474