db.py

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

PY
436
字号
# Copyright (c) 2003, 2004# 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: Nathan L. Binkertimport MySQLdb, re, stringdef statcmp(a, b):    v1 = a.split('.')    v2 = b.split('.')    last = min(len(v1), len(v2)) - 1    for i,j in zip(v1[0:last], v2[0:last]):        if i != j:            return cmp(i, j)    # Special compare for last element.    if len(v1) == len(v2):        return cmp(v1[last], v2[last])    else:        return cmp(len(v1), len(v2))class RunData:    def __init__(self, row):        self.run = int(row[0])        self.name = row[1]        self.user = row[2]        self.project = row[3]class SubData:    def __init__(self, row):        self.stat = int(row[0])        self.x = int(row[1])        self.y = int(row[2])        self.name = row[3]        self.descr = row[4]class Data:    def __init__(self, row):        if len(row) != 5:            raise 'stat db error'        self.stat = int(row[0])        self.run = int(row[1])        self.x = int(row[2])        self.y = int(row[3])        self.data = float(row[4])    def __repr__(self):        return '''Data(['%d', '%d', '%d', '%d', '%f'])''' % ( self.stat,            self.run, self.x, self.y, self.data)class StatData(object):    def __init__(self, row):        self.stat = int(row[0])        self.name = row[1]        self.desc = row[2]        self.type = row[3]        self.prereq = int(row[5])        self.precision = int(row[6])        import flags        self.flags = 0        if int(row[4]): self.flags |= flags.printable        if int(row[7]): self.flags |= flags.nozero        if int(row[8]): self.flags |= flags.nonan        if int(row[9]): self.flags |= flags.total        if int(row[10]): self.flags |= flags.pdf        if int(row[11]): self.flags |= flags.cdf        if self.type == 'DIST' or self.type == 'VECTORDIST':            self.min = float(row[12])            self.max = float(row[13])            self.bktsize = float(row[14])            self.size = int(row[15])        if self.type == 'FORMULA':            self.formula = self.db.allFormulas[self.stat]class Node(object):    def __init__(self, name):        self.name = name    def __str__(self):        return self.nameclass Result(object):    def __init__(self, x, y):        self.data = {}        self.x = x        self.y = y    def __contains__(self, run):        return run in self.data    def __getitem__(self, run):        if run not in self.data:            self.data[run] = [ [ 0.0 ] * self.y for i in xrange(self.x) ]        return self.data[run]class Database(object):    def __init__(self):        self.host = 'zizzer.pool'        self.user = ''        self.passwd = ''        self.db = 'm5stats'        self.cursor = None        self.allStats = []        self.allStatIds = {}        self.allStatNames = {}        self.allSubData = {}        self.allRuns = []        self.allRunIds = {}        self.allRunNames = {}        self.allFormulas = {}        self.stattop = {}        self.statdict = {}        self.statlist = []        self.mode = 'sum';        self.runs = None        self.ticks = None        self.method = 'sum'        self._method = type(self).sum    def get(self, job, stat, system=None):        run = self.allRunNames.get(str(job), None)        if run is None:            return None        from info import ProxyError, scalar, vector, value, values, total, len        if system is None and hasattr(job, 'system'):            system = job.system        if system is not None:            stat.system = self[system]        try:            if scalar(stat):                return value(stat, run.run)            if vector(stat):                return values(stat, run.run)        except ProxyError:            return None        return None    def query(self, sql):        self.cursor.execute(sql)    def update_dict(self, dict):        dict.update(self.stattop)    def append(self, stat):        statname = re.sub(':', '__', stat.name)        path = string.split(statname, '.')        pathtop = path[0]        fullname = ''        x = self        while len(path) > 1:            name = path.pop(0)            if not x.__dict__.has_key(name):                x.__dict__[name] = Node(fullname + name)            x = x.__dict__[name]            fullname = '%s%s.' % (fullname, name)        name = path.pop(0)        x.__dict__[name] = stat        self.stattop[pathtop] = self.__dict__[pathtop]        self.statdict[statname] = stat        self.statlist.append(statname)    def connect(self):        # connect        self.thedb = MySQLdb.connect(db=self.db,                                     host=self.host,                                     user=self.user,                                     passwd=self.passwd)        # create a cursor        self.cursor = self.thedb.cursor()        self.query('''select rn_id,rn_name,rn_sample,rn_user,rn_project                   from runs''')        for result in self.cursor.fetchall():            run = RunData(result);            self.allRuns.append(run)            self.allRunIds[run.run] = run            self.allRunNames[run.name] = run        self.query('select sd_stat,sd_x,sd_y,sd_name,sd_descr from subdata')        for result in self.cursor.fetchall():            subdata = SubData(result)            if self.allSubData.has_key(subdata.stat):                self.allSubData[subdata.stat].append(subdata)            else:                self.allSubData[subdata.stat] = [ subdata ]        self.query('select * from formulas')        for id,formula in self.cursor.fetchall():            self.allFormulas[int(id)] = formula.tostring()        StatData.db = self        self.query('select * from stats')        import info        for result in self.cursor.fetchall():            stat = info.NewStat(self, StatData(result))            self.append(stat)            self.allStats.append(stat)            self.allStatIds[stat.stat] = stat            self.allStatNames[stat.name] = stat    # Name: listruns    # Desc: Prints all runs matching a given user, if no argument    #       is given all runs are returned    def listRuns(self, user=None):        print '%-40s %-10s %-5s' % ('run name', 'user', 'id')        print '-' * 62        for run in self.allRuns:            if user == None or user == run.user:                print '%-40s %-10s %-10d' % (run.name, run.user, run.run)    # Name: listTicks    # Desc: Prints all samples for a given run    def listTicks(self, runs=None):        print "tick"        print "----------------------------------------"        sql = 'select distinct dt_tick from data where dt_stat=1180 and ('        if runs != None:            first = True            for run in runs:               if first:            #       sql += ' where'                   first = False               else:                   sql += ' or'               sql += ' dt_run=%s' % run.run            sql += ')'        self.query(sql)        for r in self.cursor.fetchall():            print r[0]    # Name: retTicks    # Desc: Prints all samples for a given run    def retTicks(self, runs=None):        sql = 'select distinct dt_tick from data where dt_stat=1180 and ('        if runs != None:            first = True            for run in runs:               if first:                   first = False               else:                   sql += ' or'               sql += ' dt_run=%s' % run.run            sql += ')'        self.query(sql)        ret = []        for r in self.cursor.fetchall():            ret.append(r[0])        return ret    # Name: liststats    # Desc: Prints all statistics that appear in the database,    #         the optional argument is a regular expression that can    #         be used to prune the result set    def listStats(self, regex=None):        print '%-60s %-8s %-10s' % ('stat name', 'id', 'type')        print '-' * 80        rx = None        if regex != None:            rx = re.compile(regex)        stats = [ stat.name for stat in self.allStats ]        stats.sort(statcmp)        for stat in stats:            stat = self.allStatNames[stat]            if rx == None or rx.match(stat.name):                print '%-60s %-8s %-10s' % (stat.name, stat.stat, stat.type)    # Name: liststats    # Desc: Prints all statistics that appear in the database,    #         the optional argument is a regular expression that can    #         be used to prune the result set    def listFormulas(self, regex=None):        print '%-60s %s' % ('formula name', 'formula')        print '-' * 80        rx = None        if regex != None:            rx = re.compile(regex)        stats = [ stat.name for stat in self.allStats ]        stats.sort(statcmp)        for stat in stats:            stat = self.allStatNames[stat]            if stat.type == 'FORMULA' and (rx == None or rx.match(stat.name)):                print '%-60s %s' % (stat.name, self.allFormulas[stat.stat])    def getStat(self, stats):        if type(stats) is not list:            stats = [ stats ]        ret = []        for stat in stats:            if type(stat) is int:                ret.append(self.allStatIds[stat])            if type(stat) is str:                rx = re.compile(stat)                for stat in self.allStats:                    if rx.match(stat.name):                        ret.append(stat)        return ret    #########################################    # get the data    #    def query(self, op, stat, ticks, group=False):        sql = 'select '        sql += 'dt_stat as stat, '        sql += 'dt_run as run, '        sql += 'dt_x as x, '        sql += 'dt_y as y, '        if group:            sql += 'dt_tick as tick, '        sql += '%s(dt_data) as data ' % op        sql += 'from data '        sql += 'where '        if isinstance(stat, list):            val = ' or '.join([ 'dt_stat=%d' % s.stat for s in stat ])            sql += ' (%s)' % val        else:            sql += ' dt_stat=%d' % stat.stat        if self.runs != None and len(self.runs):            val = ' or '.join([ 'dt_run=%d' % r for r in self.runs ])            sql += ' and (%s)' % val        if ticks != None and len(ticks):            val = ' or '.join([ 'dt_tick=%d' % s for s in ticks ])            sql += ' and (%s)' % val        sql += ' group by dt_stat,dt_run,dt_x,dt_y'        if group:            sql += ',dt_tick'        return sql    # Name: sum    # Desc: given a run, a stat and an array of samples, total the samples    def sum(self, *args, **kwargs):        return self.query('sum', *args, **kwargs)    # Name: avg    # Desc: given a run, a stat and an array of samples, average the samples    def avg(self, stat, ticks):        return self.query('avg', *args, **kwargs)    # Name: stdev    # Desc: given a run, a stat and an array of samples, get the standard    #       deviation    def stdev(self, stat, ticks):        return self.query('stddev', *args, **kwargs)    def __setattr__(self, attr, value):        super(Database, self).__setattr__(attr, value)        if attr != 'method':            return        if value == 'sum':            self._method = self.sum        elif value == 'avg':            self._method = self.avg        elif value == 'stdev':            self._method = self.stdev        else:            raise AttributeError, "can only set get to: sum | avg | stdev"    def data(self, stat, ticks=None):        if ticks is None:            ticks = self.ticks        sql = self._method(self, stat, ticks)        self.query(sql)        runs = {}        xmax = 0        ymax = 0        for x in self.cursor.fetchall():            data = Data(x)            if not runs.has_key(data.run):                runs[data.run] = {}            if not runs[data.run].has_key(data.x):                runs[data.run][data.x] = {}            xmax = max(xmax, data.x)            ymax = max(ymax, data.y)            runs[data.run][data.x][data.y] = data.data        results = Result(xmax + 1, ymax + 1)        for run,data in runs.iteritems():            result = results[run]            for x,ydata in data.iteritems():                for y,data in ydata.iteritems():                    result[x][y] = data        return results    def __getitem__(self, key):        return self.stattop[key]

⌨️ 快捷键说明

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