diff options
Diffstat (limited to 'src/python/m5/params.py')
-rw-r--r-- | src/python/m5/params.py | 195 |
1 files changed, 190 insertions, 5 deletions
diff --git a/src/python/m5/params.py b/src/python/m5/params.py index ad06e5309..88d38f87a 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -93,7 +93,7 @@ class MetaParamValue(type): # parameters. class ParamValue(object): __metaclass__ = MetaParamValue - + cmd_line_settable = False # Generate the code needed as a prerequisite for declaring a C++ # object of this type. Typically generates one or more #include @@ -119,6 +119,10 @@ class ParamValue(object): def unproxy(self, base): return self + # Produce a human readable version of the stored value + def pretty_print(self, value): + return str(value) + # Regular parameter description. class ParamDesc(object): def __init__(self, ptype_str, ptype, *args, **kwargs): @@ -162,6 +166,19 @@ class ParamDesc(object): raise AttributeError, "'%s' object has no attribute '%s'" % \ (type(self).__name__, attr) + def example_str(self): + if hasattr(self.ptype, "ex_str"): + return self.ptype.ex_str + else: + return self.ptype_str + + # Is the param available to be exposed on the command line + def isCmdLineSettable(self): + if hasattr(self.ptype, "cmd_line_settable"): + return self.ptype.cmd_line_settable + else: + return False + def convert(self, value): if isinstance(value, proxy.BaseProxy): value.set_param_desc(self) @@ -176,6 +193,13 @@ class ParamDesc(object): return value return self.ptype(value) + def pretty_print(self, value): + if isinstance(value, proxy.BaseProxy): + return str(value) + if isNullPointer(value): + return NULL + return self.ptype(value).pretty_print(value) + def cxx_predecls(self, code): code('#include <cstddef>') self.ptype.cxx_predecls(code) @@ -260,6 +284,26 @@ class SimObjectVector(VectorParamValue): value.set_parent(val.get_parent(), val._name) super(SimObjectVector, self).__setitem__(key, value) + # Enumerate the params of each member of the SimObject vector. Creates + # strings that will allow indexing into the vector by the python code and + # allow it to be specified on the command line. + def enumerateParams(self, flags_dict = {}, + cmd_line_str = "", + access_str = ""): + if hasattr(self, "_paramEnumed"): + print "Cycle detected enumerating params at %s?!" % (cmd_line_str) + else: + x = 0 + for vals in self: + # Each entry in the SimObjectVector should be an + # instance of a SimObject + flags_dict = vals.enumerateParams(flags_dict, + cmd_line_str + "%d." % x, + access_str + "[%d]." % x) + x = x + 1 + + return flags_dict + class VectorParamDesc(ParamDesc): # Convert assigned value to appropriate type. If the RHS is not a # list or tuple, it generates a single-element list. @@ -276,6 +320,39 @@ class VectorParamDesc(ParamDesc): else: return VectorParamValue(tmp_list) + # Produce a human readable example string that describes + # how to set this vector parameter in the absence of a default + # value. + def example_str(self): + s = super(VectorParamDesc, self).example_str() + help_str = "[" + s + "," + s + ", ...]" + return help_str + + # Produce a human readable representation of the value of this vector param. + def pretty_print(self, value): + if isinstance(value, (list, tuple)): + tmp_list = [ ParamDesc.pretty_print(self, v) for v in value ] + elif isinstance(value, str): + tmp_list = [ ParamDesc.pretty_print(self, v) for v in value.split(',') ] + else: + tmp_list = [ ParamDesc.pretty_print(self, value) ] + + return tmp_list + + # This is a helper function for the new config system + def __call__(self, value): + if isinstance(value, (list, tuple)): + # list: coerce each element into new list + tmp_list = [ ParamDesc.convert(self, v) for v in value ] + elif isinstance(value, str): + # If input is a csv string + tmp_list = [ ParamDesc.convert(self, v) for v in value.split(',') ] + else: + # singleton: coerce to a single-element list + tmp_list = [ ParamDesc.convert(self, value) ] + + return VectorParamValue(tmp_list) + def swig_module_name(self): return "%s_vector" % self.ptype_str @@ -349,6 +426,7 @@ VectorParam = ParamFactory(VectorParamDesc) # built-in str class. class String(ParamValue,str): cxx_type = 'std::string' + cmd_line_settable = True @classmethod def cxx_predecls(self, code): @@ -358,6 +436,10 @@ class String(ParamValue,str): def swig_predecls(cls, code): code('%include "std_string.i"') + def __call__(self, value): + self = value + return value + def getValue(self): return self @@ -430,6 +512,7 @@ class CheckedIntType(MetaParamValue): # metaclass CheckedIntType.__init__. class CheckedInt(NumericParamValue): __metaclass__ = CheckedIntType + cmd_line_settable = True def _check(self): if not self.min <= self.value <= self.max: @@ -446,6 +529,10 @@ class CheckedInt(NumericParamValue): % type(value).__name__ self._check() + def __call__(self, value): + self.__init__(value) + return value + @classmethod def cxx_predecls(cls, code): # most derived types require this, so we just do it here once @@ -490,19 +577,25 @@ class Cycles(CheckedInt): class Float(ParamValue, float): cxx_type = 'double' + cmdLineSettable = True def __init__(self, value): - if isinstance(value, (int, long, float, NumericParamValue, Float)): + if isinstance(value, (int, long, float, NumericParamValue, Float, str)): self.value = float(value) else: raise TypeError, "Can't convert object of type %s to Float" \ % type(value).__name__ + def __call__(self, value): + self.__init__(value) + return value + def getValue(self): return float(self.value) class MemorySize(CheckedInt): cxx_type = 'uint64_t' + ex_str = '512MB' size = 64 unsigned = True def __init__(self, value): @@ -514,6 +607,7 @@ class MemorySize(CheckedInt): class MemorySize32(CheckedInt): cxx_type = 'uint32_t' + ex_str = '512MB' size = 32 unsigned = True def __init__(self, value): @@ -541,6 +635,12 @@ class Addr(CheckedInt): return self.value + other.value else: return self.value + other + def pretty_print(self, value): + try: + val = convert.toMemorySize(value) + except TypeError: + val = long(value) + return "0x%x" % long(val) class AddrRange(ParamValue): cxx_type = 'AddrRange' @@ -624,12 +724,18 @@ class AddrRange(ParamValue): # False. Thus this is a little more complicated than String. class Bool(ParamValue): cxx_type = 'bool' + cmd_line_settable = True + def __init__(self, value): try: self.value = convert.toBool(value) except TypeError: self.value = bool(value) + def __call__(self, value): + self.__init__(value) + return value + def getValue(self): return bool(self.value) @@ -668,6 +774,8 @@ def NextEthernetAddr(): class EthernetAddr(ParamValue): cxx_type = 'Net::EthAddr' + ex_str = "00:90:00:00:00:01" + cmd_line_settable = True @classmethod def cxx_predecls(cls, code): @@ -695,6 +803,10 @@ class EthernetAddr(ParamValue): self.value = value + def __call__(self, value): + self.__init__(value) + return value + def unproxy(self, base): if self.value == NextEthernetAddr: return EthernetAddr(self.value()) @@ -711,6 +823,8 @@ class EthernetAddr(ParamValue): # the form "a.b.c.d", or an integer representing an IP. class IpAddress(ParamValue): cxx_type = 'Net::IpAddress' + ex_str = "127.0.0.1" + cmd_line_settable = True @classmethod def cxx_predecls(cls, code): @@ -730,6 +844,10 @@ class IpAddress(ParamValue): self.ip = long(value) self.verifyIp() + def __call__(self, value): + self.__init__(value) + return value + def __str__(self): tup = [(self.ip >> i) & 0xff for i in (24, 16, 8, 0)] return '%d.%d.%d.%d' % tuple(tup) @@ -761,6 +879,8 @@ class IpAddress(ParamValue): # positional or keyword arguments. class IpNetmask(IpAddress): cxx_type = 'Net::IpNetmask' + ex_str = "127.0.0.0/24" + cmd_line_settable = True @classmethod def cxx_predecls(cls, code): @@ -806,6 +926,10 @@ class IpNetmask(IpAddress): self.verify() + def __call__(self, value): + self.__init__(value) + return value + def __str__(self): return "%s/%d" % (super(IpNetmask, self).__str__(), self.netmask) @@ -833,6 +957,8 @@ class IpNetmask(IpAddress): # the form "a.b.c.d:p", or an ip and port as positional or keyword arguments. class IpWithPort(IpAddress): cxx_type = 'Net::IpWithPort' + ex_str = "127.0.0.1:80" + cmd_line_settable = True @classmethod def cxx_predecls(cls, code): @@ -878,6 +1004,10 @@ class IpWithPort(IpAddress): self.verify() + def __call__(self, value): + self.__init__(value) + return value + def __str__(self): return "%s:%d" % (super(IpWithPort, self).__str__(), self.port) @@ -953,6 +1083,10 @@ class Time(ParamValue): def __init__(self, value): self.value = parse_time(value) + def __call__(self, value): + self.__init__(value) + return value + def getValue(self): from m5.internal.params import tm @@ -1111,6 +1245,7 @@ $wrapper $wrapper_name { class Enum(ParamValue): __metaclass__ = MetaEnum vals = [] + cmd_line_settable = True # The name of the wrapping namespace or struct wrapper_name = 'Enums' @@ -1127,6 +1262,10 @@ class Enum(ParamValue): % (value, self.vals) self.value = value + def __call__(self, value): + self.__init__(value) + return value + @classmethod def cxx_predecls(cls, code): code('#include "enums/$0.hh"', cls.__name__) @@ -1146,6 +1285,8 @@ frequency_tolerance = 0.001 # 0.1% class TickParamValue(NumericParamValue): cxx_type = 'Tick' + ex_str = "1MHz" + cmd_line_settable = True @classmethod def cxx_predecls(cls, code): @@ -1156,10 +1297,16 @@ class TickParamValue(NumericParamValue): code('%import "stdint.i"') code('%import "base/types.hh"') + def __call__(self, value): + self.__init__(value) + return value + def getValue(self): return long(self.value) class Latency(TickParamValue): + ex_str = "100ns" + def __init__(self, value): if isinstance(value, (Latency, Clock)): self.ticks = value.ticks @@ -1174,6 +1321,10 @@ class Latency(TickParamValue): self.ticks = False self.value = convert.toLatency(value) + def __call__(self, value): + self.__init__(value) + return value + def __getattr__(self, attr): if attr in ('latency', 'period'): return self @@ -1193,6 +1344,8 @@ class Latency(TickParamValue): return '%d' % self.getValue() class Frequency(TickParamValue): + ex_str = "1GHz" + def __init__(self, value): if isinstance(value, (Latency, Clock)): if value.value == 0: @@ -1207,6 +1360,10 @@ class Frequency(TickParamValue): self.ticks = False self.value = convert.toFrequency(value) + def __call__(self, value): + self.__init__(value) + return value + def __getattr__(self, attr): if attr == 'frequency': return self @@ -1242,6 +1399,13 @@ class Clock(TickParamValue): self.ticks = False self.value = convert.anyToLatency(value) + def __call__(self, value): + self.__init__(value) + return value + + def __str__(self): + return "%s" % Latency(self) + def __getattr__(self, attr): if attr == 'frequency': return Frequency(self) @@ -1257,13 +1421,21 @@ class Clock(TickParamValue): class Voltage(float,ParamValue): cxx_type = 'double' + ex_str = "1V" + cmd_line_settable = False + def __new__(cls, value): # convert to voltage val = convert.toVoltage(value) return super(cls, Voltage).__new__(cls, val) + def __call__(self, value): + val = convert.toVoltage(value) + self.__init__(val) + return value + def __str__(self): - return str(self.val) + return str(self.getValue()) def getValue(self): value = float(self) @@ -1274,6 +1446,9 @@ class Voltage(float,ParamValue): class NetworkBandwidth(float,ParamValue): cxx_type = 'float' + ex_str = "1Gbps" + cmd_line_settable = True + def __new__(cls, value): # convert to bits per second val = convert.toNetworkBandwidth(value) @@ -1282,6 +1457,11 @@ class NetworkBandwidth(float,ParamValue): def __str__(self): return str(self.val) + def __call__(self, value): + val = convert.toNetworkBandwidth(value) + self.__init__(val) + return value + def getValue(self): # convert to seconds per byte value = 8.0 / float(self) @@ -1294,13 +1474,18 @@ class NetworkBandwidth(float,ParamValue): class MemoryBandwidth(float,ParamValue): cxx_type = 'float' + ex_str = "1GB/s" + cmd_line_settable = True + def __new__(cls, value): # convert to bytes per second val = convert.toMemoryBandwidth(value) return super(cls, MemoryBandwidth).__new__(cls, val) - def __str__(self): - return str(self.val) + def __call__(self, value): + val = convert.toMemoryBandwidth(value) + self.__init__(val) + return value def getValue(self): # convert to seconds per byte |