params.py

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· Python 代码 · 共 1,172 行 · 第 1/3 页

PY
1,172
字号
        else:            self.value = convert.toMemorySize(value)        self._check()class MemorySize32(CheckedInt):    cxx_type = 'uint32_t'    size = 32    unsigned = True    def __init__(self, value):        if isinstance(value, MemorySize):            self.value = value.value        else:            self.value = convert.toMemorySize(value)        self._check()class Addr(CheckedInt):    cxx_type = 'Addr'    cxx_predecls = ['#include "arch/isa_traits.hh"']    size = 64    unsigned = True    def __init__(self, value):        if isinstance(value, Addr):            self.value = value.value        else:            try:                self.value = convert.toMemorySize(value)            except TypeError:                self.value = long(value)        self._check()    def __add__(self, other):        if isinstance(other, Addr):            return self.value + other.value        else:            return self.value + otherclass MetaRange(MetaParamValue):    def __init__(cls, name, bases, dict):        super(MetaRange, cls).__init__(name, bases, dict)        if name == 'Range':            return        cls.cxx_type = 'Range< %s >' % cls.type.cxx_type        cls.cxx_predecls = \                       ['#include "base/range.hh"'] + cls.type.cxx_predeclsclass Range(ParamValue):    __metaclass__ = MetaRange    type = Int # default; can be overridden in subclasses    def __init__(self, *args, **kwargs):        def handle_kwargs(self, kwargs):            if 'end' in kwargs:                self.second = self.type(kwargs.pop('end'))            elif 'size' in kwargs:                self.second = self.first + self.type(kwargs.pop('size')) - 1            else:                raise TypeError, "Either end or size must be specified"        if len(args) == 0:            self.first = self.type(kwargs.pop('start'))            handle_kwargs(self, kwargs)        elif len(args) == 1:            if kwargs:                self.first = self.type(args[0])                handle_kwargs(self, kwargs)            elif isinstance(args[0], Range):                self.first = self.type(args[0].first)                self.second = self.type(args[0].second)            elif isinstance(args[0], (list, tuple)):                self.first = self.type(args[0][0])                self.second = self.type(args[0][1])            else:                self.first = self.type(0)                self.second = self.type(args[0]) - 1        elif len(args) == 2:            self.first = self.type(args[0])            self.second = self.type(args[1])        else:            raise TypeError, "Too many arguments specified"        if kwargs:            raise TypeError, "too many keywords: %s" % kwargs.keys()    def __str__(self):        return '%s:%s' % (self.first, self.second)class AddrRange(Range):    type = Addr    swig_predecls = ['%include "python/swig/range.i"']    def getValue(self):        from m5.objects.params import AddrRange        value = AddrRange()        value.start = long(self.first)        value.end = long(self.second)        return valueclass TickRange(Range):    type = Tick    swig_predecls = ['%include "python/swig/range.i"']    def getValue(self):        from m5.objects.params import TickRange        value = TickRange()        value.start = long(self.first)        value.end = long(self.second)        return value# Boolean parameter type.  Python doesn't let you subclass bool, since# it doesn't want to let you create multiple instances of True and# False.  Thus this is a little more complicated than String.class Bool(ParamValue):    cxx_type = 'bool'    def __init__(self, value):        try:            self.value = convert.toBool(value)        except TypeError:            self.value = bool(value)    def getValue(self):        return bool(self.value)    def __str__(self):        return str(self.value)    def ini_str(self):        if self.value:            return 'true'        return 'false'def IncEthernetAddr(addr, val = 1):    bytes = map(lambda x: int(x, 16), addr.split(':'))    bytes[5] += val    for i in (5, 4, 3, 2, 1):        val,rem = divmod(bytes[i], 256)        bytes[i] = rem        if val == 0:            break        bytes[i - 1] += val    assert(bytes[0] <= 255)    return ':'.join(map(lambda x: '%02x' % x, bytes))_NextEthernetAddr = "00:90:00:00:00:01"def NextEthernetAddr():    global _NextEthernetAddr    value = _NextEthernetAddr    _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1)    return valueclass EthernetAddr(ParamValue):    cxx_type = 'Net::EthAddr'    cxx_predecls = ['#include "base/inet.hh"']    swig_predecls = ['%include "python/swig/inet.i"']    def __init__(self, value):        if value == NextEthernetAddr:            self.value = value            return        if not isinstance(value, str):            raise TypeError, "expected an ethernet address and didn't get one"        bytes = value.split(':')        if len(bytes) != 6:            raise TypeError, 'invalid ethernet address %s' % value        for byte in bytes:            if not 0 <= int(byte) <= 256:                raise TypeError, 'invalid ethernet address %s' % value        self.value = value    def unproxy(self, base):        if self.value == NextEthernetAddr:            return EthernetAddr(self.value())        return self    def getValue(self):        from m5.objects.params import EthAddr        return EthAddr(self.value)    def ini_str(self):        return self.valuetime_formats = [ "%a %b %d %H:%M:%S %Z %Y",                 "%a %b %d %H:%M:%S %Z %Y",                 "%Y/%m/%d %H:%M:%S",                 "%Y/%m/%d %H:%M",                 "%Y/%m/%d",                 "%m/%d/%Y %H:%M:%S",                 "%m/%d/%Y %H:%M",                 "%m/%d/%Y",                 "%m/%d/%y %H:%M:%S",                 "%m/%d/%y %H:%M",                 "%m/%d/%y"]def parse_time(value):    from time import gmtime, strptime, struct_time, time    from datetime import datetime, date    if isinstance(value, struct_time):        return value    if isinstance(value, (int, long)):        return gmtime(value)    if isinstance(value, (datetime, date)):        return value.timetuple()    if isinstance(value, str):        if value in ('Now', 'Today'):            return time.gmtime(time.time())        for format in time_formats:            try:                return strptime(value, format)            except ValueError:                pass    raise ValueError, "Could not parse '%s' as a time" % valueclass Time(ParamValue):    cxx_type = 'tm'    cxx_predecls = [ '#include <time.h>' ]    swig_predecls = [ '%include "python/swig/time.i"' ]    def __init__(self, value):        self.value = parse_time(value)    def getValue(self):        from m5.objects.params import tm        c_time = tm()        py_time = self.value        # UNIX is years since 1900        c_time.tm_year = py_time.tm_year - 1900;        # Python starts at 1, UNIX starts at 0        c_time.tm_mon =  py_time.tm_mon - 1;        c_time.tm_mday = py_time.tm_mday;        c_time.tm_hour = py_time.tm_hour;        c_time.tm_min = py_time.tm_min;        c_time.tm_sec = py_time.tm_sec;        # Python has 0 as Monday, UNIX is 0 as sunday        c_time.tm_wday = py_time.tm_wday + 1        if c_time.tm_wday > 6:            c_time.tm_wday -= 7;        # Python starts at 1, Unix starts at 0        c_time.tm_yday = py_time.tm_yday - 1;        return c_time    def __str__(self):        return time.asctime(self.value)    def ini_str(self):        return str(self)# Enumerated types are a little more complex.  The user specifies the# type as Enum(foo) where foo is either a list or dictionary of# alternatives (typically strings, but not necessarily so).  (In the# long run, the integer value of the parameter will be the list index# or the corresponding dictionary value.  For now, since we only check# that the alternative is valid and then spit it into a .ini file,# there's not much point in using the dictionary.)# What Enum() must do is generate a new type encapsulating the# provided list/dictionary so that specific values of the parameter# can be instances of that type.  We define two hidden internal# classes (_ListEnum and _DictEnum) to serve as base classes, then# derive the new type from the appropriate base class on the fly.allEnums = {}# Metaclass for Enum typesclass MetaEnum(MetaParamValue):    def __new__(mcls, name, bases, dict):        assert name not in allEnums        cls = super(MetaEnum, mcls).__new__(mcls, name, bases, dict)        allEnums[name] = cls        return cls    def __init__(cls, name, bases, init_dict):        if init_dict.has_key('map'):            if not isinstance(cls.map, dict):                raise TypeError, "Enum-derived class attribute 'map' " \                      "must be of type dict"            # build list of value strings from map            cls.vals = cls.map.keys()            cls.vals.sort()        elif init_dict.has_key('vals'):            if not isinstance(cls.vals, list):                raise TypeError, "Enum-derived class attribute 'vals' " \                      "must be of type list"            # build string->value map from vals sequence            cls.map = {}            for idx,val in enumerate(cls.vals):                cls.map[val] = idx        else:            raise TypeError, "Enum-derived class must define "\                  "attribute 'map' or 'vals'"        cls.cxx_type = 'Enums::%s' % name        super(MetaEnum, cls).__init__(name, bases, init_dict)    def __str__(cls):        return cls.__name__    # Generate C++ class declaration for this enum type.    # Note that we wrap the enum in a class/struct to act as a namespace,    # so that the enum strings can be brief w/o worrying about collisions.    def cxx_decl(cls):        code = "#ifndef __ENUM__%s\n" % cls        code += '#define __ENUM__%s\n' % cls        code += '\n'        code += 'namespace Enums {\n'        code += '    enum %s {\n' % cls        for val in cls.vals:            code += '        %s = %d,\n' % (val, cls.map[val])        code += '        Num_%s = %d,\n' % (cls, len(cls.vals))        code += '    };\n'        code += '    extern const char *%sStrings[Num_%s];\n' % (cls, cls)        code += '}\n'        code += '\n'        code += '#endif\n'        return code    def cxx_def(cls):        code = '#include "enums/%s.hh"\n' % cls        code += 'namespace Enums {\n'        code += '    const char *%sStrings[Num_%s] =\n' % (cls, cls)        code += '    {\n'        for val in cls.vals:            code += '        "%s",\n' % val        code += '    };\n'        code += '}\n'        return code# Base class for enum types.class Enum(ParamValue):    __metaclass__ = MetaEnum    vals = []    def __init__(self, value):        if value not in self.map:            raise TypeError, "Enum param got bad value '%s' (not in %s)" \                  % (value, self.vals)        self.value = value    def getValue(self):        return int(self.map[self.value])    def __str__(self):        return self.value# how big does a rounding error need to be before we warn about it?frequency_tolerance = 0.001  # 0.1%class TickParamValue(NumericParamValue):    cxx_type = 'Tick'    cxx_predecls = ['#include "sim/host.hh"']    swig_predecls = ['%import "stdint.i"\n' +                     '%import "sim/host.hh"']    def getValue(self):        return long(self.value)class Latency(TickParamValue):    def __init__(self, value):        if isinstance(value, (Latency, Clock)):            self.ticks = value.ticks            self.value = value.value        elif isinstance(value, Frequency):            self.ticks = value.ticks            self.value = 1.0 / value.value        elif value.endswith('t'):            self.ticks = True            self.value = int(value[:-1])        else:            self.ticks = False            self.value = convert.toLatency(value)    def __getattr__(self, attr):        if attr in ('latency', 'period'):

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?