diff options
author | Kevin Lim <ktlim@umich.edu> | 2005-03-22 15:34:08 -0500 |
---|---|---|
committer | Kevin Lim <ktlim@umich.edu> | 2005-03-22 15:34:08 -0500 |
commit | 2ec918362ee1235cf0d36fb7aac3e3f4ce2d4ddc (patch) | |
tree | 33a71bd50ed74ce2127de696c69ee88c9b9c5d1c /python/m5/config.py | |
parent | cfa4221e19459d2179ba5601cf71a7a53753a3b1 (diff) | |
parent | 48e0b9ed4dd6f69cc41003d20bf755eeaf6fb633 (diff) | |
download | gem5-2ec918362ee1235cf0d36fb7aac3e3f4ce2d4ddc.tar.xz |
Merge ktlim@zizzer.eecs.umich.edu:/bk/m5
into zamp.eecs.umich.edu:/z/ktlim2/m5
--HG--
extra : convert_revision : 0c750652cc2b59946160994d53c921cb021ceef4
Diffstat (limited to 'python/m5/config.py')
-rw-r--r-- | python/m5/config.py | 208 |
1 files changed, 72 insertions, 136 deletions
diff --git a/python/m5/config.py b/python/m5/config.py index 64ec99490..f696adc79 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -29,6 +29,7 @@ import os, re, sys, types, inspect from m5 import panic from convert import * +from multidict import multidict noDot = False try: @@ -151,8 +152,11 @@ class Proxy(object): self._multiplier = None def __getattr__(self, attr): + # python uses __bases__ internally for inheritance if attr == '__bases__': return super(Proxy, self).__getattr__(self, attr) + if (self._path == None): + panic("Can't add attributes to 'any' proxy") self._path.append((attr,None)) return self @@ -198,6 +202,7 @@ class Proxy(object): raise AttributeError, \ 'Parent of %s type %s not found at path %s' \ % (base.name, ptype, self._path) + result, done = obj.find(ptype, self._path) obj = obj.parent @@ -322,17 +327,20 @@ class MetaConfigNode(type): super(MetaConfigNode, cls).__init__(name, bases, dict) # initialize required attributes - cls._params = {} - cls._values = {} + cls._params = multidict() + cls._values = multidict() cls._param_types = {} cls._bases = [c for c in cls.__mro__ if isConfigNode(c)] cls._anon_subclass_counter = 0 - # If your parent has a value in it that's a config node, clone - # it. Do this now so if we update any of the values' - # attributes we are updating the clone and not the original. - for base in cls._bases: - for key,val in base._values.iteritems(): + # We don't support multiple inheritence. If you want to, you + # must fix multidict to deal with it properly. + cnbase = [ base for base in bases if isConfigNode(base) ] + if len(cnbase) == 1: + # If your parent has a value in it that's a config node, clone + # it. Do this now so if we update any of the values' + # attributes we are updating the clone and not the original. + for key,val in cnbase[0]._values.iteritems(): # don't clone if (1) we're about to overwrite it with # a local setting or (2) we've already cloned a copy @@ -342,10 +350,17 @@ class MetaConfigNode(type): if isConfigNode(val): cls._values[key] = val() - elif isSimObjSequence(val): + elif isSimObjSequence(val) and len(val): cls._values[key] = [ v() for v in val ] - elif isNullPointer(val): - cls._values[key] = val + + cls._params.parent = cnbase[0]._params + cls._values.parent = cnbase[0]._values + + elif len(cnbase) > 1: + panic("""\ +The config hierarchy only supports single inheritence of SimObject +classes. You're trying to derive from: +%s""" % str(cnbase)) # process param types from _init_dict, as these may be needed # by param descriptions also in _init_dict @@ -359,9 +374,7 @@ class MetaConfigNode(type): for key,val in cls._init_dict.items(): # param descriptions if isinstance(val, _Param): - cls._params[key] = val - # try to resolve local param types in local param_types scope - val.maybe_resolve_type(cls._param_types) + cls._new_param(key, val) # init-time-only keywords elif cls.init_keywords.has_key(key): @@ -384,99 +397,6 @@ class MetaConfigNode(type): else: setattr(cls, key, val) - - def _isvalue(cls, name): - for c in cls._bases: - if c._params.has_key(name): - return True - - for c in cls._bases: - if c._values.has_key(name): - return True - - return False - - # generator that iterates across all parameters for this class and - # all classes it inherits from - def _getparams(cls): - params = {} - for c in cls._bases: - for p,v in c._params.iteritems(): - if not params.has_key(p): - params[p] = v - return params - - # Lookup a parameter description by name in the given class. - def _getparam(cls, name, default = AttributeError): - for c in cls._bases: - if c._params.has_key(name): - return c._params[name] - if isSubClass(default, Exception): - raise default, \ - "object '%s' has no attribute '%s'" % (cls.__name__, name) - else: - return default - - def _hasvalue(cls, name): - for c in cls._bases: - if c._values.has_key(name): - return True - - return False - - def _getvalues(cls): - values = {} - for i,c in enumerate(cls._bases): - for p,v in c._values.iteritems(): - if not values.has_key(p): - values[p] = v - for p,v in c._params.iteritems(): - if not values.has_key(p) and hasattr(v, 'default'): - try: - v.valid(v.default) - except TypeError: - panic("Invalid default %s for param %s in node %s" - % (v.default,p,cls.__name__)) - v = v.default - cls._setvalue(p, v) - values[p] = v - - return values - - def _getvalue(cls, name, default = AttributeError): - value = None - for c in cls._bases: - if c._values.has_key(name): - value = c._values[name] - break - if value is not None: - return value - - param = cls._getparam(name, None) - if param is not None and hasattr(param, 'default'): - param.valid(param.default) - value = param.default - cls._setvalue(name, value) - return value - - if isSubClass(default, Exception): - raise default, 'value for %s not found' % name - else: - return default - - def _setvalue(cls, name, value): - cls._values[name] = value - - def __getattr__(cls, attr): - if cls._isvalue(attr): - return Value(cls, attr) - - if attr == '_cpp_param_decl' and hasattr(cls, 'type'): - return cls.type + '*' - - raise AttributeError, \ - "object '%s' has no attribute '%s'" % (cls.__name__, attr) - def _set_keyword(cls, keyword, val, kwtype): if not isinstance(val, kwtype): raise TypeError, 'keyword %s has bad type %s (expecting %s)' % \ @@ -485,6 +405,13 @@ class MetaConfigNode(type): val = classmethod(val) type.__setattr__(cls, keyword, val) + def _new_param(cls, name, value): + cls._params[name] = value + if hasattr(value, 'default'): + cls._values[name] = value.default + # try to resolve local param types in local param_types scope + value.maybe_resolve_type(cls._param_types) + # Set attribute (called on foo.attr = value when foo is an # instance of class cls). def __setattr__(cls, attr, value): @@ -498,23 +425,33 @@ class MetaConfigNode(type): return # must be SimObject param - param = cls._getparam(attr, None) + param = cls._params.get(attr, None) if param: # It's ok: set attribute by delegating to 'object' class. # Note the use of param.make_value() to verify/canonicalize # the assigned value try: param.valid(value) - except: - panic("Error setting param %s.%s to %s\n" % \ - (cls.__name__, attr, value)) - cls._setvalue(attr, value) + except Exception, e: + panic("Exception: %s\nError setting param %s.%s to %s\n" % \ + (e, cls.__name__, attr, value)) + cls._values[attr] = value elif isConfigNode(value) or isSimObjSequence(value): - cls._setvalue(attr, value) + cls._values[attr] = value else: raise AttributeError, \ "Class %s has no parameter %s" % (cls.__name__, attr) + def __getattr__(cls, attr): + if cls._params.has_key(attr) or cls._values.has_key(attr): + return Value(cls, attr) + + if attr == '_cpp_param_decl' and hasattr(cls, 'type'): + return cls.type + '*' + + raise AttributeError, \ + "object '%s' has no attribute '%s'" % (cls.__name__, attr) + def add_child(cls, instance, name, child): if isNullPointer(child) or instance.top_child_names.has_key(name): return @@ -544,7 +481,7 @@ class MetaConfigNode(type): if hasattr(cls, 'check'): cls.check() - for key,value in cls._getvalues().iteritems(): + for key,value in cls._values.iteritems(): if isConfigNode(value): cls.add_child(instance, key, value) if isinstance(value, (list, tuple)): @@ -552,11 +489,10 @@ class MetaConfigNode(type): if len(vals): cls.add_child(instance, key, vals) - for pname,param in cls._getparams().iteritems(): - try: - value = cls._getvalue(pname) - except: - panic('Error getting %s' % pname) + for pname,param in cls._params.iteritems(): + value = cls._values.get(pname, None) + if value is None: + panic('Error getting %s from %s' % (pname, name)) try: if isConfigNode(value): @@ -573,10 +509,9 @@ class MetaConfigNode(type): p = NodeParam(pname, param, value) instance.params.append(p) instance.param_names[pname] = p - except: - print 'Exception while evaluating %s.%s' % \ - (instance.path, pname) - raise + except Exception, e: + raise e.__class__, 'Exception while evaluating %s.%s\n%s' % \ + (instance.path, pname, e) return instance @@ -615,7 +550,7 @@ class ConfigNode(object): cls._anon_subclass_counter += 1 return cls.__metaclass__(name, (cls, ), kwargs) -class ParamContext(ConfigNode): +class ParamContext(ConfigNode,ParamType): pass class MetaSimObject(MetaConfigNode): @@ -757,9 +692,9 @@ class Node(object): param.value = [ self.unproxy(pv, ptype) for pv in pval ] else: param.value = self.unproxy(pval, ptype) - except: - print 'Error while fixing up %s:%s' % (self.path, param.name) - raise + except Exception, e: + raise e.__class__, 'Error while fixing up %s:%s\n%s' % \ + (self.path, param.name, e) for child in self.children: assert(child != self) @@ -778,9 +713,8 @@ class Node(object): # before cpu0). Changing ordering can also influence timing # in the current memory system, as caches get added to a bus # in different orders which affects their priority in the - # case of simulataneous requests. We should uncomment the - # following line once we take care of that issue. - # self.children.sort(lambda x,y: cmp(x.name, y.name)) + # case of simulataneous requests. + self.children.sort(lambda x,y: cmp(x.name, y.name)) children = [ c.name for c in self.children if not c.paramcontext] print 'children =', ' '.join(children) @@ -792,9 +726,9 @@ class Node(object): value = param.convert(param.value) string = param.string(value) - except: - print 'exception in %s:%s' % (self.path, param.name) - raise + except Exception, e: + raise e.__class__, 'exception in %s:%s\n%s' % \ + (self.path, param.name, e) print '%s = %s' % (param.name, string) @@ -827,8 +761,9 @@ class Node(object): value = param.convert(param.value) string = param.string(value) - except: - print 'exception in %s:%s' % (self.name, param.name) + except Exception, e: + raise e.__class__, 'exception in %s:%s\n%s' % \ + (self.name, param.name, e) raise if isConfigNode(param.ptype) and string != "Null": simobjs.append(string) @@ -837,7 +772,8 @@ class Node(object): for so in simobjs: label += "|<%s> %s" % (so, so) - dot.add_edge(pydot.Edge("%s:%s" % (self.path, so), so, tailport="w")) + dot.add_edge(pydot.Edge("%s:%s" % (self.path, so), so, + tailport="w")) label += '}' dot.add_node(pydot.Node(self.path,shape="Mrecord",label=label)) @@ -877,7 +813,7 @@ class Value(object): super(Value, self).__setattr__('obj', obj) def _getattr(self): - return self.obj._getvalue(self.attr) + return self.obj._values.get(self.attr) def __setattr__(self, attr, value): setattr(self._getattr(), attr, value) |