fs.py revision 3322
13005Sstever@eecs.umich.edu# Copyright (c) 2006 The Regents of The University of Michigan 23005Sstever@eecs.umich.edu# All rights reserved. 33005Sstever@eecs.umich.edu# 43005Sstever@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 53005Sstever@eecs.umich.edu# modification, are permitted provided that the following conditions are 63005Sstever@eecs.umich.edu# met: redistributions of source code must retain the above copyright 73005Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 83005Sstever@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 93005Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 103005Sstever@eecs.umich.edu# documentation and/or other materials provided with the distribution; 113005Sstever@eecs.umich.edu# neither the name of the copyright holders nor the names of its 123005Sstever@eecs.umich.edu# contributors may be used to endorse or promote products derived from 133005Sstever@eecs.umich.edu# this software without specific prior written permission. 143005Sstever@eecs.umich.edu# 153005Sstever@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 163005Sstever@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 173005Sstever@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 183005Sstever@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 193005Sstever@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 203005Sstever@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 213005Sstever@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 223005Sstever@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 233005Sstever@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 243005Sstever@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 253005Sstever@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 263005Sstever@eecs.umich.edu# 273005Sstever@eecs.umich.edu# Authors: Ali Saidi 283005Sstever@eecs.umich.edu 292889SN/Aimport optparse, os, sys 302889SN/A 312710SN/Aimport m5 322710SN/Afrom m5.objects import * 332934SN/Am5.AddToPath('../common') 342934SN/Afrom FSConfig import * 352549SN/Afrom SysPaths import * 362995SN/Afrom Benchmarks import * 372549SN/A 383088Sstever@eecs.umich.eduif not m5.build_env['FULL_SYSTEM']: 393088Sstever@eecs.umich.edu m5.panic("This script requires full-system mode (ALPHA_FS).") 403088Sstever@eecs.umich.edu 412889SN/Aparser = optparse.OptionParser() 422710SN/A 433322Shsul@eecs.umich.edu# Benchmark options 442995SN/Aparser.add_option("--dual", action="store_true", 452995SN/A help="Simulate two systems attached with an ethernet link") 462995SN/Aparser.add_option("-b", "--benchmark", action="store", type="string", 472995SN/A dest="benchmark", 482995SN/A help="Specify the benchmark to run. Available benchmarks: %s"\ 493143Shsul@eecs.umich.edu % DefinedBenchmarks) 503322Shsul@eecs.umich.edu 513322Shsul@eecs.umich.edu# system options 523322Shsul@eecs.umich.eduparser.add_option("-d", "--detailed", action="store_true") 533322Shsul@eecs.umich.eduparser.add_option("-t", "--timing", action="store_true") 543322Shsul@eecs.umich.eduparser.add_option("-n", "--num_cpus", type="int", default=1) 553322Shsul@eecs.umich.eduparser.add_option("--caches", action="store_true") 563322Shsul@eecs.umich.edu 573322Shsul@eecs.umich.edu# Run duration options 583322Shsul@eecs.umich.eduparser.add_option("-m", "--maxtick", type="int") 593322Shsul@eecs.umich.eduparser.add_option("--maxtime", type="float") 603322Shsul@eecs.umich.edu 613322Shsul@eecs.umich.edu# Metafile options 623025Ssaidi@eecs.umich.eduparser.add_option("--etherdump", action="store", type="string", dest="etherdump", 633143Shsul@eecs.umich.edu help="Specify the filename to dump a pcap capture of the" \ 643143Shsul@eecs.umich.edu "ethernet traffic") 653322Shsul@eecs.umich.edu 663322Shsul@eecs.umich.edu# Checkpointing options 673322Shsul@eecs.umich.edu###Note that performing checkpointing via python script files will override 683322Shsul@eecs.umich.edu###checkpoint instructions built into binaries. 693322Shsul@eecs.umich.eduparser.add_option("--take_checkpoints", action="store", type="string", 703322Shsul@eecs.umich.edu help="<M,N> will take checkpoint at cycle M and every N cycles \ 713322Shsul@eecs.umich.edu thereafter") 723322Shsul@eecs.umich.eduparser.add_option("--max_checkpoints", action="store", type="int", 733322Shsul@eecs.umich.edu help="the maximum number of checkpoints to drop", 743322Shsul@eecs.umich.edu default=5) 753143Shsul@eecs.umich.eduparser.add_option("--checkpoint_dir", action="store", type="string", 763143Shsul@eecs.umich.edu help="Place all checkpoints in this absolute directory") 773322Shsul@eecs.umich.eduparser.add_option("-r", "--checkpoint_restore", action="store", type="int", 783183Shsul@eecs.umich.edu help="restore from checkpoint <N>") 792710SN/A 803322Shsul@eecs.umich.edu# CPU Switching - default switch model goes from a checkpoint 813322Shsul@eecs.umich.edu# to a timing simple CPU with caches to warm up, then to detailed CPU for 823322Shsul@eecs.umich.edu# data measurement 833322Shsul@eecs.umich.eduparser.add_option("-s", "--standard_switch", action="store_true", 843322Shsul@eecs.umich.edu help="switch from one cpu mode to another") 853322Shsul@eecs.umich.edu 862710SN/A(options, args) = parser.parse_args() 872710SN/A 882710SN/Aif args: 892710SN/A print "Error: script doesn't take any positional arguments" 902710SN/A sys.exit(1) 912710SN/A 923314Sstever@eecs.umich.educlass MyCache(BaseCache): 933314Sstever@eecs.umich.edu assoc = 2 943314Sstever@eecs.umich.edu block_size = 64 953314Sstever@eecs.umich.edu latency = 1 963314Sstever@eecs.umich.edu mshrs = 10 973314Sstever@eecs.umich.edu tgts_per_mshr = 5 983314Sstever@eecs.umich.edu 993322Shsul@eecs.umich.edu# driver system CPU is always simple... note this is an assignment of 1003304Sstever@eecs.umich.edu# a class, not an instance. 1013322Shsul@eecs.umich.eduDriveCPUClass = AtomicSimpleCPU 1023322Shsul@eecs.umich.edudrive_mem_mode = 'atomic' 1033304Sstever@eecs.umich.edu 1043322Shsul@eecs.umich.edu# system under test can be any of these CPUs 1052934SN/Aif options.detailed: 1063322Shsul@eecs.umich.edu TestCPUClass = DerivO3CPU 1073322Shsul@eecs.umich.edu test_mem_mode = 'timing' 1082934SN/Aelif options.timing: 1093322Shsul@eecs.umich.edu TestCPUClass = TimingSimpleCPU 1103322Shsul@eecs.umich.edu test_mem_mode = 'timing' 1112934SN/Aelse: 1123322Shsul@eecs.umich.edu TestCPUClass = AtomicSimpleCPU 1133322Shsul@eecs.umich.edu test_mem_mode = 'atomic' 1142566SN/A 1153322Shsul@eecs.umich.eduTestCPUClass.clock = '2GHz' 1163322Shsul@eecs.umich.eduDriveCPUClass.clock = '2GHz' 1172995SN/A 1182995SN/Aif options.benchmark: 1193304Sstever@eecs.umich.edu try: 1203304Sstever@eecs.umich.edu bm = Benchmarks[options.benchmark] 1213304Sstever@eecs.umich.edu except KeyError: 1222995SN/A print "Error benchmark %s has not been defined." % options.benchmark 1232995SN/A print "Valid benchmarks are: %s" % DefinedBenchmarks 1242995SN/A sys.exit(1) 1252917SN/Aelse: 1262995SN/A if options.dual: 1273304Sstever@eecs.umich.edu bm = [SysConfig(), SysConfig()] 1282995SN/A else: 1293304Sstever@eecs.umich.edu bm = [SysConfig()] 1303304Sstever@eecs.umich.edu 1313322Shsul@eecs.umich.edutest_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0]) 1323312Sstever@eecs.umich.edunp = options.num_cpus 1333322Shsul@eecs.umich.edutest_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)] 1343312Sstever@eecs.umich.edufor i in xrange(np): 1353322Shsul@eecs.umich.edu if options.caches and not options.standard_switch: 1363322Shsul@eecs.umich.edu test_sys.cpu[i].addPrivateSplitL1Caches(MyCache(size = '32kB'), 1373314Sstever@eecs.umich.edu MyCache(size = '64kB')) 1383322Shsul@eecs.umich.edu test_sys.cpu[i].connectMemPorts(test_sys.membus) 1393322Shsul@eecs.umich.edu test_sys.cpu[i].mem = test_sys.physmem 1403005Sstever@eecs.umich.edu 1413005Sstever@eecs.umich.eduif len(bm) == 2: 1423322Shsul@eecs.umich.edu drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1]) 1433322Shsul@eecs.umich.edu drive_sys.cpu = DriveCPUClass(cpu_id=0) 1443322Shsul@eecs.umich.edu drive_sys.cpu.connectMemPorts(drive_sys.membus) 1453322Shsul@eecs.umich.edu drive_sys.cpu.mem = drive_sys.physmem 1463322Shsul@eecs.umich.edu root = makeDualRoot(test_sys, drive_sys, options.etherdump) 1473005Sstever@eecs.umich.eduelif len(bm) == 1: 1483322Shsul@eecs.umich.edu root = Root(clock = '1THz', system = test_sys) 1493005Sstever@eecs.umich.eduelse: 1503005Sstever@eecs.umich.edu print "Error I don't know how to create more than 2 systems." 1513005Sstever@eecs.umich.edu sys.exit(1) 1522566SN/A 1533322Shsul@eecs.umich.eduif options.standard_switch: 1543322Shsul@eecs.umich.edu switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i) for i in xrange(np))] 1553322Shsul@eecs.umich.edu switch_cpus1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i) for i in xrange(np))] 1563322Shsul@eecs.umich.edu for i in xrange(np): 1573322Shsul@eecs.umich.edu switch_cpus[i].system = test_sys 1583322Shsul@eecs.umich.edu switch_cpus1[i].system = test_sys 1593322Shsul@eecs.umich.edu switch_cpus[i].clock = TestCPUClass.clock 1603322Shsul@eecs.umich.edu switch_cpus1[i].clock = TestCPUClass.clock 1613322Shsul@eecs.umich.edu if options.caches: 1623322Shsul@eecs.umich.edu switch_cpus[i].addPrivateSplitL1Caches(MyCache(size = '32kB'), 1633322Shsul@eecs.umich.edu MyCache(size = '64kB')) 1643322Shsul@eecs.umich.edu 1653322Shsul@eecs.umich.edu switch_cpus[i].mem = test_sys.physmem 1663322Shsul@eecs.umich.edu switch_cpus1[i].mem = test_sys.physmem 1673322Shsul@eecs.umich.edu switch_cpus[i].connectMemPorts(test_sys.membus) 1683322Shsul@eecs.umich.edu root.switch_cpus = switch_cpus 1693322Shsul@eecs.umich.edu root.switch_cpus1 = switch_cpus1 1703322Shsul@eecs.umich.edu switch_cpu_list = [(test_sys.cpu[i], switch_cpus[i]) for i in xrange(np)] 1713322Shsul@eecs.umich.edu switch_cpu_list1 = [(switch_cpus[i], switch_cpus1[i]) for i in xrange(np)] 1723322Shsul@eecs.umich.edu 1732710SN/Am5.instantiate(root) 1742710SN/A 1753322Shsul@eecs.umich.eduif options.checkpoint_dir: 1763322Shsul@eecs.umich.edu cptdir = options.checkpoint_dir 1773322Shsul@eecs.umich.eduelse: 1783322Shsul@eecs.umich.edu cptdir = getcwd() 1793322Shsul@eecs.umich.edu 1803322Shsul@eecs.umich.eduif options.checkpoint_restore: 1813183Shsul@eecs.umich.edu from os.path import isdir 1823183Shsul@eecs.umich.edu from os import listdir, getcwd 1833183Shsul@eecs.umich.edu import re 1843183Shsul@eecs.umich.edu 1853183Shsul@eecs.umich.edu if not isdir(cptdir): 1863183Shsul@eecs.umich.edu m5.panic("checkpoint dir %s does not exist!" % cptdir) 1873183Shsul@eecs.umich.edu 1883183Shsul@eecs.umich.edu dirs = listdir(cptdir) 1893183Shsul@eecs.umich.edu expr = re.compile('cpt.([0-9]*)') 1903183Shsul@eecs.umich.edu cpts = [] 1913183Shsul@eecs.umich.edu for dir in dirs: 1923183Shsul@eecs.umich.edu match = expr.match(dir) 1933183Shsul@eecs.umich.edu if match: 1943183Shsul@eecs.umich.edu cpts.append(match.group(1)) 1953183Shsul@eecs.umich.edu 1963322Shsul@eecs.umich.edu cpts.sort(lambda a,b: cmp(long(a), long(b))) 1973183Shsul@eecs.umich.edu 1983322Shsul@eecs.umich.edu if options.checkpoint_restore > len(cpts): 1993322Shsul@eecs.umich.edu m5.panic('Checkpoint %d not found' % options.checkpoint_restore) 2003322Shsul@eecs.umich.edu 2013322Shsul@eecs.umich.edu m5.restoreCheckpoint(root, "/".join([cptdir, "cpt.%s" % cpts[options.checkpoint_restore - 1]])) 2023322Shsul@eecs.umich.edu 2033322Shsul@eecs.umich.eduif options.standard_switch: 2043322Shsul@eecs.umich.edu exit_event = m5.simulate(1000) 2053322Shsul@eecs.umich.edu ## when you change to Timing (or Atomic), you halt the system given 2063322Shsul@eecs.umich.edu ## as argument. When you are finished with the system changes 2073322Shsul@eecs.umich.edu ## (including switchCpus), you must resume the system manually. 2083322Shsul@eecs.umich.edu ## You DON'T need to resume after just switching CPUs if you haven't 2093322Shsul@eecs.umich.edu ## changed anything on the system level. 2103322Shsul@eecs.umich.edu m5.changeToTiming(test_sys) 2113322Shsul@eecs.umich.edu m5.switchCpus(switch_cpu_list) 2123322Shsul@eecs.umich.edu m5.resume(test_sys) 2133322Shsul@eecs.umich.edu 2143322Shsul@eecs.umich.edu exit_event = m5.simulate(300000000000) 2153322Shsul@eecs.umich.edu m5.switchCpus(switch_cpu_list1) 2163183Shsul@eecs.umich.edu 2172917SN/Aif options.maxtick: 2183046Sstever@eecs.umich.edu maxtick = options.maxtick 2192948SN/Aelif options.maxtime: 2202948SN/A simtime = int(options.maxtime * root.clock.value) 2212948SN/A print "simulating for: ", simtime 2223046Sstever@eecs.umich.edu maxtick = simtime 2232917SN/Aelse: 2243046Sstever@eecs.umich.edu maxtick = -1 2253022Shsul@eecs.umich.edu 2263322Shsul@eecs.umich.edunum_checkpoints = 0 2273022Shsul@eecs.umich.edu 2283322Shsul@eecs.umich.eduexit_cause = '' 2293143Shsul@eecs.umich.edu 2303322Shsul@eecs.umich.eduif options.take_checkpoints: 2313322Shsul@eecs.umich.edu [when, period] = options.take_checkpoints.split(",", 1) 2323322Shsul@eecs.umich.edu when = int(when) 2333322Shsul@eecs.umich.edu period = int(period) 2342710SN/A 2353322Shsul@eecs.umich.edu exit_event = m5.simulate(when) 2363322Shsul@eecs.umich.edu while exit_event.getCause() == "checkpoint": 2373322Shsul@eecs.umich.edu exit_event = m5.simulate(when - m5.curTick()) 2383322Shsul@eecs.umich.edu 2393322Shsul@eecs.umich.edu if exit_event.getCause() == "simulate() limit reached": 2403322Shsul@eecs.umich.edu m5.checkpoint(root, cptdir + "cpt.%d") 2413322Shsul@eecs.umich.edu num_checkpoints += 1 2423322Shsul@eecs.umich.edu 2433322Shsul@eecs.umich.edu sim_ticks = when 2443322Shsul@eecs.umich.edu exit_cause = "maximum %d checkpoints dropped" % options.max_checkpoints 2453322Shsul@eecs.umich.edu while num_checkpoints < options.max_checkpoints: 2463322Shsul@eecs.umich.edu if (sim_ticks + period) > maxtick and maxtick != -1: 2473322Shsul@eecs.umich.edu exit_event = m5.simulate(maxtick - sim_ticks) 2483322Shsul@eecs.umich.edu exit_cause = exit_event.getCause() 2493322Shsul@eecs.umich.edu break 2503322Shsul@eecs.umich.edu else: 2513322Shsul@eecs.umich.edu exit_event = m5.simulate(period) 2523322Shsul@eecs.umich.edu sim_ticks += period 2533322Shsul@eecs.umich.edu while exit_event.getCause() == "checkpoint": 2543322Shsul@eecs.umich.edu exit_event = m5.simulate(period - m5.curTick()) 2553322Shsul@eecs.umich.edu if exit_event.getCause() == "simulate() limit reached": 2563322Shsul@eecs.umich.edu m5.checkpoint(root, cptdir + "cpt.%d") 2573322Shsul@eecs.umich.edu num_checkpoints += 1 2583322Shsul@eecs.umich.edu 2593322Shsul@eecs.umich.eduelse: #no checkpoints being taken via this script 2603322Shsul@eecs.umich.edu exit_event = m5.simulate(maxtick) 2613322Shsul@eecs.umich.edu 2623322Shsul@eecs.umich.edu while exit_event.getCause() == "checkpoint": 2633322Shsul@eecs.umich.edu m5.checkpoint(root, cptdir + "cpt.%d") 2643322Shsul@eecs.umich.edu num_checkpoints += 1 2653322Shsul@eecs.umich.edu if num_checkpoints == options.max_checkpoints: 2663322Shsul@eecs.umich.edu exit_cause = "maximum %d checkpoints dropped" % options.max_checkpoints 2673322Shsul@eecs.umich.edu break 2683322Shsul@eecs.umich.edu 2693322Shsul@eecs.umich.edu if maxtick == -1: 2703322Shsul@eecs.umich.edu exit_event = m5.simulate(maxtick) 2713322Shsul@eecs.umich.edu else: 2723322Shsul@eecs.umich.edu exit_event = m5.simulate(maxtick - m5.curTick()) 2733322Shsul@eecs.umich.edu 2743322Shsul@eecs.umich.edu exit_cause = exit_event.getCause() 2753322Shsul@eecs.umich.edu 2763322Shsul@eecs.umich.eduif exit_cause == '': 2773322Shsul@eecs.umich.edu exit_cause = exit_event.getCause() 2783322Shsul@eecs.umich.eduprint 'Exiting @ cycle', m5.curTick(), 'because ', exit_cause 279