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 + -
显示快捷键?