Simulation.py revision 11688
1955SN/A# Copyright (c) 2012-2013 ARM Limited 2955SN/A# All rights reserved 31762SN/A# 4955SN/A# The license below extends only to copyright in the software and shall 5955SN/A# not be construed as granting a license to any other intellectual 6955SN/A# property including but not limited to intellectual property relating 7955SN/A# to a hardware implementation of the functionality of the software 8955SN/A# licensed hereunder. You may use the software subject to the license 9955SN/A# terms below provided that you ensure that this notice is replicated 10955SN/A# unmodified and in its entirety in all distributions of the software, 11955SN/A# modified or unmodified, in source code or in binary form. 12955SN/A# 13955SN/A# Copyright (c) 2006-2008 The Regents of The University of Michigan 14955SN/A# Copyright (c) 2010 Advanced Micro Devices, Inc. 15955SN/A# All rights reserved. 16955SN/A# 17955SN/A# Redistribution and use in source and binary forms, with or without 18955SN/A# modification, are permitted provided that the following conditions are 19955SN/A# met: redistributions of source code must retain the above copyright 20955SN/A# notice, this list of conditions and the following disclaimer; 21955SN/A# redistributions in binary form must reproduce the above copyright 22955SN/A# notice, this list of conditions and the following disclaimer in the 23955SN/A# documentation and/or other materials provided with the distribution; 24955SN/A# neither the name of the copyright holders nor the names of its 25955SN/A# contributors may be used to endorse or promote products derived from 26955SN/A# this software without specific prior written permission. 27955SN/A# 282665Ssaidi@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 294762Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30955SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 315522Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 326143Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 334762Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 345522Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35955SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 365522Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37955SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 385522Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 394202Sbinkertn@umich.edu# 405742Snate@binkert.org# Authors: Lisa Hsu 41955SN/A 424381Sbinkertn@umich.eduimport sys 434381Sbinkertn@umich.edufrom os import getcwd 448334Snate@binkert.orgfrom os.path import join as joinpath 45955SN/A 46955SN/Afrom common import CpuConfig 474202Sbinkertn@umich.edufrom common import MemConfig 48955SN/A 494382Sbinkertn@umich.eduimport m5 504382Sbinkertn@umich.edufrom m5.defines import buildEnv 514382Sbinkertn@umich.edufrom m5.objects import * 526654Snate@binkert.orgfrom m5.util import * 535517Snate@binkert.org 548614Sgblack@eecs.umich.eduaddToPath('../common') 557674Snate@binkert.org 566143Snate@binkert.orgdef getCPUClass(cpu_type): 576143Snate@binkert.org """Returns the required cpu class and the mode of operation.""" 586143Snate@binkert.org cls = CpuConfig.get(cpu_type) 598233Snate@binkert.org return cls, cls.memory_mode() 608233Snate@binkert.org 618233Snate@binkert.orgdef setCPUClass(options): 628233Snate@binkert.org """Returns two cpu classes and the initial mode of operation. 638233Snate@binkert.org 648334Snate@binkert.org Restoring from a checkpoint or fast forwarding through a benchmark 658334Snate@binkert.org can be done using one type of cpu, and then the actual 6610453SAndrew.Bardsley@arm.com simulation can be carried out using another type. This function 6710453SAndrew.Bardsley@arm.com returns these two types of cpus and the initial mode of operation 688233Snate@binkert.org depending on the options provided. 698233Snate@binkert.org """ 708233Snate@binkert.org 718233Snate@binkert.org TmpClass, test_mem_mode = getCPUClass(options.cpu_type) 728233Snate@binkert.org CPUClass = None 738233Snate@binkert.org if TmpClass.require_caches() and \ 746143Snate@binkert.org not options.caches and not options.ruby: 758233Snate@binkert.org fatal("%s must be used with caches" % options.cpu_type) 768233Snate@binkert.org 778233Snate@binkert.org if options.checkpoint_restore != None: 786143Snate@binkert.org if options.restore_with_cpu != options.cpu_type: 796143Snate@binkert.org CPUClass = TmpClass 806143Snate@binkert.org TmpClass, test_mem_mode = getCPUClass(options.restore_with_cpu) 8111308Santhony.gutierrez@amd.com elif options.fast_forward: 828233Snate@binkert.org CPUClass = TmpClass 838233Snate@binkert.org TmpClass = AtomicSimpleCPU 848233Snate@binkert.org test_mem_mode = 'atomic' 856143Snate@binkert.org 868233Snate@binkert.org return (TmpClass, test_mem_mode, CPUClass) 878233Snate@binkert.org 888233Snate@binkert.orgdef setMemClass(options): 898233Snate@binkert.org """Returns a memory controller class.""" 906143Snate@binkert.org 916143Snate@binkert.org return MemConfig.get(options.mem_type) 926143Snate@binkert.org 934762Snate@binkert.orgdef setWorkCountOptions(system, options): 946143Snate@binkert.org if options.work_item_id != None: 958233Snate@binkert.org system.work_item_id = options.work_item_id 968233Snate@binkert.org if options.num_work_ids != None: 978233Snate@binkert.org system.num_work_ids = options.num_work_ids 988233Snate@binkert.org if options.work_begin_cpu_id_exit != None: 998233Snate@binkert.org system.work_begin_cpu_id_exit = options.work_begin_cpu_id_exit 1006143Snate@binkert.org if options.work_end_exit_count != None: 1018233Snate@binkert.org system.work_end_exit_count = options.work_end_exit_count 1028233Snate@binkert.org if options.work_end_checkpoint_count != None: 1038233Snate@binkert.org system.work_end_ckpt_count = options.work_end_checkpoint_count 1048233Snate@binkert.org if options.work_begin_exit_count != None: 1056143Snate@binkert.org system.work_begin_exit_count = options.work_begin_exit_count 1066143Snate@binkert.org if options.work_begin_checkpoint_count != None: 1076143Snate@binkert.org system.work_begin_ckpt_count = options.work_begin_checkpoint_count 1086143Snate@binkert.org if options.work_cpus_checkpoint_count != None: 1096143Snate@binkert.org system.work_cpus_ckpt_count = options.work_cpus_checkpoint_count 1106143Snate@binkert.org 1116143Snate@binkert.orgdef findCptDir(options, cptdir, testsys): 1126143Snate@binkert.org """Figures out the directory from which the checkpointed state is read. 1136143Snate@binkert.org 1147065Snate@binkert.org There are two different ways in which the directories holding checkpoints 1156143Snate@binkert.org can be named -- 1168233Snate@binkert.org 1. cpt.<benchmark name>.<instruction count when the checkpoint was taken> 1178233Snate@binkert.org 2. cpt.<some number, usually the tick value when the checkpoint was taken> 1188233Snate@binkert.org 1198233Snate@binkert.org This function parses through the options to figure out which one of the 1208233Snate@binkert.org above should be used for selecting the checkpoint, and then figures out 1218233Snate@binkert.org the appropriate directory. 1228233Snate@binkert.org """ 1238233Snate@binkert.org 1248233Snate@binkert.org from os.path import isdir, exists 1258233Snate@binkert.org from os import listdir 1268233Snate@binkert.org import re 1278233Snate@binkert.org 1288233Snate@binkert.org if not isdir(cptdir): 1298233Snate@binkert.org fatal("checkpoint dir %s does not exist!", cptdir) 1308233Snate@binkert.org 1318233Snate@binkert.org cpt_starttick = 0 1328233Snate@binkert.org if options.at_instruction or options.simpoint: 1338233Snate@binkert.org inst = options.checkpoint_restore 1348233Snate@binkert.org if options.simpoint: 1358233Snate@binkert.org # assume workload 0 has the simpoint 1368233Snate@binkert.org if testsys.cpu[0].workload[0].simpoint == 0: 1378233Snate@binkert.org fatal('Unable to find simpoint') 1388233Snate@binkert.org inst += int(testsys.cpu[0].workload[0].simpoint) 1398233Snate@binkert.org 1408233Snate@binkert.org checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst)) 1418233Snate@binkert.org if not exists(checkpoint_dir): 1428233Snate@binkert.org fatal("Unable to find checkpoint directory %s", checkpoint_dir) 1438233Snate@binkert.org 1448233Snate@binkert.org elif options.restore_simpoint_checkpoint: 1458233Snate@binkert.org # Restore from SimPoint checkpoints 1468233Snate@binkert.org # Assumes that the checkpoint dir names are formatted as follows: 1476143Snate@binkert.org dirs = listdir(cptdir) 1486143Snate@binkert.org expr = re.compile('cpt\.simpoint_(\d+)_inst_(\d+)' + 1496143Snate@binkert.org '_weight_([\d\.e\-]+)_interval_(\d+)_warmup_(\d+)') 1506143Snate@binkert.org cpts = [] 1516143Snate@binkert.org for dir in dirs: 1526143Snate@binkert.org match = expr.match(dir) 1539982Satgutier@umich.edu if match: 15410196SCurtis.Dunham@arm.com cpts.append(dir) 15510196SCurtis.Dunham@arm.com cpts.sort() 15610196SCurtis.Dunham@arm.com 15710196SCurtis.Dunham@arm.com cpt_num = options.checkpoint_restore 15810196SCurtis.Dunham@arm.com if cpt_num > len(cpts): 15910196SCurtis.Dunham@arm.com fatal('Checkpoint %d not found', cpt_num) 16010196SCurtis.Dunham@arm.com checkpoint_dir = joinpath(cptdir, cpts[cpt_num - 1]) 16110196SCurtis.Dunham@arm.com match = expr.match(cpts[cpt_num - 1]) 1626143Snate@binkert.org if match: 1636143Snate@binkert.org index = int(match.group(1)) 1648945Ssteve.reinhardt@amd.com start_inst = int(match.group(2)) 1658233Snate@binkert.org weight_inst = float(match.group(3)) 1668233Snate@binkert.org interval_length = int(match.group(4)) 1676143Snate@binkert.org warmup_length = int(match.group(5)) 1688945Ssteve.reinhardt@amd.com print "Resuming from", checkpoint_dir 1696143Snate@binkert.org simpoint_start_insts = [] 1706143Snate@binkert.org simpoint_start_insts.append(warmup_length) 1716143Snate@binkert.org simpoint_start_insts.append(warmup_length + interval_length) 1726143Snate@binkert.org testsys.cpu[0].simpoint_start_insts = simpoint_start_insts 1735522Snate@binkert.org if testsys.switch_cpus != None: 1746143Snate@binkert.org testsys.switch_cpus[0].simpoint_start_insts = simpoint_start_insts 1756143Snate@binkert.org 1766143Snate@binkert.org print "Resuming from SimPoint", 1779982Satgutier@umich.edu print "#%d, start_inst:%d, weight:%f, interval:%d, warmup:%d" % \ 1788233Snate@binkert.org (index, start_inst, weight_inst, interval_length, warmup_length) 1798233Snate@binkert.org 1808233Snate@binkert.org else: 1816143Snate@binkert.org dirs = listdir(cptdir) 1826143Snate@binkert.org expr = re.compile('cpt\.([0-9]+)') 1836143Snate@binkert.org cpts = [] 1846143Snate@binkert.org for dir in dirs: 1855522Snate@binkert.org match = expr.match(dir) 1865522Snate@binkert.org if match: 1875522Snate@binkert.org cpts.append(match.group(1)) 1885522Snate@binkert.org 1895604Snate@binkert.org cpts.sort(lambda a,b: cmp(long(a), long(b))) 1905604Snate@binkert.org 1916143Snate@binkert.org cpt_num = options.checkpoint_restore 1926143Snate@binkert.org if cpt_num > len(cpts): 1934762Snate@binkert.org fatal('Checkpoint %d not found', cpt_num) 1944762Snate@binkert.org 1956143Snate@binkert.org cpt_starttick = int(cpts[cpt_num - 1]) 1966727Ssteve.reinhardt@amd.com checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1]) 1976727Ssteve.reinhardt@amd.com 1986727Ssteve.reinhardt@amd.com return cpt_starttick, checkpoint_dir 1994762Snate@binkert.org 2006143Snate@binkert.orgdef scriptCheckpoints(options, maxtick, cptdir): 2016143Snate@binkert.org if options.at_instruction or options.simpoint: 2026143Snate@binkert.org checkpoint_inst = int(options.take_checkpoints) 2036143Snate@binkert.org 2046727Ssteve.reinhardt@amd.com # maintain correct offset if we restored from some instruction 2056143Snate@binkert.org if options.checkpoint_restore != None: 2067674Snate@binkert.org checkpoint_inst += options.checkpoint_restore 2077674Snate@binkert.org 2085604Snate@binkert.org print "Creating checkpoint at inst:%d" % (checkpoint_inst) 2096143Snate@binkert.org exit_event = m5.simulate() 2106143Snate@binkert.org exit_cause = exit_event.getCause() 2116143Snate@binkert.org print "exit cause = %s" % exit_cause 2124762Snate@binkert.org 2136143Snate@binkert.org # skip checkpoint instructions should they exist 2144762Snate@binkert.org while exit_cause == "checkpoint": 2154762Snate@binkert.org exit_event = m5.simulate() 2164762Snate@binkert.org exit_cause = exit_event.getCause() 2176143Snate@binkert.org 2186143Snate@binkert.org if exit_cause == "a thread reached the max instruction count": 2194762Snate@binkert.org m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \ 2208233Snate@binkert.org (options.bench, checkpoint_inst))) 2218233Snate@binkert.org print "Checkpoint written." 2228233Snate@binkert.org 2238233Snate@binkert.org else: 2246143Snate@binkert.org when, period = options.take_checkpoints.split(",", 1) 2256143Snate@binkert.org when = int(when) 2264762Snate@binkert.org period = int(period) 2276143Snate@binkert.org num_checkpoints = 0 2284762Snate@binkert.org 2296143Snate@binkert.org exit_event = m5.simulate(when - m5.curTick()) 2304762Snate@binkert.org exit_cause = exit_event.getCause() 2316143Snate@binkert.org while exit_cause == "checkpoint": 2328233Snate@binkert.org exit_event = m5.simulate(when - m5.curTick()) 2338233Snate@binkert.org exit_cause = exit_event.getCause() 23410453SAndrew.Bardsley@arm.com 2356143Snate@binkert.org if exit_cause == "simulate() limit reached": 2366143Snate@binkert.org m5.checkpoint(joinpath(cptdir, "cpt.%d")) 2376143Snate@binkert.org num_checkpoints += 1 2386143Snate@binkert.org 2396143Snate@binkert.org sim_ticks = when 2406143Snate@binkert.org max_checkpoints = options.max_checkpoints 2416143Snate@binkert.org 2426143Snate@binkert.org while num_checkpoints < max_checkpoints and \ 24310453SAndrew.Bardsley@arm.com exit_cause == "simulate() limit reached": 24410453SAndrew.Bardsley@arm.com if (sim_ticks + period) > maxtick: 245955SN/A exit_event = m5.simulate(maxtick - sim_ticks) 2469396Sandreas.hansson@arm.com exit_cause = exit_event.getCause() 2479396Sandreas.hansson@arm.com break 2489396Sandreas.hansson@arm.com else: 2499396Sandreas.hansson@arm.com exit_event = m5.simulate(period) 2509396Sandreas.hansson@arm.com exit_cause = exit_event.getCause() 2519396Sandreas.hansson@arm.com sim_ticks += period 2529396Sandreas.hansson@arm.com while exit_event.getCause() == "checkpoint": 2539396Sandreas.hansson@arm.com exit_event = m5.simulate(sim_ticks - m5.curTick()) 2549396Sandreas.hansson@arm.com if exit_event.getCause() == "simulate() limit reached": 2559396Sandreas.hansson@arm.com m5.checkpoint(joinpath(cptdir, "cpt.%d")) 2569396Sandreas.hansson@arm.com num_checkpoints += 1 2579396Sandreas.hansson@arm.com 2589396Sandreas.hansson@arm.com return exit_event 2599930Sandreas.hansson@arm.com 2609930Sandreas.hansson@arm.comdef benchCheckpoints(options, maxtick, cptdir): 2619396Sandreas.hansson@arm.com exit_event = m5.simulate(maxtick - m5.curTick()) 2628235Snate@binkert.org exit_cause = exit_event.getCause() 2638235Snate@binkert.org 2646143Snate@binkert.org num_checkpoints = 0 2658235Snate@binkert.org max_checkpoints = options.max_checkpoints 2669003SAli.Saidi@ARM.com 2678235Snate@binkert.org while exit_cause == "checkpoint": 2688235Snate@binkert.org m5.checkpoint(joinpath(cptdir, "cpt.%d")) 2698235Snate@binkert.org num_checkpoints += 1 2708235Snate@binkert.org if num_checkpoints == max_checkpoints: 2718235Snate@binkert.org exit_cause = "maximum %d checkpoints dropped" % max_checkpoints 2728235Snate@binkert.org break 2738235Snate@binkert.org 2748235Snate@binkert.org exit_event = m5.simulate(maxtick - m5.curTick()) 2758235Snate@binkert.org exit_cause = exit_event.getCause() 2768235Snate@binkert.org 2778235Snate@binkert.org return exit_event 2788235Snate@binkert.org 2798235Snate@binkert.org# Set up environment for taking SimPoint checkpoints 2808235Snate@binkert.org# Expecting SimPoint files generated by SimPoint 3.2 2819003SAli.Saidi@ARM.comdef parseSimpointAnalysisFile(options, testsys): 2828235Snate@binkert.org import re 2835584Snate@binkert.org 2844382Sbinkertn@umich.edu simpoint_filename, weight_filename, interval_length, warmup_length = \ 2854202Sbinkertn@umich.edu options.take_simpoint_checkpoints.split(",", 3) 2864382Sbinkertn@umich.edu print "simpoint analysis file:", simpoint_filename 2874382Sbinkertn@umich.edu print "simpoint weight file:", weight_filename 2884382Sbinkertn@umich.edu print "interval length:", interval_length 2899396Sandreas.hansson@arm.com print "warmup length:", warmup_length 2905584Snate@binkert.org 2914382Sbinkertn@umich.edu interval_length = int(interval_length) 2924382Sbinkertn@umich.edu warmup_length = int(warmup_length) 2934382Sbinkertn@umich.edu 2948232Snate@binkert.org # Simpoint analysis output starts interval counts with 0. 2955192Ssaidi@eecs.umich.edu simpoints = [] 2968232Snate@binkert.org simpoint_start_insts = [] 2978232Snate@binkert.org 2988232Snate@binkert.org # Read in SimPoint analysis files 2995192Ssaidi@eecs.umich.edu simpoint_file = open(simpoint_filename) 3008232Snate@binkert.org weight_file = open(weight_filename) 3015192Ssaidi@eecs.umich.edu while True: 3025799Snate@binkert.org line = simpoint_file.readline() 3038232Snate@binkert.org if not line: 3045192Ssaidi@eecs.umich.edu break 3055192Ssaidi@eecs.umich.edu m = re.match("(\d+)\s+(\d+)", line) 3065192Ssaidi@eecs.umich.edu if m: 3078232Snate@binkert.org interval = int(m.group(1)) 3085192Ssaidi@eecs.umich.edu else: 3098232Snate@binkert.org fatal('unrecognized line in simpoint file!') 3105192Ssaidi@eecs.umich.edu 3115192Ssaidi@eecs.umich.edu line = weight_file.readline() 3125192Ssaidi@eecs.umich.edu if not line: 3135192Ssaidi@eecs.umich.edu fatal('not enough lines in simpoint weight file!') 3144382Sbinkertn@umich.edu m = re.match("([0-9\.e\-]+)\s+(\d+)", line) 3154382Sbinkertn@umich.edu if m: 3164382Sbinkertn@umich.edu weight = float(m.group(1)) 3172667Sstever@eecs.umich.edu else: 3182667Sstever@eecs.umich.edu fatal('unrecognized line in simpoint weight file!') 3192667Sstever@eecs.umich.edu 3202667Sstever@eecs.umich.edu if (interval * interval_length - warmup_length > 0): 3212667Sstever@eecs.umich.edu starting_inst_count = \ 3222667Sstever@eecs.umich.edu interval * interval_length - warmup_length 3235742Snate@binkert.org actual_warmup_length = warmup_length 3245742Snate@binkert.org else: 3255742Snate@binkert.org # Not enough room for proper warmup 3265793Snate@binkert.org # Just starting from the beginning 3278334Snate@binkert.org starting_inst_count = 0 3285793Snate@binkert.org actual_warmup_length = interval * interval_length 3295793Snate@binkert.org 3305793Snate@binkert.org simpoints.append((interval, weight, starting_inst_count, 3314382Sbinkertn@umich.edu actual_warmup_length)) 3324762Snate@binkert.org 3335344Sstever@gmail.com # Sort SimPoints by starting inst count 3344382Sbinkertn@umich.edu simpoints.sort(key=lambda obj: obj[2]) 3355341Sstever@gmail.com for s in simpoints: 3365742Snate@binkert.org interval, weight, starting_inst_count, actual_warmup_length = s 3375742Snate@binkert.org print str(interval), str(weight), starting_inst_count, \ 3385742Snate@binkert.org actual_warmup_length 3395742Snate@binkert.org simpoint_start_insts.append(starting_inst_count) 3405742Snate@binkert.org 3414762Snate@binkert.org print "Total # of simpoints:", len(simpoints) 3425742Snate@binkert.org testsys.cpu[0].simpoint_start_insts = simpoint_start_insts 3435742Snate@binkert.org 3447722Sgblack@eecs.umich.edu return (simpoints, interval_length) 3455742Snate@binkert.org 3465742Snate@binkert.orgdef takeSimpointCheckpoints(simpoints, interval_length, cptdir): 3475742Snate@binkert.org num_checkpoints = 0 3489930Sandreas.hansson@arm.com index = 0 3499930Sandreas.hansson@arm.com last_chkpnt_inst_count = -1 3509930Sandreas.hansson@arm.com for simpoint in simpoints: 3519930Sandreas.hansson@arm.com interval, weight, starting_inst_count, actual_warmup_length = simpoint 3529930Sandreas.hansson@arm.com if starting_inst_count == last_chkpnt_inst_count: 3535742Snate@binkert.org # checkpoint starting point same as last time 3548242Sbradley.danofsky@amd.com # (when warmup period longer than starting point) 3558242Sbradley.danofsky@amd.com exit_cause = "simpoint starting point found" 3568242Sbradley.danofsky@amd.com code = 0 3578242Sbradley.danofsky@amd.com else: 3585341Sstever@gmail.com exit_event = m5.simulate() 3595742Snate@binkert.org 3607722Sgblack@eecs.umich.edu # skip checkpoint instructions should they exist 3614773Snate@binkert.org while exit_event.getCause() == "checkpoint": 3626108Snate@binkert.org print "Found 'checkpoint' exit event...ignoring..." 3631858SN/A exit_event = m5.simulate() 3641085SN/A 3656658Snate@binkert.org exit_cause = exit_event.getCause() 3666658Snate@binkert.org code = exit_event.getCode() 3677673Snate@binkert.org 3686658Snate@binkert.org if exit_cause == "simpoint starting point found": 3696658Snate@binkert.org m5.checkpoint(joinpath(cptdir, 37011308Santhony.gutierrez@amd.com "cpt.simpoint_%02d_inst_%d_weight_%f_interval_%d_warmup_%d" 3716658Snate@binkert.org % (index, starting_inst_count, weight, interval_length, 37211308Santhony.gutierrez@amd.com actual_warmup_length))) 3736658Snate@binkert.org print "Checkpoint #%d written. start inst:%d weight:%f" % \ 3746658Snate@binkert.org (num_checkpoints, starting_inst_count, weight) 3757673Snate@binkert.org num_checkpoints += 1 3767673Snate@binkert.org last_chkpnt_inst_count = starting_inst_count 3777673Snate@binkert.org else: 3787673Snate@binkert.org break 3797673Snate@binkert.org index += 1 3807673Snate@binkert.org 3817673Snate@binkert.org print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause) 38210467Sandreas.hansson@arm.com print "%d checkpoints taken" % num_checkpoints 3836658Snate@binkert.org sys.exit(code) 3847673Snate@binkert.org 38510467Sandreas.hansson@arm.comdef restoreSimpointCheckpoint(): 38610467Sandreas.hansson@arm.com exit_event = m5.simulate() 38710467Sandreas.hansson@arm.com exit_cause = exit_event.getCause() 38810467Sandreas.hansson@arm.com 38910467Sandreas.hansson@arm.com if exit_cause == "simpoint starting point found": 39010467Sandreas.hansson@arm.com print "Warmed up! Dumping and resetting stats!" 39110467Sandreas.hansson@arm.com m5.stats.dump() 39210467Sandreas.hansson@arm.com m5.stats.reset() 39310467Sandreas.hansson@arm.com 39410467Sandreas.hansson@arm.com exit_event = m5.simulate() 39510467Sandreas.hansson@arm.com exit_cause = exit_event.getCause() 3967673Snate@binkert.org 3977673Snate@binkert.org if exit_cause == "simpoint starting point found": 3987673Snate@binkert.org print "Done running SimPoint!" 3997673Snate@binkert.org sys.exit(exit_event.getCode()) 4007673Snate@binkert.org 4019048SAli.Saidi@ARM.com print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause) 4027673Snate@binkert.org sys.exit(exit_event.getCode()) 4037673Snate@binkert.org 4047673Snate@binkert.orgdef repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq): 4057673Snate@binkert.org print "starting switch loop" 4066658Snate@binkert.org while True: 4077756SAli.Saidi@ARM.com exit_event = m5.simulate(switch_freq) 4087816Ssteve.reinhardt@amd.com exit_cause = exit_event.getCause() 4096658Snate@binkert.org 41011308Santhony.gutierrez@amd.com if exit_cause != "simulate() limit reached": 41111308Santhony.gutierrez@amd.com return exit_event 41211308Santhony.gutierrez@amd.com 41311308Santhony.gutierrez@amd.com m5.switchCpus(testsys, repeat_switch_cpu_list) 41411308Santhony.gutierrez@amd.com 41511308Santhony.gutierrez@amd.com tmp_cpu_list = [] 41611308Santhony.gutierrez@amd.com for old_cpu, new_cpu in repeat_switch_cpu_list: 41711308Santhony.gutierrez@amd.com tmp_cpu_list.append((new_cpu, old_cpu)) 41811308Santhony.gutierrez@amd.com repeat_switch_cpu_list = tmp_cpu_list 41911308Santhony.gutierrez@amd.com 42011308Santhony.gutierrez@amd.com if (maxtick - m5.curTick()) <= switch_freq: 42111308Santhony.gutierrez@amd.com exit_event = m5.simulate(maxtick - m5.curTick()) 42211308Santhony.gutierrez@amd.com return exit_event 42311308Santhony.gutierrez@amd.com 42411308Santhony.gutierrez@amd.comdef run(options, root, testsys, cpu_class): 42511308Santhony.gutierrez@amd.com if options.checkpoint_dir: 42611308Santhony.gutierrez@amd.com cptdir = options.checkpoint_dir 42711308Santhony.gutierrez@amd.com elif m5.options.outdir: 42811308Santhony.gutierrez@amd.com cptdir = m5.options.outdir 42911308Santhony.gutierrez@amd.com else: 43011308Santhony.gutierrez@amd.com cptdir = getcwd() 43111308Santhony.gutierrez@amd.com 43211308Santhony.gutierrez@amd.com if options.fast_forward and options.checkpoint_restore != None: 43311308Santhony.gutierrez@amd.com fatal("Can't specify both --fast-forward and --checkpoint-restore") 43411308Santhony.gutierrez@amd.com 43511308Santhony.gutierrez@amd.com if options.standard_switch and not options.caches: 43611308Santhony.gutierrez@amd.com fatal("Must specify --caches when using --standard-switch") 43711308Santhony.gutierrez@amd.com 43811308Santhony.gutierrez@amd.com if options.standard_switch and options.repeat_switch: 43911308Santhony.gutierrez@amd.com fatal("Can't specify both --standard-switch and --repeat-switch") 44011308Santhony.gutierrez@amd.com 44111308Santhony.gutierrez@amd.com if options.repeat_switch and options.take_checkpoints: 44211308Santhony.gutierrez@amd.com fatal("Can't specify both --repeat-switch and --take-checkpoints") 44311308Santhony.gutierrez@amd.com 44411308Santhony.gutierrez@amd.com np = options.num_cpus 44511308Santhony.gutierrez@amd.com switch_cpus = None 44611308Santhony.gutierrez@amd.com 44711308Santhony.gutierrez@amd.com if options.prog_interval: 44811308Santhony.gutierrez@amd.com for i in xrange(np): 44911308Santhony.gutierrez@amd.com testsys.cpu[i].progress_interval = options.prog_interval 45011308Santhony.gutierrez@amd.com 45111308Santhony.gutierrez@amd.com if options.maxinsts: 45211308Santhony.gutierrez@amd.com for i in xrange(np): 45311308Santhony.gutierrez@amd.com testsys.cpu[i].max_insts_any_thread = options.maxinsts 45411308Santhony.gutierrez@amd.com 4554382Sbinkertn@umich.edu if cpu_class: 4564382Sbinkertn@umich.edu switch_cpus = [cpu_class(switched_out=True, cpu_id=(i)) 4574762Snate@binkert.org for i in xrange(np)] 4584762Snate@binkert.org 4594762Snate@binkert.org for i in xrange(np): 4606654Snate@binkert.org if options.fast_forward: 4616654Snate@binkert.org testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) 4625517Snate@binkert.org switch_cpus[i].system = testsys 4635517Snate@binkert.org switch_cpus[i].workload = testsys.cpu[i].workload 4645517Snate@binkert.org switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain 4655517Snate@binkert.org switch_cpus[i].progress_interval = \ 4665517Snate@binkert.org testsys.cpu[i].progress_interval 4675517Snate@binkert.org # simulation period 4685517Snate@binkert.org if options.maxinsts: 4695517Snate@binkert.org switch_cpus[i].max_insts_any_thread = options.maxinsts 4705517Snate@binkert.org # Add checker cpu if selected 4715517Snate@binkert.org if options.checker: 4725517Snate@binkert.org switch_cpus[i].addCheckerCpu() 4735517Snate@binkert.org 4745517Snate@binkert.org # If elastic tracing is enabled attach the elastic trace probe 4755517Snate@binkert.org # to the switch CPUs 4765517Snate@binkert.org if options.elastic_trace_en: 4775517Snate@binkert.org CpuConfig.config_etrace(cpu_class, switch_cpus, options) 4785517Snate@binkert.org 4796654Snate@binkert.org testsys.switch_cpus = switch_cpus 4805517Snate@binkert.org switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] 4815517Snate@binkert.org 4825517Snate@binkert.org if options.repeat_switch: 4835517Snate@binkert.org switch_class = getCPUClass(options.cpu_type)[0] 4845517Snate@binkert.org if switch_class.require_caches() and \ 4855517Snate@binkert.org not options.caches: 4865517Snate@binkert.org print "%s: Must be used with caches" % str(switch_class) 4875517Snate@binkert.org sys.exit(1) 4886143Snate@binkert.org if not switch_class.support_take_over(): 4896654Snate@binkert.org print "%s: CPU switching not supported" % str(switch_class) 4905517Snate@binkert.org sys.exit(1) 4915517Snate@binkert.org 4925517Snate@binkert.org repeat_switch_cpus = [switch_class(switched_out=True, \ 4935517Snate@binkert.org cpu_id=(i)) for i in xrange(np)] 4945517Snate@binkert.org 4955517Snate@binkert.org for i in xrange(np): 4965517Snate@binkert.org repeat_switch_cpus[i].system = testsys 4975517Snate@binkert.org repeat_switch_cpus[i].workload = testsys.cpu[i].workload 4985517Snate@binkert.org repeat_switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain 4995517Snate@binkert.org 5005517Snate@binkert.org if options.maxinsts: 5015517Snate@binkert.org repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts 5025517Snate@binkert.org 5035517Snate@binkert.org if options.checker: 5046654Snate@binkert.org repeat_switch_cpus[i].addCheckerCpu() 5056654Snate@binkert.org 5065517Snate@binkert.org testsys.repeat_switch_cpus = repeat_switch_cpus 5075517Snate@binkert.org 5086143Snate@binkert.org if cpu_class: 5096143Snate@binkert.org repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i]) 5106143Snate@binkert.org for i in xrange(np)] 5116727Ssteve.reinhardt@amd.com else: 5125517Snate@binkert.org repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i]) 5136727Ssteve.reinhardt@amd.com for i in xrange(np)] 5145517Snate@binkert.org 5155517Snate@binkert.org if options.standard_switch: 5165517Snate@binkert.org switch_cpus = [TimingSimpleCPU(switched_out=True, cpu_id=(i)) 5176654Snate@binkert.org for i in xrange(np)] 5186654Snate@binkert.org switch_cpus_1 = [DerivO3CPU(switched_out=True, cpu_id=(i)) 5197673Snate@binkert.org for i in xrange(np)] 5206654Snate@binkert.org 5216654Snate@binkert.org for i in xrange(np): 5226654Snate@binkert.org switch_cpus[i].system = testsys 5236654Snate@binkert.org switch_cpus_1[i].system = testsys 5245517Snate@binkert.org switch_cpus[i].workload = testsys.cpu[i].workload 5255517Snate@binkert.org switch_cpus_1[i].workload = testsys.cpu[i].workload 5265517Snate@binkert.org switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain 5276143Snate@binkert.org switch_cpus_1[i].clk_domain = testsys.cpu[i].clk_domain 5285517Snate@binkert.org 5294762Snate@binkert.org # if restoring, make atomic cpu simulate only a few instructions 5305517Snate@binkert.org if options.checkpoint_restore != None: 5315517Snate@binkert.org testsys.cpu[i].max_insts_any_thread = 1 5326143Snate@binkert.org # Fast forward to specified location if we are not restoring 5336143Snate@binkert.org elif options.fast_forward: 5345517Snate@binkert.org testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) 5355517Snate@binkert.org # Fast forward to a simpoint (warning: time consuming) 5365517Snate@binkert.org elif options.simpoint: 5375517Snate@binkert.org if testsys.cpu[i].workload[0].simpoint == 0: 5385517Snate@binkert.org fatal('simpoint not found') 5395517Snate@binkert.org testsys.cpu[i].max_insts_any_thread = \ 5405517Snate@binkert.org testsys.cpu[i].workload[0].simpoint 5415517Snate@binkert.org # No distance specified, just switch 5425517Snate@binkert.org else: 5439338SAndreas.Sandberg@arm.com testsys.cpu[i].max_insts_any_thread = 1 5449338SAndreas.Sandberg@arm.com 5459338SAndreas.Sandberg@arm.com # warmup period 5469338SAndreas.Sandberg@arm.com if options.warmup_insts: 5479338SAndreas.Sandberg@arm.com switch_cpus[i].max_insts_any_thread = options.warmup_insts 5489338SAndreas.Sandberg@arm.com 5498596Ssteve.reinhardt@amd.com # simulation period 5508596Ssteve.reinhardt@amd.com if options.maxinsts: 5518596Ssteve.reinhardt@amd.com switch_cpus_1[i].max_insts_any_thread = options.maxinsts 5528596Ssteve.reinhardt@amd.com 5538596Ssteve.reinhardt@amd.com # attach the checker cpu if selected 5548596Ssteve.reinhardt@amd.com if options.checker: 5558596Ssteve.reinhardt@amd.com switch_cpus[i].addCheckerCpu() 5566143Snate@binkert.org switch_cpus_1[i].addCheckerCpu() 5575517Snate@binkert.org 5586654Snate@binkert.org testsys.switch_cpus = switch_cpus 5596654Snate@binkert.org testsys.switch_cpus_1 = switch_cpus_1 5606654Snate@binkert.org switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] 5616654Snate@binkert.org switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] 5626654Snate@binkert.org 5636654Snate@binkert.org # set the checkpoint in the cpu before m5.instantiate is called 5645517Snate@binkert.org if options.take_checkpoints != None and \ 5655517Snate@binkert.org (options.simpoint or options.at_instruction): 5665517Snate@binkert.org offset = int(options.take_checkpoints) 5678596Ssteve.reinhardt@amd.com # Set an instruction break point 5688596Ssteve.reinhardt@amd.com if options.simpoint: 5694762Snate@binkert.org for i in xrange(np): 5704762Snate@binkert.org if testsys.cpu[i].workload[0].simpoint == 0: 5714762Snate@binkert.org fatal('no simpoint for testsys.cpu[%d].workload[0]', i) 5724762Snate@binkert.org checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset 5734762Snate@binkert.org testsys.cpu[i].max_insts_any_thread = checkpoint_inst 5744762Snate@binkert.org # used for output below 5757675Snate@binkert.org options.take_checkpoints = checkpoint_inst 57610584Sandreas.hansson@arm.com else: 5774762Snate@binkert.org options.take_checkpoints = offset 5784762Snate@binkert.org # Set all test cpus with the right number of instructions 5794762Snate@binkert.org # for the upcoming simulation 5804762Snate@binkert.org for i in xrange(np): 5814382Sbinkertn@umich.edu testsys.cpu[i].max_insts_any_thread = offset 5824382Sbinkertn@umich.edu 5835517Snate@binkert.org if options.take_simpoint_checkpoints != None: 5846654Snate@binkert.org simpoints, interval_length = parseSimpointAnalysisFile(options, testsys) 5855517Snate@binkert.org 5868126Sgblack@eecs.umich.edu checkpoint_dir = None 5876654Snate@binkert.org if options.checkpoint_restore: 5887673Snate@binkert.org cpt_starttick, checkpoint_dir = findCptDir(options, cptdir, testsys) 5896654Snate@binkert.org m5.instantiate(checkpoint_dir) 5906654Snate@binkert.org 5916654Snate@binkert.org # Initialization is complete. If we're not in control of simulation 5926654Snate@binkert.org # (that is, if we're a slave simulator acting as a component in another 5936654Snate@binkert.org # 'master' simulator) then we're done here. The other simulator will 5946654Snate@binkert.org # call simulate() directly. --initialize-only is used to indicate this. 5956654Snate@binkert.org if options.initialize_only: 5966669Snate@binkert.org return 5976669Snate@binkert.org 5986669Snate@binkert.org # Handle the max tick settings now that tick frequency was resolved 5996669Snate@binkert.org # during system instantiation 6006669Snate@binkert.org # NOTE: the maxtick variable here is in absolute ticks, so it must 6016669Snate@binkert.org # include any simulated ticks before a checkpoint 6026654Snate@binkert.org explicit_maxticks = 0 6037673Snate@binkert.org maxtick_from_abs = m5.MaxTick 6045517Snate@binkert.org maxtick_from_rel = m5.MaxTick 6058126Sgblack@eecs.umich.edu maxtick_from_maxtime = m5.MaxTick 6065798Snate@binkert.org if options.abs_max_tick: 6077756SAli.Saidi@ARM.com maxtick_from_abs = options.abs_max_tick 6087816Ssteve.reinhardt@amd.com explicit_maxticks += 1 6095798Snate@binkert.org if options.rel_max_tick: 6105798Snate@binkert.org maxtick_from_rel = options.rel_max_tick 6115517Snate@binkert.org if options.checkpoint_restore: 6125517Snate@binkert.org # NOTE: this may need to be updated if checkpoints ever store 6137673Snate@binkert.org # the ticks per simulated second 6145517Snate@binkert.org maxtick_from_rel += cpt_starttick 6155517Snate@binkert.org if options.at_instruction or options.simpoint: 6167673Snate@binkert.org warn("Relative max tick specified with --at-instruction or" \ 6177673Snate@binkert.org " --simpoint\n These options don't specify the " \ 6185517Snate@binkert.org "checkpoint start tick, so assuming\n you mean " \ 6195798Snate@binkert.org "absolute max tick") 6205798Snate@binkert.org explicit_maxticks += 1 6218333Snate@binkert.org if options.maxtime: 6227816Ssteve.reinhardt@amd.com maxtick_from_maxtime = m5.ticks.fromSeconds(options.maxtime) 6235798Snate@binkert.org explicit_maxticks += 1 6245798Snate@binkert.org if explicit_maxticks > 1: 6254762Snate@binkert.org warn("Specified multiple of --abs-max-tick, --rel-max-tick, --maxtime."\ 6264762Snate@binkert.org " Using least") 6274762Snate@binkert.org maxtick = min([maxtick_from_abs, maxtick_from_rel, maxtick_from_maxtime]) 6284762Snate@binkert.org 6294762Snate@binkert.org if options.checkpoint_restore != None and maxtick < cpt_starttick: 6308596Ssteve.reinhardt@amd.com fatal("Bad maxtick (%d) specified: " \ 6315517Snate@binkert.org "Checkpoint starts starts from tick: %d", maxtick, cpt_starttick) 6325517Snate@binkert.org 6335517Snate@binkert.org if options.standard_switch or cpu_class: 6345517Snate@binkert.org if options.standard_switch: 6355517Snate@binkert.org print "Switch at instruction count:%s" % \ 6367673Snate@binkert.org str(testsys.cpu[0].max_insts_any_thread) 6378596Ssteve.reinhardt@amd.com exit_event = m5.simulate() 6387673Snate@binkert.org elif cpu_class and options.fast_forward: 6395517Snate@binkert.org print "Switch at instruction count:%s" % \ 64010458Sandreas.hansson@arm.com str(testsys.cpu[0].max_insts_any_thread) 64110458Sandreas.hansson@arm.com exit_event = m5.simulate() 64210458Sandreas.hansson@arm.com else: 64310458Sandreas.hansson@arm.com print "Switch at curTick count:%s" % str(10000) 64410458Sandreas.hansson@arm.com exit_event = m5.simulate(10000) 64510458Sandreas.hansson@arm.com print "Switched CPUS @ tick %s" % (m5.curTick()) 64610458Sandreas.hansson@arm.com 64710458Sandreas.hansson@arm.com m5.switchCpus(testsys, switch_cpu_list) 64810458Sandreas.hansson@arm.com 64910458Sandreas.hansson@arm.com if options.standard_switch: 65010458Sandreas.hansson@arm.com print "Switch at instruction count:%d" % \ 65110458Sandreas.hansson@arm.com (testsys.switch_cpus[0].max_insts_any_thread) 6528596Ssteve.reinhardt@amd.com 6535517Snate@binkert.org #warmup instruction count may have already been set 6545517Snate@binkert.org if options.warmup_insts: 6555517Snate@binkert.org exit_event = m5.simulate() 6568596Ssteve.reinhardt@amd.com else: 6575517Snate@binkert.org exit_event = m5.simulate(options.standard_switch) 6587673Snate@binkert.org print "Switching CPUS @ tick %s" % (m5.curTick()) 6597673Snate@binkert.org print "Simulation ends instruction count:%d" % \ 6607673Snate@binkert.org (testsys.switch_cpus_1[0].max_insts_any_thread) 6615517Snate@binkert.org m5.switchCpus(testsys, switch_cpu_list1) 6625517Snate@binkert.org 6635517Snate@binkert.org # If we're taking and restoring checkpoints, use checkpoint_dir 6645517Snate@binkert.org # option only for finding the checkpoints to restore from. This 6655517Snate@binkert.org # lets us test checkpointing by restoring from one set of 6665517Snate@binkert.org # checkpoints, generating a second set, and then comparing them. 6675517Snate@binkert.org if (options.take_checkpoints or options.take_simpoint_checkpoints) \ 6687673Snate@binkert.org and options.checkpoint_restore: 6697673Snate@binkert.org 6707673Snate@binkert.org if m5.options.outdir: 6715517Snate@binkert.org cptdir = m5.options.outdir 6728596Ssteve.reinhardt@amd.com else: 6735517Snate@binkert.org cptdir = getcwd() 6745517Snate@binkert.org 6755517Snate@binkert.org if options.take_checkpoints != None : 6765517Snate@binkert.org # Checkpoints being taken via the command line at <when> and at 6775517Snate@binkert.org # subsequent periods of <period>. Checkpoint instructions 6787673Snate@binkert.org # received from the benchmark running are ignored and skipped in 6797673Snate@binkert.org # favor of command line checkpoint instructions. 6807673Snate@binkert.org exit_event = scriptCheckpoints(options, maxtick, cptdir) 6815517Snate@binkert.org 6828596Ssteve.reinhardt@amd.com # Take SimPoint checkpoints 6837675Snate@binkert.org elif options.take_simpoint_checkpoints != None: 6847675Snate@binkert.org takeSimpointCheckpoints(simpoints, interval_length, cptdir) 6857675Snate@binkert.org 6867675Snate@binkert.org # Restore from SimPoint checkpoints 6877675Snate@binkert.org elif options.restore_simpoint_checkpoint != None: 6887675Snate@binkert.org restoreSimpointCheckpoint() 6898596Ssteve.reinhardt@amd.com 6907675Snate@binkert.org else: 6917675Snate@binkert.org if options.fast_forward: 6928596Ssteve.reinhardt@amd.com m5.stats.reset() 6938596Ssteve.reinhardt@amd.com print "**** REAL SIMULATION ****" 6948596Ssteve.reinhardt@amd.com 6958596Ssteve.reinhardt@amd.com # If checkpoints are being taken, then the checkpoint instruction 6968596Ssteve.reinhardt@amd.com # will occur in the benchmark code it self. 6978596Ssteve.reinhardt@amd.com if options.repeat_switch and maxtick > options.repeat_switch: 6988596Ssteve.reinhardt@amd.com exit_event = repeatSwitch(testsys, repeat_switch_cpu_list, 6998596Ssteve.reinhardt@amd.com maxtick, options.repeat_switch) 70010454SCurtis.Dunham@arm.com else: 70110454SCurtis.Dunham@arm.com exit_event = benchCheckpoints(options, maxtick, cptdir) 70210454SCurtis.Dunham@arm.com 70310454SCurtis.Dunham@arm.com print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_event.getCause()) 7048596Ssteve.reinhardt@amd.com if options.checkpoint_at_end: 7054762Snate@binkert.org m5.checkpoint(joinpath(cptdir, "cpt.%d")) 7066143Snate@binkert.org 7076143Snate@binkert.org if not m5.options.interactive: 7086143Snate@binkert.org sys.exit(exit_event.getCode()) 7094762Snate@binkert.org