summaryrefslogtreecommitdiff
path: root/src/python/m5/params.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/python/m5/params.py')
-rw-r--r--src/python/m5/params.py195
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