params.py

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

PY
1,172
字号
# Copyright (c) 2004, 2005, 2006# The Regents of The University of Michigan# All Rights Reserved## This code is part of the M5 simulator.## Permission is granted to use, copy, create derivative works and# redistribute this software and such derivative works for any# purpose, so long as the copyright notice above, this grant of# permission, and the disclaimer below appear in all copies made; and# so long as the name of The University of Michigan is not used in any# advertising or publicity pertaining to the use or distribution of# this software without specific, written prior authorization.## THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE# UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND# WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER# EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR# PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE# LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT,# INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM# ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN# IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH# DAMAGES.## Authors: Steven K. Reinhardt#          Nathan L. Binkert####################################################################### Parameter description classes## The _params dictionary in each class maps parameter names to either# a Param or a VectorParam object.  These objects contain the# parameter description string, the parameter type, and the default# value (if any).  The convert() method on these objects is used to# force whatever value is assigned to the parameter to the appropriate# type.## Note that the default values are loaded into the class's attribute# space when the parameter dictionary is initialized (in# MetaSimObject._new_param()); after that point they aren't used.######################################################################import copyimport datetimeimport reimport sysimport timeimport convertimport proxyimport ticksfrom util import *import SimObjectdef isSimObject(*args, **kwargs):    return SimObject.isSimObject(*args, **kwargs)def isSimObjectSequence(*args, **kwargs):    return SimObject.isSimObjectSequence(*args, **kwargs)def isSimObjectClass(*args, **kwargs):    return SimObject.isSimObjectClass(*args, **kwargs)allParams = {}class MetaParamValue(type):    def __new__(mcls, name, bases, dct):        cls = super(MetaParamValue, mcls).__new__(mcls, name, bases, dct)        assert name not in allParams        allParams[name] = cls        return cls# Dummy base class to identify types that are legitimate for SimObject# parameters.class ParamValue(object):    __metaclass__ = MetaParamValue    cxx_predecls = []    swig_predecls = []    # default for printing to .ini file is regular string conversion.    # will be overridden in some cases    def ini_str(self):        return str(self)    # allows us to blithely call unproxy() on things without checking    # if they're really proxies or not    def unproxy(self, base):        return self# Regular parameter description.class ParamDesc(object):    def __init__(self, ptype_str, ptype, *args, **kwargs):        self.ptype_str = ptype_str        # remember ptype only if it is provided        if ptype != None:            self.ptype = ptype        if args:            if len(args) == 1:                self.desc = args[0]            elif len(args) == 2:                self.default = args[0]                self.desc = args[1]            else:                raise TypeError, 'too many arguments'        if kwargs.has_key('desc'):            assert(not hasattr(self, 'desc'))            self.desc = kwargs['desc']            del kwargs['desc']        if kwargs.has_key('default'):            assert(not hasattr(self, 'default'))            self.default = kwargs['default']            del kwargs['default']        if kwargs:            raise TypeError, 'extra unknown kwargs %s' % kwargs        if not hasattr(self, 'desc'):            raise TypeError, 'desc attribute missing'    def __getattr__(self, attr):        if attr == 'ptype':            ptype = SimObject.allClasses[self.ptype_str]            assert issubclass(ptype, SimObject.SimObject)            self.ptype = ptype            return ptype        raise AttributeError, "'%s' object has no attribute '%s'" % \              (type(self).__name__, attr)    def convert(self, value):        if isinstance(value, proxy.BaseProxy):            value.set_param_desc(self)            return value        if not hasattr(self, 'ptype') and isNullPointer(value):            # deferred evaluation of SimObject; continue to defer if            # we're just assigning a null pointer            return value        if isinstance(value, self.ptype):            return value        if isNullPointer(value) and isSimObjectClass(self.ptype):            return value        return self.ptype(value)    def cxx_predecls(self):        return self.ptype.cxx_predecls    def swig_predecls(self):        return self.ptype.swig_predecls    def cxx_decl(self):        return '%s %s;' % (self.ptype.cxx_type, self.name)# Vector-valued parameter description.  Just like ParamDesc, except# that the value is a vector (list) of the specified type instead of a# single value.class VectorParamValue(list):    __metaclass__ = MetaParamValue    def ini_str(self):        return ' '.join([v.ini_str() for v in self])    def getValue(self):        return [ v.getValue() for v in self ]    def unproxy(self, base):        return [v.unproxy(base) for v in self]class SimObjVector(VectorParamValue):    def print_ini(self, ini_file):        for v in self:            v.print_ini(ini_file)class VectorParamDesc(ParamDesc):    # Convert assigned value to appropriate type.  If the RHS is not a    # list or tuple, it generates a single-element list.    def convert(self, value):        if isinstance(value, (list, tuple)):            # list: coerce each element into new list            tmp_list = [ ParamDesc.convert(self, v) for v in value ]        else:            # singleton: coerce to a single-element list            tmp_list = [ ParamDesc.convert(self, value) ]        if isSimObjectSequence(tmp_list):            return SimObjVector(tmp_list)        else:            return VectorParamValue(tmp_list)    def swig_predecls(self):        return ['%%include "%s_vptype.i"' % self.ptype_str]    def swig_decl(self):        cxx_type = re.sub('std::', '', self.ptype.cxx_type)        vdecl = 'namespace std { %%template(vector_%s) vector< %s >; }' % \                (self.ptype_str, cxx_type)        return ['%include "std_vector.i"'] + self.ptype.swig_predecls + [vdecl]    def cxx_predecls(self):        return ['#include <vector>'] + self.ptype.cxx_predecls    def cxx_decl(self):        return 'std::vector< %s > %s;' % (self.ptype.cxx_type, self.name)class ParamFactory(object):    def __init__(self, param_desc_class, ptype_str = None):        self.param_desc_class = param_desc_class        self.ptype_str = ptype_str    def __getattr__(self, attr):        if self.ptype_str:            attr = self.ptype_str + '.' + attr        return ParamFactory(self.param_desc_class, attr)    # E.g., Param.Int(5, "number of widgets")    def __call__(self, *args, **kwargs):        ptype = None        try:            ptype = allParams[self.ptype_str]        except KeyError:            # if name isn't defined yet, assume it's a SimObject, and            # try to resolve it later            pass        return self.param_desc_class(self.ptype_str, ptype, *args, **kwargs)Param = ParamFactory(ParamDesc)VectorParam = ParamFactory(VectorParamDesc)####################################################################### Parameter Types## Though native Python types could be used to specify parameter types# (the 'ptype' field of the Param and VectorParam classes), it's more# flexible to define our own set of types.  This gives us more control# over how Python expressions are converted to values (via the# __init__() constructor) and how these values are printed out (via# the __str__() conversion method).####################################################################### String-valued parameter.  Just mixin the ParamValue class with the# built-in str class.class String(ParamValue,str):    cxx_type = 'std::string'    cxx_predecls = ['#include <string>']    swig_predecls = ['%include "std_string.i"\n' +                     '%apply const std::string& {std::string *};']    swig_predecls = ['%include "std_string.i"' ]    def getValue(self):        return self# superclass for "numeric" parameter values, to emulate math# operations in a type-safe way.  e.g., a Latency times an int returns# a new Latency object.class NumericParamValue(ParamValue):    def __str__(self):        return str(self.value)    def __float__(self):        return float(self.value)    def __long__(self):        return long(self.value)    def __int__(self):        return int(self.value)    # hook for bounds checking    def _check(self):        return    def __mul__(self, other):        newobj = self.__class__(self)        newobj.value *= other        newobj._check()        return newobj    __rmul__ = __mul__    def __div__(self, other):        newobj = self.__class__(self)        newobj.value /= other        newobj._check()        return newobj    def __sub__(self, other):        newobj = self.__class__(self)        newobj.value -= other        newobj._check()        return newobj# Metaclass for bounds-checked integer parameters.  See CheckedInt.class CheckedIntType(MetaParamValue):    def __init__(cls, name, bases, dict):        super(CheckedIntType, cls).__init__(name, bases, dict)        # CheckedInt is an abstract base class, so we actually don't        # want to do any processing on it... the rest of this code is        # just for classes that derive from CheckedInt.        if name == 'CheckedInt':            return        if not cls.cxx_predecls:            # most derived types require this, so we just do it here once            cls.cxx_predecls = ['#include "sim/host.hh"']        if not cls.swig_predecls:            # most derived types require this, so we just do it here once            cls.swig_predecls = ['%import "stdint.i"\n' +                                 '%import "sim/host.hh"']        if not (hasattr(cls, 'min') and hasattr(cls, 'max')):            if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')):                panic("CheckedInt subclass %s must define either\n" \                      "    'min' and 'max' or 'size' and 'unsigned'\n" \                      % name);            if cls.unsigned:                cls.min = 0                cls.max = 2 ** cls.size - 1            else:                cls.min = -(2 ** (cls.size - 1))                cls.max = (2 ** (cls.size - 1)) - 1# Abstract superclass for bounds-checked integer parameters.  This# 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(NumericParamValue):    __metaclass__ = CheckedIntType    def _check(self):        if not self.min <= self.value <= self.max:            raise TypeError, 'Integer param out of bounds %d < %d < %d' % \                  (self.min, self.value, self.max)    def __init__(self, value):        if isinstance(value, str):            self.value = convert.toInteger(value)        elif isinstance(value, (int, long, float, NumericParamValue)):            self.value = long(value)        else:            raise TypeError, "Can't convert object of type %s to CheckedInt" \                  % type(value).__name__        self._check()    def getValue(self):        return long(self.value)class Int(CheckedInt):      cxx_type = 'int';      size = 32; unsigned = Falseclass Unsigned(CheckedInt): cxx_type = 'unsigned'; size = 32; unsigned = Trueclass Int8(CheckedInt):     cxx_type =   'int8_t'; size =  8; unsigned = Falseclass UInt8(CheckedInt):    cxx_type =  'uint8_t'; size =  8; unsigned = Trueclass Int16(CheckedInt):    cxx_type =  'int16_t'; size = 16; unsigned = Falseclass UInt16(CheckedInt):   cxx_type = 'uint16_t'; size = 16; unsigned = Trueclass Int32(CheckedInt):    cxx_type =  'int32_t'; size = 32; unsigned = Falseclass UInt32(CheckedInt):   cxx_type = 'uint32_t'; size = 32; unsigned = Trueclass Int64(CheckedInt):    cxx_type =  'int64_t'; size = 64; unsigned = Falseclass UInt64(CheckedInt):   cxx_type = 'uint64_t'; size = 64; unsigned = Trueclass Counter(CheckedInt):  cxx_type = 'Counter';  size = 64; unsigned = Trueclass Tick(CheckedInt):     cxx_type = 'Tick';     size = 64; unsigned = Trueclass TcpPort(CheckedInt):  cxx_type = 'uint16_t'; size = 16; unsigned = Trueclass UdpPort(CheckedInt):  cxx_type = 'uint16_t'; size = 16; unsigned = Trueclass Percent(CheckedInt):  cxx_type = 'int'; min = 0; max = 100class Float(ParamValue, float):    cxx_type = 'double'    def getValue(self):        return float(self.value)class MemorySize(CheckedInt):    cxx_type = 'uint64_t'    size = 64    unsigned = True    def __init__(self, value):        if isinstance(value, MemorySize):            self.value = value.value

⌨️ 快捷键说明

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