info.py revision 2665
11758Ssaidi@eecs.umich.edu# Copyright (c) 2003-2004 The Regents of The University of Michigan 21758Ssaidi@eecs.umich.edu# All rights reserved. 31758Ssaidi@eecs.umich.edu# 41758Ssaidi@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 51758Ssaidi@eecs.umich.edu# modification, are permitted provided that the following conditions are 61758Ssaidi@eecs.umich.edu# met: redistributions of source code must retain the above copyright 71758Ssaidi@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 81758Ssaidi@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 91758Ssaidi@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 101758Ssaidi@eecs.umich.edu# documentation and/or other materials provided with the distribution; 111758Ssaidi@eecs.umich.edu# neither the name of the copyright holders nor the names of its 121758Ssaidi@eecs.umich.edu# contributors may be used to endorse or promote products derived from 131758Ssaidi@eecs.umich.edu# this software without specific prior written permission. 141758Ssaidi@eecs.umich.edu# 151758Ssaidi@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 161758Ssaidi@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 171758Ssaidi@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 181758Ssaidi@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 191758Ssaidi@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 201758Ssaidi@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 211758Ssaidi@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 221758Ssaidi@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 231758Ssaidi@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 241758Ssaidi@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 251758Ssaidi@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262665Ssaidi@eecs.umich.edu# 272665Ssaidi@eecs.umich.edu# Authors: Nathan Binkert 281758Ssaidi@eecs.umich.edu 291049Sbinkertn@umich.edufrom __future__ import division 301049Sbinkertn@umich.eduimport operator, re, types 311049Sbinkertn@umich.edu 322015Sbinkertn@umich.educlass ProxyError(Exception): 332015Sbinkertn@umich.edu pass 342015Sbinkertn@umich.edu 351929Sbinkertn@umich.edudef unproxy(proxy): 361929Sbinkertn@umich.edu if hasattr(proxy, '__unproxy__'): 371929Sbinkertn@umich.edu return proxy.__unproxy__() 381049Sbinkertn@umich.edu 391929Sbinkertn@umich.edu return proxy 401049Sbinkertn@umich.edu 411929Sbinkertn@umich.edudef scalar(stat): 421929Sbinkertn@umich.edu stat = unproxy(stat) 431929Sbinkertn@umich.edu assert(stat.__scalar__() != stat.__vector__()) 441929Sbinkertn@umich.edu return stat.__scalar__() 451049Sbinkertn@umich.edu 461929Sbinkertn@umich.edudef vector(stat): 471929Sbinkertn@umich.edu stat = unproxy(stat) 481929Sbinkertn@umich.edu assert(stat.__scalar__() != stat.__vector__()) 491929Sbinkertn@umich.edu return stat.__vector__() 501049Sbinkertn@umich.edu 511929Sbinkertn@umich.edudef value(stat, *args): 521929Sbinkertn@umich.edu stat = unproxy(stat) 531929Sbinkertn@umich.edu return stat.__value__(*args) 541049Sbinkertn@umich.edu 551929Sbinkertn@umich.edudef values(stat, run): 561929Sbinkertn@umich.edu stat = unproxy(stat) 571929Sbinkertn@umich.edu result = [] 581929Sbinkertn@umich.edu for i in xrange(len(stat)): 591934Sbinkertn@umich.edu val = value(stat, run, i) 601929Sbinkertn@umich.edu if val is None: 611929Sbinkertn@umich.edu return None 621929Sbinkertn@umich.edu result.append(val) 631049Sbinkertn@umich.edu return result 641049Sbinkertn@umich.edu 651929Sbinkertn@umich.edudef total(stat, run): 661929Sbinkertn@umich.edu return sum(values(stat, run)) 671049Sbinkertn@umich.edu 681929Sbinkertn@umich.edudef len(stat): 691929Sbinkertn@umich.edu stat = unproxy(stat) 701929Sbinkertn@umich.edu return stat.__len__() 711049Sbinkertn@umich.edu 721929Sbinkertn@umich.educlass Value(object): 731929Sbinkertn@umich.edu def __scalar__(self): 741929Sbinkertn@umich.edu raise AttributeError, "must define __scalar__ for %s" % (type (self)) 751929Sbinkertn@umich.edu def __vector__(self): 761929Sbinkertn@umich.edu raise AttributeError, "must define __vector__ for %s" % (type (self)) 771049Sbinkertn@umich.edu 781929Sbinkertn@umich.edu def __add__(self, other): 791929Sbinkertn@umich.edu return BinaryProxy(operator.__add__, self, other) 801929Sbinkertn@umich.edu def __sub__(self, other): 811929Sbinkertn@umich.edu return BinaryProxy(operator.__sub__, self, other) 821929Sbinkertn@umich.edu def __mul__(self, other): 831929Sbinkertn@umich.edu return BinaryProxy(operator.__mul__, self, other) 841929Sbinkertn@umich.edu def __div__(self, other): 851929Sbinkertn@umich.edu return BinaryProxy(operator.__div__, self, other) 861929Sbinkertn@umich.edu def __truediv__(self, other): 871929Sbinkertn@umich.edu return BinaryProxy(operator.__truediv__, self, other) 881929Sbinkertn@umich.edu def __floordiv__(self, other): 891929Sbinkertn@umich.edu return BinaryProxy(operator.__floordiv__, self, other) 901049Sbinkertn@umich.edu 911929Sbinkertn@umich.edu def __radd__(self, other): 921929Sbinkertn@umich.edu return BinaryProxy(operator.__add__, other, self) 931929Sbinkertn@umich.edu def __rsub__(self, other): 941929Sbinkertn@umich.edu return BinaryProxy(operator.__sub__, other, self) 951929Sbinkertn@umich.edu def __rmul__(self, other): 961929Sbinkertn@umich.edu return BinaryProxy(operator.__mul__, other, self) 971929Sbinkertn@umich.edu def __rdiv__(self, other): 981929Sbinkertn@umich.edu return BinaryProxy(operator.__div__, other, self) 991929Sbinkertn@umich.edu def __rtruediv__(self, other): 1001929Sbinkertn@umich.edu return BinaryProxy(operator.__truediv__, other, self) 1011929Sbinkertn@umich.edu def __rfloordiv__(self, other): 1021929Sbinkertn@umich.edu return BinaryProxy(operator.__floordiv__, other, self) 1031929Sbinkertn@umich.edu 1041929Sbinkertn@umich.edu def __neg__(self): 1051929Sbinkertn@umich.edu return UnaryProxy(operator.__neg__, self) 1061929Sbinkertn@umich.edu def __pos__(self): 1071929Sbinkertn@umich.edu return UnaryProxy(operator.__pos__, self) 1081929Sbinkertn@umich.edu def __abs__(self): 1091929Sbinkertn@umich.edu return UnaryProxy(operator.__abs__, self) 1101929Sbinkertn@umich.edu 1111929Sbinkertn@umich.educlass Scalar(Value): 1121929Sbinkertn@umich.edu def __scalar__(self): 1131929Sbinkertn@umich.edu return True 1141929Sbinkertn@umich.edu 1151929Sbinkertn@umich.edu def __vector__(self): 1161929Sbinkertn@umich.edu return False 1171929Sbinkertn@umich.edu 1181929Sbinkertn@umich.edu def __value__(self, run): 1191929Sbinkertn@umich.edu raise AttributeError, '__value__ must be defined' 1201929Sbinkertn@umich.edu 1211929Sbinkertn@umich.educlass VectorItemProxy(Value): 1221929Sbinkertn@umich.edu def __init__(self, proxy, index): 1231929Sbinkertn@umich.edu self.proxy = proxy 1241929Sbinkertn@umich.edu self.index = index 1251929Sbinkertn@umich.edu 1261929Sbinkertn@umich.edu def __scalar__(self): 1271929Sbinkertn@umich.edu return True 1281929Sbinkertn@umich.edu 1291929Sbinkertn@umich.edu def __vector__(self): 1301929Sbinkertn@umich.edu return False 1311929Sbinkertn@umich.edu 1321929Sbinkertn@umich.edu def __value__(self, run): 1331929Sbinkertn@umich.edu return value(self.proxy, run, self.index) 1341929Sbinkertn@umich.edu 1351929Sbinkertn@umich.educlass Vector(Value): 1361929Sbinkertn@umich.edu def __scalar__(self): 1371929Sbinkertn@umich.edu return False 1381929Sbinkertn@umich.edu 1391929Sbinkertn@umich.edu def __vector__(self): 1401929Sbinkertn@umich.edu return True 1411929Sbinkertn@umich.edu 1421929Sbinkertn@umich.edu def __value__(self, run, index): 1431929Sbinkertn@umich.edu raise AttributeError, '__value__ must be defined' 1441929Sbinkertn@umich.edu 1451929Sbinkertn@umich.edu def __getitem__(self, index): 1461929Sbinkertn@umich.edu return VectorItemProxy(self, index) 1471929Sbinkertn@umich.edu 1481929Sbinkertn@umich.educlass ScalarConstant(Scalar): 1491929Sbinkertn@umich.edu def __init__(self, constant): 1501929Sbinkertn@umich.edu self.constant = constant 1511929Sbinkertn@umich.edu def __value__(self, run): 1521929Sbinkertn@umich.edu return self.constant 1531986Sbinkertn@umich.edu def __str__(self): 1541986Sbinkertn@umich.edu return str(self.constant) 1551929Sbinkertn@umich.edu 1561929Sbinkertn@umich.educlass VectorConstant(Vector): 1571929Sbinkertn@umich.edu def __init__(self, constant): 1581929Sbinkertn@umich.edu self.constant = constant 1591929Sbinkertn@umich.edu def __value__(self, run, index): 1601929Sbinkertn@umich.edu return self.constant[index] 1611929Sbinkertn@umich.edu def __len__(self): 1621929Sbinkertn@umich.edu return len(self.constant) 1631986Sbinkertn@umich.edu def __str__(self): 1641986Sbinkertn@umich.edu return str(self.constant) 1651929Sbinkertn@umich.edu 1661929Sbinkertn@umich.edudef WrapValue(value): 1671929Sbinkertn@umich.edu if isinstance(value, (int, long, float)): 1681929Sbinkertn@umich.edu return ScalarConstant(value) 1691929Sbinkertn@umich.edu if isinstance(value, (list, tuple)): 1701929Sbinkertn@umich.edu return VectorConstant(value) 1711929Sbinkertn@umich.edu if isinstance(value, Value): 1721929Sbinkertn@umich.edu return value 1731929Sbinkertn@umich.edu 1741929Sbinkertn@umich.edu raise AttributeError, 'Only values can be wrapped' 1751049Sbinkertn@umich.edu 1761049Sbinkertn@umich.educlass Statistic(object): 1771929Sbinkertn@umich.edu def __getattr__(self, attr): 1781929Sbinkertn@umich.edu if attr in ('data', 'x', 'y'): 1791929Sbinkertn@umich.edu result = self.source.data(self, self.bins, self.ticks) 1801929Sbinkertn@umich.edu self.data = result.data 1811929Sbinkertn@umich.edu self.x = result.x 1821929Sbinkertn@umich.edu self.y = result.y 1831929Sbinkertn@umich.edu return super(Statistic, self).__getattribute__(attr) 1841049Sbinkertn@umich.edu 1851049Sbinkertn@umich.edu def __setattr__(self, attr, value): 1861929Sbinkertn@umich.edu if attr == 'stat': 1871929Sbinkertn@umich.edu raise AttributeError, '%s is read only' % stat 1881929Sbinkertn@umich.edu if attr in ('source', 'bins', 'ticks'): 1891929Sbinkertn@umich.edu if getattr(self, attr) != value: 1901929Sbinkertn@umich.edu if hasattr(self, 'data'): 1911929Sbinkertn@umich.edu delattr(self, 'data') 1921049Sbinkertn@umich.edu 1931929Sbinkertn@umich.edu super(Statistic, self).__setattr__(attr, value) 1941049Sbinkertn@umich.edu 1951986Sbinkertn@umich.edu def __str__(self): 1961986Sbinkertn@umich.edu return self.name 1971986Sbinkertn@umich.edu 1981929Sbinkertn@umich.educlass ValueProxy(Value): 1991929Sbinkertn@umich.edu def __getattr__(self, attr): 2001929Sbinkertn@umich.edu if attr == '__value__': 2011929Sbinkertn@umich.edu if scalar(self): 2021929Sbinkertn@umich.edu return self.__scalarvalue__ 2031929Sbinkertn@umich.edu if vector(self): 2041929Sbinkertn@umich.edu return self.__vectorvalue__ 2051929Sbinkertn@umich.edu if attr == '__len__': 2061929Sbinkertn@umich.edu if vector(self): 2071929Sbinkertn@umich.edu return self.__vectorlen__ 2081929Sbinkertn@umich.edu return super(ValueProxy, self).__getattribute__(attr) 2091049Sbinkertn@umich.edu 2101929Sbinkertn@umich.educlass UnaryProxy(ValueProxy): 2111929Sbinkertn@umich.edu def __init__(self, op, arg): 2121929Sbinkertn@umich.edu self.op = op 2131929Sbinkertn@umich.edu self.arg = WrapValue(arg) 2141049Sbinkertn@umich.edu 2151929Sbinkertn@umich.edu def __scalar__(self): 2161929Sbinkertn@umich.edu return scalar(self.arg) 2171049Sbinkertn@umich.edu 2181929Sbinkertn@umich.edu def __vector__(self): 2191929Sbinkertn@umich.edu return vector(self.arg) 2201049Sbinkertn@umich.edu 2211929Sbinkertn@umich.edu def __scalarvalue__(self, run): 2221929Sbinkertn@umich.edu val = value(self.arg, run) 2231929Sbinkertn@umich.edu if val is None: 2241929Sbinkertn@umich.edu return None 2251929Sbinkertn@umich.edu return self.op(val) 2261049Sbinkertn@umich.edu 2271929Sbinkertn@umich.edu def __vectorvalue__(self, run, index): 2281929Sbinkertn@umich.edu val = value(self.arg, run, index) 2291929Sbinkertn@umich.edu if val is None: 2301929Sbinkertn@umich.edu return None 2311929Sbinkertn@umich.edu return self.op(val) 2321049Sbinkertn@umich.edu 2331929Sbinkertn@umich.edu def __vectorlen__(self): 2341929Sbinkertn@umich.edu return len(unproxy(self.arg)) 2351049Sbinkertn@umich.edu 2361986Sbinkertn@umich.edu def __str__(self): 2371986Sbinkertn@umich.edu if self.op == operator.__neg__: 2381986Sbinkertn@umich.edu return '-%s' % str(self.arg) 2391986Sbinkertn@umich.edu if self.op == operator.__pos__: 2401986Sbinkertn@umich.edu return '+%s' % str(self.arg) 2411986Sbinkertn@umich.edu if self.op == operator.__abs__: 2421986Sbinkertn@umich.edu return 'abs(%s)' % self.arg 2431986Sbinkertn@umich.edu 2441929Sbinkertn@umich.educlass BinaryProxy(ValueProxy): 2451929Sbinkertn@umich.edu def __init__(self, op, arg0, arg1): 2461929Sbinkertn@umich.edu super(BinaryProxy, self).__init__() 2471929Sbinkertn@umich.edu self.op = op 2481929Sbinkertn@umich.edu self.arg0 = WrapValue(arg0) 2491929Sbinkertn@umich.edu self.arg1 = WrapValue(arg1) 2501049Sbinkertn@umich.edu 2511929Sbinkertn@umich.edu def __scalar__(self): 2521929Sbinkertn@umich.edu return scalar(self.arg0) and scalar(self.arg1) 2531049Sbinkertn@umich.edu 2541929Sbinkertn@umich.edu def __vector__(self): 2551929Sbinkertn@umich.edu return vector(self.arg0) or vector(self.arg1) 2561929Sbinkertn@umich.edu 2571929Sbinkertn@umich.edu def __scalarvalue__(self, run): 2581929Sbinkertn@umich.edu val0 = value(self.arg0, run) 2591929Sbinkertn@umich.edu val1 = value(self.arg1, run) 2601929Sbinkertn@umich.edu if val0 is None or val1 is None: 2611929Sbinkertn@umich.edu return None 2621987Sbinkertn@umich.edu try: 2631987Sbinkertn@umich.edu return self.op(val0, val1) 2641987Sbinkertn@umich.edu except ZeroDivisionError: 2651987Sbinkertn@umich.edu return None 2661929Sbinkertn@umich.edu 2671929Sbinkertn@umich.edu def __vectorvalue__(self, run, index): 2681929Sbinkertn@umich.edu if scalar(self.arg0): 2691929Sbinkertn@umich.edu val0 = value(self.arg0, run) 2701929Sbinkertn@umich.edu if vector(self.arg0): 2711929Sbinkertn@umich.edu val0 = value(self.arg0, run, index) 2721929Sbinkertn@umich.edu if scalar(self.arg1): 2731929Sbinkertn@umich.edu val1 = value(self.arg1, run) 2741929Sbinkertn@umich.edu if vector(self.arg1): 2751929Sbinkertn@umich.edu val1 = value(self.arg1, run, index) 2761929Sbinkertn@umich.edu 2771929Sbinkertn@umich.edu if val0 is None or val1 is None: 2781929Sbinkertn@umich.edu return None 2791929Sbinkertn@umich.edu 2801987Sbinkertn@umich.edu try: 2811987Sbinkertn@umich.edu return self.op(val0, val1) 2821987Sbinkertn@umich.edu except ZeroDivisionError: 2831987Sbinkertn@umich.edu return None 2841929Sbinkertn@umich.edu 2851929Sbinkertn@umich.edu def __vectorlen__(self): 2861929Sbinkertn@umich.edu if vector(self.arg0) and scalar(self.arg1): 2871929Sbinkertn@umich.edu return len(self.arg0) 2881929Sbinkertn@umich.edu if scalar(self.arg0) and vector(self.arg1): 2891929Sbinkertn@umich.edu return len(self.arg1) 2901929Sbinkertn@umich.edu 2911929Sbinkertn@umich.edu len0 = len(self.arg0) 2921929Sbinkertn@umich.edu len1 = len(self.arg1) 2931929Sbinkertn@umich.edu 2941929Sbinkertn@umich.edu if len0 != len1: 2951929Sbinkertn@umich.edu raise AttributeError, \ 2961929Sbinkertn@umich.edu "vectors of different lengths %d != %d" % (len0, len1) 2971929Sbinkertn@umich.edu 2981929Sbinkertn@umich.edu return len0 2991929Sbinkertn@umich.edu 3001986Sbinkertn@umich.edu def __str__(self): 3011986Sbinkertn@umich.edu ops = { operator.__add__ : '+', 3021986Sbinkertn@umich.edu operator.__sub__ : '-', 3031986Sbinkertn@umich.edu operator.__mul__ : '*', 3041986Sbinkertn@umich.edu operator.__div__ : '/', 3051986Sbinkertn@umich.edu operator.__truediv__ : '/', 3061986Sbinkertn@umich.edu operator.__floordiv__ : '//' } 3071986Sbinkertn@umich.edu 3081986Sbinkertn@umich.edu return '(%s %s %s)' % (str(self.arg0), ops[self.op], str(self.arg1)) 3091986Sbinkertn@umich.edu 3101929Sbinkertn@umich.educlass Proxy(Value): 3111929Sbinkertn@umich.edu def __init__(self, name, dict): 3121929Sbinkertn@umich.edu self.name = name 3131929Sbinkertn@umich.edu self.dict = dict 3141929Sbinkertn@umich.edu 3151929Sbinkertn@umich.edu def __unproxy__(self): 3161929Sbinkertn@umich.edu return unproxy(self.dict[self.name]) 3171929Sbinkertn@umich.edu 3181929Sbinkertn@umich.edu def __getitem__(self, index): 3191929Sbinkertn@umich.edu return ItemProxy(self, index) 3201929Sbinkertn@umich.edu 3211929Sbinkertn@umich.edu def __getattr__(self, attr): 3221929Sbinkertn@umich.edu return AttrProxy(self, attr) 3231929Sbinkertn@umich.edu 3241986Sbinkertn@umich.edu def __str__(self): 3251986Sbinkertn@umich.edu return str(self.dict[self.name]) 3261986Sbinkertn@umich.edu 3271929Sbinkertn@umich.educlass ItemProxy(Proxy): 3281929Sbinkertn@umich.edu def __init__(self, proxy, index): 3291929Sbinkertn@umich.edu self.proxy = proxy 3301929Sbinkertn@umich.edu self.index = index 3311929Sbinkertn@umich.edu 3321929Sbinkertn@umich.edu def __unproxy__(self): 3331929Sbinkertn@umich.edu return unproxy(unproxy(self.proxy)[self.index]) 3341929Sbinkertn@umich.edu 3351986Sbinkertn@umich.edu def __str__(self): 3361986Sbinkertn@umich.edu return '%s[%s]' % (self.proxy, self.index) 3371986Sbinkertn@umich.edu 3381929Sbinkertn@umich.educlass AttrProxy(Proxy): 3391929Sbinkertn@umich.edu def __init__(self, proxy, attr): 3401929Sbinkertn@umich.edu self.proxy = proxy 3411929Sbinkertn@umich.edu self.attr = attr 3421929Sbinkertn@umich.edu 3431929Sbinkertn@umich.edu def __unproxy__(self): 3442015Sbinkertn@umich.edu proxy = unproxy(self.proxy) 3452015Sbinkertn@umich.edu try: 3462015Sbinkertn@umich.edu attr = getattr(proxy, self.attr) 3472015Sbinkertn@umich.edu except AttributeError, e: 3482015Sbinkertn@umich.edu raise ProxyError, e 3492015Sbinkertn@umich.edu return unproxy(attr) 3501929Sbinkertn@umich.edu 3511986Sbinkertn@umich.edu def __str__(self): 3521986Sbinkertn@umich.edu return '%s.%s' % (self.proxy, self.attr) 3531986Sbinkertn@umich.edu 3541929Sbinkertn@umich.educlass ProxyGroup(object): 3551929Sbinkertn@umich.edu def __init__(self, dict=None, **kwargs): 3561929Sbinkertn@umich.edu self.__dict__['dict'] = {} 3571929Sbinkertn@umich.edu 3581929Sbinkertn@umich.edu if dict is not None: 3591929Sbinkertn@umich.edu self.dict.update(dict) 3601929Sbinkertn@umich.edu 3611929Sbinkertn@umich.edu if kwargs: 3621929Sbinkertn@umich.edu self.dict.update(kwargs) 3631929Sbinkertn@umich.edu 3641929Sbinkertn@umich.edu def __getattr__(self, name): 3651929Sbinkertn@umich.edu return Proxy(name, self.dict) 3661929Sbinkertn@umich.edu 3671929Sbinkertn@umich.edu def __setattr__(self, attr, value): 3681929Sbinkertn@umich.edu self.dict[attr] = value 3691929Sbinkertn@umich.edu 3701929Sbinkertn@umich.educlass ScalarStat(Statistic,Scalar): 3711929Sbinkertn@umich.edu def __value__(self, run): 3721929Sbinkertn@umich.edu if run not in self.data: 3731929Sbinkertn@umich.edu return None 3741929Sbinkertn@umich.edu return self.data[run][0][0] 3751929Sbinkertn@umich.edu 3761929Sbinkertn@umich.edu def display(self, run=None): 3771049Sbinkertn@umich.edu import display 3781049Sbinkertn@umich.edu p = display.Print() 3791049Sbinkertn@umich.edu p.name = self.name 3801049Sbinkertn@umich.edu p.desc = self.desc 3811929Sbinkertn@umich.edu p.value = value(self, run) 3821049Sbinkertn@umich.edu p.flags = self.flags 3831049Sbinkertn@umich.edu p.precision = self.precision 3841049Sbinkertn@umich.edu if display.all or (self.flags & flags.printable): 3851049Sbinkertn@umich.edu p.display() 3861049Sbinkertn@umich.edu 3871929Sbinkertn@umich.educlass VectorStat(Statistic,Vector): 3881929Sbinkertn@umich.edu def __value__(self, run, item): 3891929Sbinkertn@umich.edu if run not in self.data: 3901929Sbinkertn@umich.edu return None 3911929Sbinkertn@umich.edu return self.data[run][item][0] 3921049Sbinkertn@umich.edu 3931929Sbinkertn@umich.edu def __len__(self): 3941929Sbinkertn@umich.edu return self.x 3951049Sbinkertn@umich.edu 3961929Sbinkertn@umich.edu def display(self, run=None): 3971049Sbinkertn@umich.edu import display 3981049Sbinkertn@umich.edu d = display.VectorDisplay() 3991929Sbinkertn@umich.edu d.name = self.name 4001929Sbinkertn@umich.edu d.desc = self.desc 4011929Sbinkertn@umich.edu d.value = [ value(self, run, i) for i in xrange(len(self)) ] 4021929Sbinkertn@umich.edu d.flags = self.flags 4031929Sbinkertn@umich.edu d.precision = self.precision 4041049Sbinkertn@umich.edu d.display() 4051049Sbinkertn@umich.edu 4061929Sbinkertn@umich.educlass Formula(Value): 4071929Sbinkertn@umich.edu def __getattribute__(self, attr): 4081929Sbinkertn@umich.edu if attr not in ( '__scalar__', '__vector__', '__value__', '__len__' ): 4091929Sbinkertn@umich.edu return super(Formula, self).__getattribute__(attr) 4101049Sbinkertn@umich.edu 4111929Sbinkertn@umich.edu formula = re.sub(':', '__', self.formula) 4121929Sbinkertn@umich.edu value = eval(formula, self.source.stattop) 4131929Sbinkertn@umich.edu return getattr(value, attr) 4141049Sbinkertn@umich.edu 4151986Sbinkertn@umich.edu def __str__(self): 4161986Sbinkertn@umich.edu return self.name 4171986Sbinkertn@umich.edu 4181929Sbinkertn@umich.educlass SimpleDist(Statistic): 4191049Sbinkertn@umich.edu def __init__(self, sums, squares, samples): 4201049Sbinkertn@umich.edu self.sums = sums 4211049Sbinkertn@umich.edu self.squares = squares 4221049Sbinkertn@umich.edu self.samples = samples 4231049Sbinkertn@umich.edu 4241049Sbinkertn@umich.edu def display(self, name, desc, flags, precision): 4251049Sbinkertn@umich.edu import display 4261049Sbinkertn@umich.edu p = display.Print() 4271049Sbinkertn@umich.edu p.flags = flags 4281049Sbinkertn@umich.edu p.precision = precision 4291049Sbinkertn@umich.edu 4301049Sbinkertn@umich.edu if self.samples > 0: 4311049Sbinkertn@umich.edu p.name = name + ".mean" 4321049Sbinkertn@umich.edu p.value = self.sums / self.samples 4331049Sbinkertn@umich.edu p.display() 4341049Sbinkertn@umich.edu 4351049Sbinkertn@umich.edu p.name = name + ".stdev" 4361049Sbinkertn@umich.edu if self.samples > 1: 4371049Sbinkertn@umich.edu var = (self.samples * self.squares - self.sums ** 2) \ 4381049Sbinkertn@umich.edu / (self.samples * (self.samples - 1)) 4391049Sbinkertn@umich.edu if var >= 0: 4401049Sbinkertn@umich.edu p.value = math.sqrt(var) 4411049Sbinkertn@umich.edu else: 4421049Sbinkertn@umich.edu p.value = 'NaN' 4431049Sbinkertn@umich.edu else: 4441049Sbinkertn@umich.edu p.value = 0.0 4451049Sbinkertn@umich.edu p.display() 4461049Sbinkertn@umich.edu 4471049Sbinkertn@umich.edu p.name = name + ".samples" 4481049Sbinkertn@umich.edu p.value = self.samples 4491049Sbinkertn@umich.edu p.display() 4501049Sbinkertn@umich.edu 4511049Sbinkertn@umich.edu def comparable(self, other): 4521049Sbinkertn@umich.edu return True 4531049Sbinkertn@umich.edu 4541049Sbinkertn@umich.edu def __eq__(self, other): 4551049Sbinkertn@umich.edu return self.sums == other.sums and self.squares == other.squares and \ 4561049Sbinkertn@umich.edu self.samples == other.samples 4571049Sbinkertn@umich.edu 4581049Sbinkertn@umich.edu def __isub__(self, other): 4591049Sbinkertn@umich.edu self.sums -= other.sums 4601049Sbinkertn@umich.edu self.squares -= other.squares 4611049Sbinkertn@umich.edu self.samples -= other.samples 4621049Sbinkertn@umich.edu return self 4631049Sbinkertn@umich.edu 4641049Sbinkertn@umich.edu def __iadd__(self, other): 4651049Sbinkertn@umich.edu self.sums += other.sums 4661049Sbinkertn@umich.edu self.squares += other.squares 4671049Sbinkertn@umich.edu self.samples += other.samples 4681049Sbinkertn@umich.edu return self 4691049Sbinkertn@umich.edu 4701049Sbinkertn@umich.edu def __itruediv__(self, other): 4711049Sbinkertn@umich.edu if not other: 4721049Sbinkertn@umich.edu return self 4731049Sbinkertn@umich.edu self.sums /= other 4741049Sbinkertn@umich.edu self.squares /= other 4751049Sbinkertn@umich.edu self.samples /= other 4761049Sbinkertn@umich.edu return self 4771049Sbinkertn@umich.edu 4781049Sbinkertn@umich.educlass FullDist(SimpleDist): 4791049Sbinkertn@umich.edu def __init__(self, sums, squares, samples, minval, maxval, 4801049Sbinkertn@umich.edu under, vec, over, min, max, bsize, size): 4811049Sbinkertn@umich.edu self.sums = sums 4821049Sbinkertn@umich.edu self.squares = squares 4831049Sbinkertn@umich.edu self.samples = samples 4841049Sbinkertn@umich.edu self.minval = minval 4851049Sbinkertn@umich.edu self.maxval = maxval 4861049Sbinkertn@umich.edu self.under = under 4871049Sbinkertn@umich.edu self.vec = vec 4881049Sbinkertn@umich.edu self.over = over 4891049Sbinkertn@umich.edu self.min = min 4901049Sbinkertn@umich.edu self.max = max 4911049Sbinkertn@umich.edu self.bsize = bsize 4921049Sbinkertn@umich.edu self.size = size 4931049Sbinkertn@umich.edu 4941049Sbinkertn@umich.edu def display(self, name, desc, flags, precision): 4951049Sbinkertn@umich.edu import display 4961049Sbinkertn@umich.edu p = display.Print() 4971049Sbinkertn@umich.edu p.flags = flags 4981049Sbinkertn@umich.edu p.precision = precision 4991049Sbinkertn@umich.edu 5001049Sbinkertn@umich.edu p.name = name + '.min_val' 5011049Sbinkertn@umich.edu p.value = self.minval 5021049Sbinkertn@umich.edu p.display() 5031049Sbinkertn@umich.edu 5041049Sbinkertn@umich.edu p.name = name + '.max_val' 5051049Sbinkertn@umich.edu p.value = self.maxval 5061049Sbinkertn@umich.edu p.display() 5071049Sbinkertn@umich.edu 5081049Sbinkertn@umich.edu p.name = name + '.underflow' 5091049Sbinkertn@umich.edu p.value = self.under 5101049Sbinkertn@umich.edu p.display() 5111049Sbinkertn@umich.edu 5121049Sbinkertn@umich.edu i = self.min 5131049Sbinkertn@umich.edu for val in self.vec[:-1]: 5141049Sbinkertn@umich.edu p.name = name + '[%d:%d]' % (i, i + self.bsize - 1) 5151049Sbinkertn@umich.edu p.value = val 5161049Sbinkertn@umich.edu p.display() 5171049Sbinkertn@umich.edu i += self.bsize 5181049Sbinkertn@umich.edu 5191049Sbinkertn@umich.edu p.name = name + '[%d:%d]' % (i, self.max) 5201049Sbinkertn@umich.edu p.value = self.vec[-1] 5211049Sbinkertn@umich.edu p.display() 5221049Sbinkertn@umich.edu 5231049Sbinkertn@umich.edu 5241049Sbinkertn@umich.edu p.name = name + '.overflow' 5251049Sbinkertn@umich.edu p.value = self.over 5261049Sbinkertn@umich.edu p.display() 5271049Sbinkertn@umich.edu 5281049Sbinkertn@umich.edu SimpleDist.display(self, name, desc, flags, precision) 5291049Sbinkertn@umich.edu 5301049Sbinkertn@umich.edu def comparable(self, other): 5311049Sbinkertn@umich.edu return self.min == other.min and self.max == other.max and \ 5321049Sbinkertn@umich.edu self.bsize == other.bsize and self.size == other.size 5331049Sbinkertn@umich.edu 5341049Sbinkertn@umich.edu def __eq__(self, other): 5351049Sbinkertn@umich.edu return self.sums == other.sums and self.squares == other.squares and \ 5361049Sbinkertn@umich.edu self.samples == other.samples 5371049Sbinkertn@umich.edu 5381049Sbinkertn@umich.edu def __isub__(self, other): 5391049Sbinkertn@umich.edu self.sums -= other.sums 5401049Sbinkertn@umich.edu self.squares -= other.squares 5411049Sbinkertn@umich.edu self.samples -= other.samples 5421049Sbinkertn@umich.edu 5431049Sbinkertn@umich.edu if other.samples: 5441049Sbinkertn@umich.edu self.minval = min(self.minval, other.minval) 5451049Sbinkertn@umich.edu self.maxval = max(self.maxval, other.maxval) 5461049Sbinkertn@umich.edu self.under -= under 5471049Sbinkertn@umich.edu self.vec = map(lambda x,y: x - y, self.vec, other.vec) 5481049Sbinkertn@umich.edu self.over -= over 5491049Sbinkertn@umich.edu return self 5501049Sbinkertn@umich.edu 5511049Sbinkertn@umich.edu def __iadd__(self, other): 5521049Sbinkertn@umich.edu if not self.samples and other.samples: 5531049Sbinkertn@umich.edu self = other 5541049Sbinkertn@umich.edu return self 5551049Sbinkertn@umich.edu 5561049Sbinkertn@umich.edu self.sums += other.sums 5571049Sbinkertn@umich.edu self.squares += other.squares 5581049Sbinkertn@umich.edu self.samples += other.samples 5591049Sbinkertn@umich.edu 5601049Sbinkertn@umich.edu if other.samples: 5611049Sbinkertn@umich.edu self.minval = min(self.minval, other.minval) 5621049Sbinkertn@umich.edu self.maxval = max(self.maxval, other.maxval) 5631049Sbinkertn@umich.edu self.under += other.under 5641049Sbinkertn@umich.edu self.vec = map(lambda x,y: x + y, self.vec, other.vec) 5651049Sbinkertn@umich.edu self.over += other.over 5661049Sbinkertn@umich.edu return self 5671049Sbinkertn@umich.edu 5681049Sbinkertn@umich.edu def __itruediv__(self, other): 5691049Sbinkertn@umich.edu if not other: 5701049Sbinkertn@umich.edu return self 5711049Sbinkertn@umich.edu self.sums /= other 5721049Sbinkertn@umich.edu self.squares /= other 5731049Sbinkertn@umich.edu self.samples /= other 5741049Sbinkertn@umich.edu 5751049Sbinkertn@umich.edu if self.samples: 5761049Sbinkertn@umich.edu self.under /= other 5771049Sbinkertn@umich.edu for i in xrange(len(self.vec)): 5781049Sbinkertn@umich.edu self.vec[i] /= other 5791049Sbinkertn@umich.edu self.over /= other 5801049Sbinkertn@umich.edu return self 5811049Sbinkertn@umich.edu 5821049Sbinkertn@umich.educlass Dist(Statistic): 5831049Sbinkertn@umich.edu def display(self): 5841049Sbinkertn@umich.edu import display 5851049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 5861049Sbinkertn@umich.edu return 5871049Sbinkertn@umich.edu 5881049Sbinkertn@umich.edu self.dist.display(self.name, self.desc, self.flags, self.precision) 5891049Sbinkertn@umich.edu 5901049Sbinkertn@umich.edu def comparable(self, other): 5911049Sbinkertn@umich.edu return self.name == other.name and \ 5921049Sbinkertn@umich.edu self.dist.compareable(other.dist) 5931049Sbinkertn@umich.edu 5941049Sbinkertn@umich.edu def __eq__(self, other): 5951049Sbinkertn@umich.edu return self.dist == other.dist 5961049Sbinkertn@umich.edu 5971049Sbinkertn@umich.edu def __isub__(self, other): 5981049Sbinkertn@umich.edu self.dist -= other.dist 5991049Sbinkertn@umich.edu return self 6001049Sbinkertn@umich.edu 6011049Sbinkertn@umich.edu def __iadd__(self, other): 6021049Sbinkertn@umich.edu self.dist += other.dist 6031049Sbinkertn@umich.edu return self 6041049Sbinkertn@umich.edu 6051049Sbinkertn@umich.edu def __itruediv__(self, other): 6061049Sbinkertn@umich.edu if not other: 6071049Sbinkertn@umich.edu return self 6081049Sbinkertn@umich.edu self.dist /= other 6091049Sbinkertn@umich.edu return self 6101049Sbinkertn@umich.edu 6111049Sbinkertn@umich.educlass VectorDist(Statistic): 6121049Sbinkertn@umich.edu def display(self): 6131049Sbinkertn@umich.edu import display 6141049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 6151049Sbinkertn@umich.edu return 6161049Sbinkertn@umich.edu 6171049Sbinkertn@umich.edu if isinstance(self.dist, SimpleDist): 6181049Sbinkertn@umich.edu return 6191049Sbinkertn@umich.edu 6201049Sbinkertn@umich.edu for dist,sn,sd,i in map(None, self.dist, self.subnames, self.subdescs, 6211049Sbinkertn@umich.edu range(len(self.dist))): 6221049Sbinkertn@umich.edu if len(sn) > 0: 6231049Sbinkertn@umich.edu name = '%s.%s' % (self.name, sn) 6241049Sbinkertn@umich.edu else: 6251049Sbinkertn@umich.edu name = '%s[%d]' % (self.name, i) 6261049Sbinkertn@umich.edu 6271049Sbinkertn@umich.edu if len(sd) > 0: 6281049Sbinkertn@umich.edu desc = sd 6291049Sbinkertn@umich.edu else: 6301049Sbinkertn@umich.edu desc = self.desc 6311049Sbinkertn@umich.edu 6321049Sbinkertn@umich.edu dist.display(name, desc, self.flags, self.precision) 6331049Sbinkertn@umich.edu 6341049Sbinkertn@umich.edu if (self.flags & flags.total) or 1: 6351049Sbinkertn@umich.edu if isinstance(self.dist[0], SimpleDist): 6361049Sbinkertn@umich.edu disttotal = SimpleDist( \ 6371049Sbinkertn@umich.edu reduce(sums, [d.sums for d in self.dist]), 6381049Sbinkertn@umich.edu reduce(sums, [d.squares for d in self.dist]), 6391049Sbinkertn@umich.edu reduce(sums, [d.samples for d in self.dist])) 6401049Sbinkertn@umich.edu else: 6411049Sbinkertn@umich.edu disttotal = FullDist( \ 6421049Sbinkertn@umich.edu reduce(sums, [d.sums for d in self.dist]), 6431049Sbinkertn@umich.edu reduce(sums, [d.squares for d in self.dist]), 6441049Sbinkertn@umich.edu reduce(sums, [d.samples for d in self.dist]), 6451049Sbinkertn@umich.edu min([d.minval for d in self.dist]), 6461049Sbinkertn@umich.edu max([d.maxval for d in self.dist]), 6471049Sbinkertn@umich.edu reduce(sums, [d.under for d in self.dist]), 6481049Sbinkertn@umich.edu reduce(sums, [d.vec for d in self.dist]), 6491049Sbinkertn@umich.edu reduce(sums, [d.over for d in self.dist]), 6501049Sbinkertn@umich.edu dist[0].min, 6511049Sbinkertn@umich.edu dist[0].max, 6521049Sbinkertn@umich.edu dist[0].bsize, 6531049Sbinkertn@umich.edu dist[0].size) 6541049Sbinkertn@umich.edu 6551049Sbinkertn@umich.edu name = '%s.total' % (self.name) 6561049Sbinkertn@umich.edu desc = self.desc 6571049Sbinkertn@umich.edu disttotal.display(name, desc, self.flags, self.precision) 6581049Sbinkertn@umich.edu 6591049Sbinkertn@umich.edu def comparable(self, other): 6601049Sbinkertn@umich.edu return self.name == other.name and \ 6611049Sbinkertn@umich.edu alltrue(map(lambda x, y : x.comparable(y), 6621049Sbinkertn@umich.edu self.dist, 6631049Sbinkertn@umich.edu other.dist)) 6641049Sbinkertn@umich.edu 6651049Sbinkertn@umich.edu def __eq__(self, other): 6661049Sbinkertn@umich.edu return alltrue(map(lambda x, y : x == y, self.dist, other.dist)) 6671049Sbinkertn@umich.edu 6681049Sbinkertn@umich.edu def __isub__(self, other): 6691547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)) and \ 6701547Sbinkertn@umich.edu isinstance(other.dist, (list, tuple)): 6711049Sbinkertn@umich.edu for sd,od in zip(self.dist, other.dist): 6721049Sbinkertn@umich.edu sd -= od 6731049Sbinkertn@umich.edu else: 6741049Sbinkertn@umich.edu self.dist -= other.dist 6751049Sbinkertn@umich.edu return self 6761049Sbinkertn@umich.edu 6771049Sbinkertn@umich.edu def __iadd__(self, other): 6781547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)) and \ 6791547Sbinkertn@umich.edu isinstance(other.dist, (list, tuple)): 6801049Sbinkertn@umich.edu for sd,od in zip(self.dist, other.dist): 6811049Sbinkertn@umich.edu sd += od 6821049Sbinkertn@umich.edu else: 6831049Sbinkertn@umich.edu self.dist += other.dist 6841049Sbinkertn@umich.edu return self 6851049Sbinkertn@umich.edu 6861049Sbinkertn@umich.edu def __itruediv__(self, other): 6871049Sbinkertn@umich.edu if not other: 6881049Sbinkertn@umich.edu return self 6891547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)): 6901049Sbinkertn@umich.edu for dist in self.dist: 6911049Sbinkertn@umich.edu dist /= other 6921049Sbinkertn@umich.edu else: 6931049Sbinkertn@umich.edu self.dist /= other 6941049Sbinkertn@umich.edu return self 6951049Sbinkertn@umich.edu 6961049Sbinkertn@umich.educlass Vector2d(Statistic): 6971049Sbinkertn@umich.edu def display(self): 6981049Sbinkertn@umich.edu import display 6991049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 7001049Sbinkertn@umich.edu return 7011049Sbinkertn@umich.edu 7021049Sbinkertn@umich.edu d = display.VectorDisplay() 7031049Sbinkertn@umich.edu d.__dict__.update(self.__dict__) 7041049Sbinkertn@umich.edu 7051049Sbinkertn@umich.edu if self.__dict__.has_key('ysubnames'): 7061049Sbinkertn@umich.edu ysubnames = list(self.ysubnames) 7071049Sbinkertn@umich.edu slack = self.x - len(ysubnames) 7081049Sbinkertn@umich.edu if slack > 0: 7091049Sbinkertn@umich.edu ysubnames.extend(['']*slack) 7101049Sbinkertn@umich.edu else: 7111049Sbinkertn@umich.edu ysubnames = range(self.x) 7121049Sbinkertn@umich.edu 7131049Sbinkertn@umich.edu for x,sname in enumerate(ysubnames): 7141049Sbinkertn@umich.edu o = x * self.y 7151049Sbinkertn@umich.edu d.value = self.value[o:o+self.y] 7161049Sbinkertn@umich.edu d.name = '%s[%s]' % (self.name, sname) 7171049Sbinkertn@umich.edu d.display() 7181049Sbinkertn@umich.edu 7191049Sbinkertn@umich.edu if self.flags & flags.total: 7201049Sbinkertn@umich.edu d.value = [] 7211049Sbinkertn@umich.edu for y in range(self.y): 7221049Sbinkertn@umich.edu xtot = 0.0 7231049Sbinkertn@umich.edu for x in range(self.x): 7241049Sbinkertn@umich.edu xtot += self.value[y + x * self.x] 7251049Sbinkertn@umich.edu d.value.append(xtot) 7261049Sbinkertn@umich.edu 7271049Sbinkertn@umich.edu d.name = self.name + '.total' 7281049Sbinkertn@umich.edu d.display() 7291049Sbinkertn@umich.edu 7301049Sbinkertn@umich.edu def comparable(self, other): 7311049Sbinkertn@umich.edu return self.name == other.name and self.x == other.x and \ 7321049Sbinkertn@umich.edu self.y == other.y 7331049Sbinkertn@umich.edu 7341049Sbinkertn@umich.edu def __eq__(self, other): 7351049Sbinkertn@umich.edu return True 7361049Sbinkertn@umich.edu 7371049Sbinkertn@umich.edu def __isub__(self, other): 7381049Sbinkertn@umich.edu return self 7391049Sbinkertn@umich.edu 7401049Sbinkertn@umich.edu def __iadd__(self, other): 7411049Sbinkertn@umich.edu return self 7421049Sbinkertn@umich.edu 7431049Sbinkertn@umich.edu def __itruediv__(self, other): 7441049Sbinkertn@umich.edu if not other: 7451049Sbinkertn@umich.edu return self 7461049Sbinkertn@umich.edu return self 7471049Sbinkertn@umich.edu 7481929Sbinkertn@umich.edudef NewStat(source, data): 7491049Sbinkertn@umich.edu stat = None 7501049Sbinkertn@umich.edu if data.type == 'SCALAR': 7511929Sbinkertn@umich.edu stat = ScalarStat() 7521049Sbinkertn@umich.edu elif data.type == 'VECTOR': 7531929Sbinkertn@umich.edu stat = VectorStat() 7541049Sbinkertn@umich.edu elif data.type == 'DIST': 7551929Sbinkertn@umich.edu stat = Dist() 7561049Sbinkertn@umich.edu elif data.type == 'VECTORDIST': 7571929Sbinkertn@umich.edu stat = VectorDist() 7581049Sbinkertn@umich.edu elif data.type == 'VECTOR2D': 7591929Sbinkertn@umich.edu stat = Vector2d() 7601049Sbinkertn@umich.edu elif data.type == 'FORMULA': 7611929Sbinkertn@umich.edu stat = Formula() 7621929Sbinkertn@umich.edu 7631929Sbinkertn@umich.edu stat.__dict__['source'] = source 7641929Sbinkertn@umich.edu stat.__dict__['bins'] = None 7651929Sbinkertn@umich.edu stat.__dict__['ticks'] = None 7661929Sbinkertn@umich.edu stat.__dict__.update(data.__dict__) 7671049Sbinkertn@umich.edu 7681049Sbinkertn@umich.edu return stat 7691049Sbinkertn@umich.edu 770