__init__.py revision 8224:75527411e636
111147Smitch.hayenga@arm.com# Copyright (c) 2008-2009 The Hewlett-Packard Development Company 213953Sgiacomo.gabrielli@arm.com# Copyright (c) 2004-2006 The Regents of The University of Michigan 311147Smitch.hayenga@arm.com# All rights reserved. 411147Smitch.hayenga@arm.com# 511147Smitch.hayenga@arm.com# Redistribution and use in source and binary forms, with or without 611147Smitch.hayenga@arm.com# modification, are permitted provided that the following conditions are 711147Smitch.hayenga@arm.com# met: redistributions of source code must retain the above copyright 811147Smitch.hayenga@arm.com# notice, this list of conditions and the following disclaimer; 911147Smitch.hayenga@arm.com# redistributions in binary form must reproduce the above copyright 1011147Smitch.hayenga@arm.com# notice, this list of conditions and the following disclaimer in the 1111147Smitch.hayenga@arm.com# documentation and/or other materials provided with the distribution; 1211147Smitch.hayenga@arm.com# neither the name of the copyright holders nor the names of its 1311147Smitch.hayenga@arm.com# contributors may be used to endorse or promote products derived from 1411147Smitch.hayenga@arm.com# this software without specific prior written permission. 1511147Smitch.hayenga@arm.com# 1611147Smitch.hayenga@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711147Smitch.hayenga@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811147Smitch.hayenga@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911147Smitch.hayenga@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011147Smitch.hayenga@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111147Smitch.hayenga@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211147Smitch.hayenga@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311147Smitch.hayenga@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411147Smitch.hayenga@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511147Smitch.hayenga@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611147Smitch.hayenga@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711147Smitch.hayenga@arm.com# 2811147Smitch.hayenga@arm.com# Authors: Nathan Binkert 2911147Smitch.hayenga@arm.com 3011147Smitch.hayenga@arm.comimport os 3111147Smitch.hayenga@arm.comimport re 3211147Smitch.hayenga@arm.comimport sys 3311147Smitch.hayenga@arm.com 3411147Smitch.hayenga@arm.comimport convert 3511147Smitch.hayenga@arm.comimport jobfile 3611147Smitch.hayenga@arm.com 3711147Smitch.hayenga@arm.comfrom attrdict import attrdict, multiattrdict, optiondict 3811147Smitch.hayenga@arm.comfrom code_formatter import code_formatter 3911147Smitch.hayenga@arm.comfrom multidict import multidict 4011147Smitch.hayenga@arm.comfrom orderdict import orderdict 4111147Smitch.hayenga@arm.comfrom smartdict import SmartDict 4211147Smitch.hayenga@arm.comfrom sorteddict import SortedDict 4311147Smitch.hayenga@arm.comfrom region import neg_inf, pos_inf, Region, Regions 4411147Smitch.hayenga@arm.com 4511147Smitch.hayenga@arm.com# define this here so we can use it right away if necessary 4611147Smitch.hayenga@arm.comdef errorURL(prefix, s): 4711147Smitch.hayenga@arm.com try: 4811147Smitch.hayenga@arm.com import zlib 4911147Smitch.hayenga@arm.com hashstr = "%x" % zlib.crc32(s) 5011147Smitch.hayenga@arm.com except: 5111147Smitch.hayenga@arm.com hashstr = "UnableToHash" 5211147Smitch.hayenga@arm.com return "For more information see: http://www.m5sim.org/%s/%s" % \ 5312104Snathanael.premillieu@arm.com (prefix, hashstr) 5411147Smitch.hayenga@arm.com 5511147Smitch.hayenga@arm.com# panic() should be called when something happens that should never 5611147Smitch.hayenga@arm.com# ever happen regardless of what the user does (i.e., an acutal m5 5711608Snikos.nikoleris@arm.com# bug). 5811147Smitch.hayenga@arm.comdef panic(fmt, *args): 5911147Smitch.hayenga@arm.com print >>sys.stderr, 'panic:', fmt % args 6011147Smitch.hayenga@arm.com print >>sys.stderr, errorURL('panic',fmt) 6111147Smitch.hayenga@arm.com sys.exit(1) 6211147Smitch.hayenga@arm.com 6312109SRekai.GonzalezAlberquilla@arm.com# fatal() should be called when the simulation cannot continue due to 6412109SRekai.GonzalezAlberquilla@arm.com# some condition that is the user's fault (bad configuration, invalid 6511147Smitch.hayenga@arm.com# arguments, etc.) and not a simulator bug. 6611147Smitch.hayenga@arm.comdef fatal(fmt, *args): 6711147Smitch.hayenga@arm.com print >>sys.stderr, 'fatal:', fmt % args 6811147Smitch.hayenga@arm.com print >>sys.stderr, errorURL('fatal',fmt) 6911147Smitch.hayenga@arm.com sys.exit(1) 7011147Smitch.hayenga@arm.com 7111147Smitch.hayenga@arm.comclass Singleton(type): 7211147Smitch.hayenga@arm.com def __call__(cls, *args, **kwargs): 7311147Smitch.hayenga@arm.com if hasattr(cls, '_instance'): 7411147Smitch.hayenga@arm.com return cls._instance 7511147Smitch.hayenga@arm.com 7611147Smitch.hayenga@arm.com cls._instance = super(Singleton, cls).__call__(*args, **kwargs) 7711147Smitch.hayenga@arm.com return cls._instance 7811147Smitch.hayenga@arm.com 7911147Smitch.hayenga@arm.comdef addToPath(path): 8011147Smitch.hayenga@arm.com """Prepend given directory to system module search path. We may not 8111147Smitch.hayenga@arm.com need this anymore if we can structure our config library more like a 8211147Smitch.hayenga@arm.com Python package.""" 8311147Smitch.hayenga@arm.com 8411147Smitch.hayenga@arm.com # if it's a relative path and we know what directory the current 8511147Smitch.hayenga@arm.com # python script is in, make the path relative to that directory. 8611147Smitch.hayenga@arm.com if not os.path.isabs(path) and sys.path[0]: 8711147Smitch.hayenga@arm.com path = os.path.join(sys.path[0], path) 8811147Smitch.hayenga@arm.com path = os.path.realpath(path) 8911147Smitch.hayenga@arm.com # sys.path[0] should always refer to the current script's directory, 9011147Smitch.hayenga@arm.com # so place the new dir right after that. 9111147Smitch.hayenga@arm.com sys.path.insert(1, path) 9211147Smitch.hayenga@arm.com 9312110SRekai.GonzalezAlberquilla@arm.com# Apply method to object. 9412110SRekai.GonzalezAlberquilla@arm.com# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>) 9512110SRekai.GonzalezAlberquilla@arm.comdef applyMethod(obj, meth, *args, **kwargs): 9611147Smitch.hayenga@arm.com return getattr(obj, meth)(*args, **kwargs) 9711147Smitch.hayenga@arm.com 9811147Smitch.hayenga@arm.com# If the first argument is an (non-sequence) object, apply the named 9911147Smitch.hayenga@arm.com# method with the given arguments. If the first argument is a 10011147Smitch.hayenga@arm.com# sequence, apply the method to each element of the sequence (a la 10111147Smitch.hayenga@arm.com# 'map'). 10211147Smitch.hayenga@arm.comdef applyOrMap(objOrSeq, meth, *args, **kwargs): 10311147Smitch.hayenga@arm.com if not isinstance(objOrSeq, (list, tuple)): 10411147Smitch.hayenga@arm.com return applyMethod(objOrSeq, meth, *args, **kwargs) 10511147Smitch.hayenga@arm.com else: 10611147Smitch.hayenga@arm.com return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] 10711147Smitch.hayenga@arm.com 10812110SRekai.GonzalezAlberquilla@arm.comdef compareVersions(v1, v2): 10912110SRekai.GonzalezAlberquilla@arm.com """helper function: compare arrays or strings of version numbers. 11012110SRekai.GonzalezAlberquilla@arm.com E.g., compare_version((1,3,25), (1,4,1)') 11111147Smitch.hayenga@arm.com returns -1, 0, 1 if v1 is <, ==, > v2 11211147Smitch.hayenga@arm.com """ 11311147Smitch.hayenga@arm.com def make_version_list(v): 11411147Smitch.hayenga@arm.com if isinstance(v, (list,tuple)): 11511147Smitch.hayenga@arm.com return v 11611147Smitch.hayenga@arm.com elif isinstance(v, str): 11711147Smitch.hayenga@arm.com return map(lambda x: int(re.match('\d+', x).group()), v.split('.')) 11811147Smitch.hayenga@arm.com else: 11912109SRekai.GonzalezAlberquilla@arm.com raise TypeError 12012109SRekai.GonzalezAlberquilla@arm.com 12112109SRekai.GonzalezAlberquilla@arm.com v1 = make_version_list(v1) 12212109SRekai.GonzalezAlberquilla@arm.com v2 = make_version_list(v2) 12313610Sgiacomo.gabrielli@arm.com # Compare corresponding elements of lists 12413610Sgiacomo.gabrielli@arm.com for n1,n2 in zip(v1, v2): 12513610Sgiacomo.gabrielli@arm.com if n1 < n2: return -1 12613610Sgiacomo.gabrielli@arm.com if n1 > n2: return 1 12711147Smitch.hayenga@arm.com # all corresponding values are equal... see if one has extra values 12811147Smitch.hayenga@arm.com if len(v1) < len(v2): return -1 12911147Smitch.hayenga@arm.com if len(v1) > len(v2): return 1 13011147Smitch.hayenga@arm.com return 0 13111147Smitch.hayenga@arm.com 13211147Smitch.hayenga@arm.comdef crossproduct(items): 13311147Smitch.hayenga@arm.com if len(items) == 1: 13411147Smitch.hayenga@arm.com for i in items[0]: 13511147Smitch.hayenga@arm.com yield (i,) 13611147Smitch.hayenga@arm.com else: 13711147Smitch.hayenga@arm.com for i in items[0]: 13811147Smitch.hayenga@arm.com for j in crossproduct(items[1:]): 13911147Smitch.hayenga@arm.com yield (i,) + j 14011147Smitch.hayenga@arm.com 14111147Smitch.hayenga@arm.comdef flatten(items): 14211147Smitch.hayenga@arm.com while items: 14311147Smitch.hayenga@arm.com item = items.pop(0) 14411147Smitch.hayenga@arm.com if isinstance(item, (list, tuple)): 14511147Smitch.hayenga@arm.com items[0:0] = item 14611147Smitch.hayenga@arm.com else: 14711147Smitch.hayenga@arm.com yield item 14811147Smitch.hayenga@arm.com 14911147Smitch.hayenga@arm.com# force scalars to one-element lists for uniformity 15011147Smitch.hayenga@arm.comdef makeList(objOrList): 15111147Smitch.hayenga@arm.com if isinstance(objOrList, list): 15211147Smitch.hayenga@arm.com return objOrList 15311147Smitch.hayenga@arm.com return [objOrList] 15411147Smitch.hayenga@arm.com 15511147Smitch.hayenga@arm.comdef printList(items, indent=4): 15611147Smitch.hayenga@arm.com line = ' ' * indent 15711147Smitch.hayenga@arm.com for i,item in enumerate(items): 15811147Smitch.hayenga@arm.com if len(line) + len(item) > 76: 15911147Smitch.hayenga@arm.com print line 16011147Smitch.hayenga@arm.com line = ' ' * indent 16111147Smitch.hayenga@arm.com 16211147Smitch.hayenga@arm.com if i < len(items) - 1: 16311147Smitch.hayenga@arm.com line += '%s, ' % item 16411147Smitch.hayenga@arm.com else: 16511147Smitch.hayenga@arm.com line += item 16611147Smitch.hayenga@arm.com print line 16711147Smitch.hayenga@arm.com 16811147Smitch.hayenga@arm.comdef readCommand(cmd, **kwargs): 16911147Smitch.hayenga@arm.com """run the command cmd, read the results and return them 17011147Smitch.hayenga@arm.com this is sorta like `cmd` in shell""" 17111147Smitch.hayenga@arm.com from subprocess import Popen, PIPE, STDOUT 17211147Smitch.hayenga@arm.com 17311147Smitch.hayenga@arm.com if isinstance(cmd, str): 17411147Smitch.hayenga@arm.com cmd = cmd.split() 17511147Smitch.hayenga@arm.com 17611147Smitch.hayenga@arm.com no_exception = 'exception' in kwargs 17713557Sgabeblack@google.com exception = kwargs.pop('exception', None) 17813557Sgabeblack@google.com 17911147Smitch.hayenga@arm.com kwargs.setdefault('shell', False) 18011147Smitch.hayenga@arm.com kwargs.setdefault('stdout', PIPE) 18112106SRekai.GonzalezAlberquilla@arm.com kwargs.setdefault('stderr', STDOUT) 18212106SRekai.GonzalezAlberquilla@arm.com kwargs.setdefault('close_fds', True) 18312106SRekai.GonzalezAlberquilla@arm.com try: 18411147Smitch.hayenga@arm.com subp = Popen(cmd, **kwargs) 18511147Smitch.hayenga@arm.com except Exception, e: 18611147Smitch.hayenga@arm.com if no_exception: 18713557Sgabeblack@google.com return exception 18813557Sgabeblack@google.com raise 18911147Smitch.hayenga@arm.com 19011147Smitch.hayenga@arm.com return subp.communicate()[0] 19112106SRekai.GonzalezAlberquilla@arm.com