__init__.py revision 8224
14312SN/A# Copyright (c) 2008-2009 The Hewlett-Packard Development Company 24312SN/A# Copyright (c) 2004-2006 The Regents of The University of Michigan 34312SN/A# All rights reserved. 410036SN/A# 58835SN/A# Redistribution and use in source and binary forms, with or without 610036SN/A# modification, are permitted provided that the following conditions are 77935SN/A# met: redistributions of source code must retain the above copyright 87935SN/A# notice, this list of conditions and the following disclaimer; 97935SN/A# redistributions in binary form must reproduce the above copyright 104312SN/A# notice, this list of conditions and the following disclaimer in the 114312SN/A# documentation and/or other materials provided with the distribution; 124312SN/A# neither the name of the copyright holders nor the names of its 1310315SN/A# contributors may be used to endorse or promote products derived from 148835SN/A# this software without specific prior written permission. 159885SN/A# 169885SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710036SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 188835SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 198835SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010315SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 218835SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210315SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239481SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249481SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258625SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611066Snilay@cs.wisc.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711219Snilay@cs.wisc.edu# 288721SN/A# Authors: Nathan Binkert 298835SN/A 308835SN/Aimport os 317935SN/Aimport re 327935SN/Aimport sys 337935SN/A 347935SN/Aimport convert 357935SN/Aimport jobfile 367935SN/A 377935SN/Afrom attrdict import attrdict, multiattrdict, optiondict 388983SN/Afrom code_formatter import code_formatter 394312SN/Afrom multidict import multidict 409885SN/Afrom orderdict import orderdict 419885SN/Afrom smartdict import SmartDict 429885SN/Afrom sorteddict import SortedDict 4310315SN/Afrom region import neg_inf, pos_inf, Region, Regions 4410036SN/A 4510315SN/A# define this here so we can use it right away if necessary 469885SN/Adef errorURL(prefix, s): 479885SN/A try: 484312SN/A import zlib 494312SN/A hashstr = "%x" % zlib.crc32(s) 509481SN/A except: 5110315SN/A hashstr = "UnableToHash" 525876SN/A return "For more information see: http://www.m5sim.org/%s/%s" % \ 539885SN/A (prefix, hashstr) 544312SN/A 555876SN/A# panic() should be called when something happens that should never 568835SN/A# ever happen regardless of what the user does (i.e., an acutal m5 575876SN/A# bug). 585000SN/Adef panic(fmt, *args): 5910036SN/A print >>sys.stderr, 'panic:', fmt % args 604312SN/A print >>sys.stderr, errorURL('panic',fmt) 614312SN/A sys.exit(1) 628835SN/A 639481SN/A# fatal() should be called when the simulation cannot continue due to 645000SN/A# some condition that is the user's fault (bad configuration, invalid 654312SN/A# arguments, etc.) and not a simulator bug. 664312SN/Adef fatal(fmt, *args): 674312SN/A print >>sys.stderr, 'fatal:', fmt % args 684312SN/A print >>sys.stderr, errorURL('fatal',fmt) 695575SN/A sys.exit(1) 708835SN/A 714312SN/Aclass Singleton(type): 729885SN/A def __call__(cls, *args, **kwargs): 7310315SN/A if hasattr(cls, '_instance'): 749481SN/A return cls._instance 754312SN/A 764971SN/A cls._instance = super(Singleton, cls).__call__(*args, **kwargs) 774312SN/A return cls._instance 784312SN/A 794312SN/Adef addToPath(path): 804312SN/A """Prepend given directory to system module search path. We may not 814312SN/A need this anymore if we can structure our config library more like a 8211066Snilay@cs.wisc.edu Python package.""" 839885SN/A 848983SN/A # if it's a relative path and we know what directory the current 854312SN/A # python script is in, make the path relative to that directory. 869885SN/A if not os.path.isabs(path) and sys.path[0]: 8711219Snilay@cs.wisc.edu path = os.path.join(sys.path[0], path) 8811066Snilay@cs.wisc.edu path = os.path.realpath(path) 8910036SN/A # sys.path[0] should always refer to the current script's directory, 906123SN/A # so place the new dir right after that. 919481SN/A sys.path.insert(1, path) 9211066Snilay@cs.wisc.edu 934312SN/A# Apply method to object. 949481SN/A# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>) 955876SN/Adef applyMethod(obj, meth, *args, **kwargs): 968835SN/A return getattr(obj, meth)(*args, **kwargs) 979481SN/A 9810036SN/A# If the first argument is an (non-sequence) object, apply the named 994312SN/A# method with the given arguments. If the first argument is a 1008835SN/A# sequence, apply the method to each element of the sequence (a la 1019885SN/A# 'map'). 1029481SN/Adef applyOrMap(objOrSeq, meth, *args, **kwargs): 1034312SN/A if not isinstance(objOrSeq, (list, tuple)): 10411219Snilay@cs.wisc.edu return applyMethod(objOrSeq, meth, *args, **kwargs) 1054312SN/A else: 1068983SN/A return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] 1074312SN/A 1089885SN/Adef compareVersions(v1, v2): 1099885SN/A """helper function: compare arrays or strings of version numbers. 1109885SN/A E.g., compare_version((1,3,25), (1,4,1)') 1119885SN/A returns -1, 0, 1 if v1 is <, ==, > v2 1129885SN/A """ 11310036SN/A def make_version_list(v): 1149885SN/A if isinstance(v, (list,tuple)): 11510036SN/A return v 1169885SN/A elif isinstance(v, str): 1179885SN/A return map(lambda x: int(re.match('\d+', x).group()), v.split('.')) 1185000SN/A else: 1196024SN/A raise TypeError 12010036SN/A 1215000SN/A v1 = make_version_list(v1) 1225000SN/A v2 = make_version_list(v2) 1234312SN/A # Compare corresponding elements of lists 12411066Snilay@cs.wisc.edu for n1,n2 in zip(v1, v2): 1259885SN/A if n1 < n2: return -1 1268983SN/A if n1 > n2: return 1 1274312SN/A # all corresponding values are equal... see if one has extra values 1289885SN/A if len(v1) < len(v2): return -1 12911219Snilay@cs.wisc.edu if len(v1) > len(v2): return 1 13011066Snilay@cs.wisc.edu return 0 13110036SN/A 1326123SN/Adef crossproduct(items): 1339481SN/A if len(items) == 1: 13411066Snilay@cs.wisc.edu for i in items[0]: 1354312SN/A yield (i,) 1369481SN/A else: 1375876SN/A for i in items[0]: 1388835SN/A for j in crossproduct(items[1:]): 1399481SN/A yield (i,) + j 14010036SN/A 1414312SN/Adef flatten(items): 1428835SN/A while items: 1439885SN/A item = items.pop(0) 1449481SN/A if isinstance(item, (list, tuple)): 1454312SN/A items[0:0] = item 14611219Snilay@cs.wisc.edu else: 1474312SN/A yield item 1488983SN/A 1494312SN/A# force scalars to one-element lists for uniformity 1509885SN/Adef makeList(objOrList): 1519885SN/A if isinstance(objOrList, list): 1529885SN/A return objOrList 1539885SN/A return [objOrList] 1549885SN/A 15510036SN/Adef printList(items, indent=4): 1569885SN/A line = ' ' * indent 15710036SN/A for i,item in enumerate(items): 1589885SN/A if len(line) + len(item) > 76: 1599885SN/A print line 1608835SN/A line = ' ' * indent 1618835SN/A 16210036SN/A if i < len(items) - 1: 1638835SN/A line += '%s, ' % item 1649481SN/A else: 1659481SN/A line += item 16610036SN/A print line 1679481SN/A 1685000SN/Adef readCommand(cmd, **kwargs): 1696024SN/A """run the command cmd, read the results and return them 17010036SN/A this is sorta like `cmd` in shell""" 1715000SN/A from subprocess import Popen, PIPE, STDOUT 1725000SN/A 1734312SN/A if isinstance(cmd, str): 17411066Snilay@cs.wisc.edu cmd = cmd.split() 1759885SN/A 1768983SN/A no_exception = 'exception' in kwargs 1779481SN/A exception = kwargs.pop('exception', None) 1789885SN/A 17911219Snilay@cs.wisc.edu kwargs.setdefault('shell', False) 18011066Snilay@cs.wisc.edu kwargs.setdefault('stdout', PIPE) 18110036SN/A kwargs.setdefault('stderr', STDOUT) 1826123SN/A kwargs.setdefault('close_fds', True) 1839481SN/A try: 18411066Snilay@cs.wisc.edu subp = Popen(cmd, **kwargs) 1854312SN/A except Exception, e: 1869481SN/A if no_exception: 1875876SN/A return exception 1888835SN/A raise 1899481SN/A 19010036SN/A return subp.communicate()[0] 1914312SN/A