diff options
author | Nathan Binkert <binkertn@umich.edu> | 2005-03-23 13:25:48 -0500 |
---|---|---|
committer | Nathan Binkert <binkertn@umich.edu> | 2005-03-23 13:25:48 -0500 |
commit | 153130e5586e18025f7a0f05242ead3a7e2be881 (patch) | |
tree | e9a92385d5b06db63b202a27699f26996ab47974 /python | |
parent | 48e0b9ed4dd6f69cc41003d20bf755eeaf6fb633 (diff) | |
download | gem5-153130e5586e18025f7a0f05242ead3a7e2be881.tar.xz |
First step in fixing up parameter handling. Clean up the
way ranges work, more fully support metric prefixes for all
integer types, and convert memory sized parameters to the
MemorySize type.
python/m5/config.py:
- no more _Param and _ParamProxy stuff. Use the names
ParamBase and ParamFactory to hopefully make it clearer
what we intend.
- Get rid of RangeSize and the old Range class and more fully flesh
out the Range class to deal with types of parameters and different
kinds of ranges.
- Call toInteger on the CheckedInt types so we can use metric prefixes
in strings for all integers.
- Get rid of the K, M, and G constants. Use the proper type or call
one of the functions in the convert package.
python/m5/convert.py:
Simple way to deal with both floating point and integer strings.
python/m5/objects/BaseCache.mpy:
python/m5/objects/Ethernet.mpy:
This is a MemorySize typed parameter
--HG--
extra : convert_revision : 92b4ea662d723abdd6c0a49065b79c25400fac9b
Diffstat (limited to 'python')
-rw-r--r-- | python/m5/config.py | 187 | ||||
-rw-r--r-- | python/m5/convert.py | 2 | ||||
-rw-r--r-- | python/m5/objects/BaseCache.mpy | 2 | ||||
-rw-r--r-- | python/m5/objects/Ethernet.mpy | 4 |
4 files changed, 123 insertions, 72 deletions
diff --git a/python/m5/config.py b/python/m5/config.py index f696adc79..3fc90f6bc 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -65,7 +65,7 @@ class Singleton(type): # object, either using keyword assignment in the constructor or in # separate assignment statements. For example: # -# cache = BaseCache('my_cache', root, size=64*K) +# cache = BaseCache('my_cache', root, size='64KB') # cache.hit_latency = 3 # cache.assoc = 8 # @@ -373,7 +373,7 @@ classes. You're trying to derive from: # now process remaining _init_dict items for key,val in cls._init_dict.items(): # param descriptions - if isinstance(val, _Param): + if isinstance(val, ParamBase): cls._new_param(key, val) # init-time-only keywords @@ -433,8 +433,8 @@ classes. You're trying to derive from: try: param.valid(value) except Exception, e: - panic("Exception: %s\nError setting param %s.%s to %s\n" % \ - (e, cls.__name__, attr, value)) + raise e.__class__, "%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._values[attr] = value @@ -837,7 +837,7 @@ class Value(object): return len(self._getattr()) # Regular parameter. -class _Param(object): +class ParamBase(object): def __init__(self, ptype, *args, **kwargs): if isinstance(ptype, types.StringType): self.ptype_string = ptype @@ -909,13 +909,13 @@ class _Param(object): def cpp_decl(self, name): return '%s %s;' % (self.ptype._cpp_param_decl, name) -class _ParamProxy(object): +class ParamFactory(object): def __init__(self, type): self.ptype = type # E.g., Param.Int(5, "number of widgets") def __call__(self, *args, **kwargs): - return _Param(self.ptype, *args, **kwargs) + return ParamBase(self.ptype, *args, **kwargs) # Strange magic to theoretically allow dotted names as Param classes, # e.g., Param.Foo.Bar(...) to have a param of type Foo.Bar @@ -929,17 +929,17 @@ class _ParamProxy(object): if attr != 'ptype': raise AttributeError, \ 'Attribute %s not available in %s' % (attr, self.__class__) - super(_ParamProxy, self).__setattr__(attr, value) + super(ParamFactory, self).__setattr__(attr, value) -Param = _ParamProxy(None) +Param = ParamFactory(None) # Vector-valued parameter description. Just like Param, except that # the value is a vector (list) of the specified type instead of a # single value. -class _VectorParam(_Param): +class VectorParamBase(ParamBase): def __init__(self, type, *args, **kwargs): - _Param.__init__(self, type, *args, **kwargs) + ParamBase.__init__(self, type, *args, **kwargs) def valid(self, value): if value == None: @@ -974,12 +974,12 @@ class _VectorParam(_Param): def cpp_decl(self, name): return 'std::vector<%s> %s;' % (self.ptype._cpp_param_decl, name) -class _VectorParamProxy(_ParamProxy): +class VectorParamFactory(ParamFactory): # E.g., VectorParam.Int(5, "number of widgets") def __call__(self, *args, **kwargs): - return _VectorParam(self.ptype, *args, **kwargs) + return VectorParamBase(self.ptype, *args, **kwargs) -VectorParam = _VectorParamProxy(None) +VectorParam = VectorParamFactory(None) ##################################################################### # @@ -995,6 +995,80 @@ VectorParam = _VectorParamProxy(None) # ##################################################################### +class MetaRange(type): + def __init__(cls, name, bases, dict): + super(MetaRange, cls).__init__(name, bases, dict) + if name == 'Range': + return + cls._cpp_param_decl = 'Range<%s>' % cls.type._cpp_param_decl + + def _convert(cls, value): + if not isinstance(value, Range): + raise TypeError, 'value %s is not a Pair' % value + value = cls(value) + value.first = cls.type._convert(value.first) + value.second = cls.type._convert(value.second) + return value + + def _string(cls, value): + first = int(value.first) + second = int(value.second) + if value.extend: + second += first + if not value.inclusive: + second -= 1 + return '%s:%s' % (cls.type._string(first), cls.type._string(second)) + +class Range(ParamType): + __metaclass__ = MetaRange + def __init__(self, *args, **kwargs): + if len(args) == 0: + self.first = kwargs.pop('start') + + if 'end' in kwargs: + self.second = kwargs.pop('end') + self.inclusive = True + self.extend = False + elif 'size' in kwargs: + self.second = kwargs.pop('size') + self.inclusive = False + self.extend = True + else: + raise TypeError, "Either end or size must be specified" + + elif len(args) == 1: + if kwargs: + self.first = args[0] + if 'end' in kwargs: + self.second = kwargs.pop('end') + self.inclusive = True + self.extend = False + elif 'size' in kwargs: + self.second = kwargs.pop('size') + self.inclusive = False + self.extend = True + else: + raise TypeError, "Either end or size must be specified" + elif isinstance(args[0], Range): + self.first = args[0].first + self.second = args[0].second + self.inclusive = args[0].inclusive + self.extend = args[0].extend + else: + self.first = 0 + self.second = args[0] + self.inclusive = False + self.extend = True + + elif len(args) == 2: + self.first, self.second = args + self.inclusive = True + self.extend = False + else: + raise TypeError, "Too many arguments specified" + + if kwargs: + raise TypeError, "too many keywords: %s" % kwargs.keys() # Metaclass for bounds-checked integer parameters. See CheckedInt. class CheckedIntType(type): @@ -1028,8 +1102,10 @@ class CheckedIntType(type): if not isinstance(value, (int, long, float, str)): raise TypeError, 'Integer param of invalid type %s' % type(value) - if isinstance(value, (str, float)): - value = long(float(value)) + if isinstance(value, float): + value = long(value) + elif isinstance(value, str): + value = toInteger(value) if not cls.min <= value <= cls.max: raise TypeError, 'Integer param out of bounds %d < %d < %d' % \ @@ -1044,7 +1120,7 @@ class CheckedIntType(type): # class is subclassed to generate parameter classes with specific # bounds. Initialization of the min and max bounds is done in the # metaclass CheckedIntType.__init__. -class CheckedInt(ParamType): +class CheckedInt(long,ParamType): __metaclass__ = CheckedIntType class Int(CheckedInt): cppname = 'int'; size = 32; unsigned = False @@ -1060,68 +1136,47 @@ class Int64(CheckedInt): cppname = 'int64_t'; size = 64; unsigned = False class UInt64(CheckedInt): cppname = 'uint64_t'; size = 64; unsigned = True class Counter(CheckedInt): cppname = 'Counter'; size = 64; unsigned = True -class Addr(CheckedInt): cppname = 'Addr'; size = 64; unsigned = True class Tick(CheckedInt): cppname = 'Tick'; size = 64; unsigned = True class Percent(CheckedInt): cppname = 'int'; min = 0; max = 100 -class Pair(object): - def __init__(self, first, second): - self.first = first - self.second = second - -class MetaRange(type): - def __init__(cls, name, bases, dict): - super(MetaRange, cls).__init__(name, bases, dict) - if name == 'Range': - return - cls._cpp_param_decl = 'Range<%s>' % cls.type._cpp_param_decl +class MemorySize(CheckedInt): + cppname = 'uint64_t' + size = 64 + unsigned = True + def __new__(cls, value): + return super(MemorySize, cls).__new__(cls, toMemorySize(value)) def _convert(cls, value): - if not isinstance(value, Pair): - raise TypeError, 'value %s is not a Pair' % value - return Pair(cls.type._convert(value.first), - cls.type._convert(value.second)) + return cls(value) + _convert = classmethod(_convert) def _string(cls, value): - return '%s:%s' % (cls.type._string(value.first), - cls.type._string(value.second)) - -class Range(ParamType): - __metaclass__ = MetaRange + return '%d' % value + _string = classmethod(_string) -def RangeSize(start, size): - return Pair(start, start + size - 1) +class Addr(MemorySize): + pass -class AddrRange(Range): type = Addr +class AddrRange(Range): + type = Addr # Boolean parameter type. class Bool(ParamType): _cpp_param_decl = 'bool' - def _convert(value): - t = type(value) - if t == bool: - return value + #def __new__(cls, value): + # return super(MemorySize, cls).__new__(cls, toBool(value)) - if t == int or t == long: - return bool(value) - - if t == str: - v = value.lower() - if v == "true" or v == "t" or v == "yes" or v == "y": - return True - elif v == "false" or v == "f" or v == "no" or v == "n": - return False - - raise TypeError, 'Bool parameter (%s) of invalid type %s' % (v, t) - _convert = staticmethod(_convert) + def _convert(cls, value): + return toBool(value) + _convert = classmethod(_convert) - def _string(value): + def _string(cls, value): if value: return "true" else: return "false" - _string = staticmethod(_string) + _string = classmethod(_string) # String-valued parameter. class String(ParamType): @@ -1291,13 +1346,9 @@ class Enum(ParamType): # # Some memory range specifications use this as a default upper bound. -MAX_ADDR = Addr.max +MaxAddr = Addr.max MaxTick = Tick.max - -# For power-of-two sizing, e.g. 64*K gives an integer value 65536. -K = 1024 -M = K*K -G = K*M +AllMemory = AddrRange(0, MaxAddr) ##################################################################### @@ -1337,6 +1388,6 @@ __all__ = ['ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam', 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64', 'Counter', 'Addr', 'Tick', 'Percent', - 'Pair', 'RangeSize', 'AddrRange', 'MAX_ADDR', 'NULL', 'K', 'M', - 'NextEthernetAddr', - 'instantiate'] + 'MemorySize', + 'Range', 'AddrRange', 'MaxAddr', 'MaxTick', 'AllMemory', 'NULL', + 'NextEthernetAddr', 'instantiate'] diff --git a/python/m5/convert.py b/python/m5/convert.py index 2ebe93889..2f69645b9 100644 --- a/python/m5/convert.py +++ b/python/m5/convert.py @@ -60,7 +60,7 @@ def toInteger(value): elif value.endswith('f'): result = int(value[:-1]) * femto else: - result = int(value) + result = int(float(value)) return result diff --git a/python/m5/objects/BaseCache.mpy b/python/m5/objects/BaseCache.mpy index 98a422e30..b9986917f 100644 --- a/python/m5/objects/BaseCache.mpy +++ b/python/m5/objects/BaseCache.mpy @@ -23,7 +23,7 @@ simobj BaseCache(BaseMem): "always service demand misses first") protocol = Param.CoherenceProtocol(NULL, "coherence protocol to use") repl = Param.Repl(NULL, "replacement policy") - size = Param.Int("capacity in bytes") + size = Param.MemorySize("capacity in bytes") split = Param.Bool(False, "whether or not this cache is split") split_size = Param.Int(0, "How many ways of the cache belong to CPU/LRU partition") diff --git a/python/m5/objects/Ethernet.mpy b/python/m5/objects/Ethernet.mpy index cd251f36d..3acd8d04d 100644 --- a/python/m5/objects/Ethernet.mpy +++ b/python/m5/objects/Ethernet.mpy @@ -68,8 +68,8 @@ simobj NSGigE(PciDevice): rx_delay = Param.Tick(1000, "Receive Delay") tx_delay = Param.Tick(1000, "Transmit Delay") - rx_fifo_size = Param.Int(131072, "max size in bytes of rxFifo") - tx_fifo_size = Param.Int(131072, "max size in bytes of txFifo") + rx_fifo_size = Param.MemorySize('128kB', "max size in bytes of rxFifo") + tx_fifo_size = Param.MemorySize('128kB', "max size in bytes of txFifo") intr_delay = Param.Tick(0, "Interrupt Delay in microseconds") payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload") |