1# Copyright (c) 2006-2008 The Regents of The University of Michigan 2# Copyright (c) 2010 Advanced Micro Devices, Inc. 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer; 9# redistributions in binary form must reproduce the above copyright 10# notice, this list of conditions and the following disclaimer in the 11# documentation and/or other materials provided with the distribution; 12# neither the name of the copyright holders nor the names of its 13# contributors may be used to endorse or promote products derived from 14# this software without specific prior written permission. 15# 16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27# 28# Authors: Lisa Hsu 29 30from os import getcwd 31from os.path import join as joinpath 32 33import m5 34from m5.defines import buildEnv 35from m5.objects import * 36from m5.util import * 37from O3_ARM_v7a import * 38 39addToPath('../common') 40 41def setCPUClass(options): 42 43 atomic = False 44 if options.cpu_type == "timing": 45 class TmpClass(TimingSimpleCPU): pass 46 elif options.cpu_type == "detailed" or options.cpu_type == "arm_detailed": 47 if not options.caches and not options.ruby: 48 print "O3 CPU must be used with caches" 49 sys.exit(1) 50 if options.cpu_type == "arm_detailed": 51 class TmpClass(O3_ARM_v7a_3): pass 52 else: 53 class TmpClass(DerivO3CPU): pass 54 elif options.cpu_type == "inorder": 55 if not options.caches: 56 print "InOrder CPU must be used with caches" 57 sys.exit(1) 58 class TmpClass(InOrderCPU): pass 59 else: 60 class TmpClass(AtomicSimpleCPU): pass 61 atomic = True 62 63 CPUClass = None 64 test_mem_mode = 'atomic' 65 66 if not atomic: 67 if options.checkpoint_restore != None: 68 if options.restore_with_cpu != options.cpu_type: 69 CPUClass = TmpClass 70 class TmpClass(AtomicSimpleCPU): pass 71 else: 72 if options.restore_with_cpu != "atomic": 73 test_mem_mode = 'timing' 74 75 elif options.fast_forward: 76 CPUClass = TmpClass 77 class TmpClass(AtomicSimpleCPU): pass 78 else: 79 test_mem_mode = 'timing' 80 81 return (TmpClass, test_mem_mode, CPUClass) 82 83 84def run(options, root, testsys, cpu_class): 85 if options.maxtick: 86 maxtick = options.maxtick 87 elif options.maxtime: 88 simtime = m5.ticks.seconds(simtime) 89 print "simulating for: ", simtime 90 maxtick = simtime 91 else: 92 maxtick = m5.MaxTick 93 94 if options.checkpoint_dir: 95 cptdir = options.checkpoint_dir 96 elif m5.options.outdir: 97 cptdir = m5.options.outdir 98 else: 99 cptdir = getcwd() 100 101 if options.fast_forward and options.checkpoint_restore != None: 102 fatal("Can't specify both --fast-forward and --checkpoint-restore") 103 104 if options.standard_switch and not options.caches: 105 fatal("Must specify --caches when using --standard-switch") 106 107 np = options.num_cpus 108 max_checkpoints = options.max_checkpoints 109 switch_cpus = None 110 111 if options.prog_interval: 112 for i in xrange(np): 113 testsys.cpu[i].progress_interval = options.prog_interval 114 115 if options.maxinsts: 116 for i in xrange(np): 117 testsys.cpu[i].max_insts_any_thread = options.maxinsts 118 119 if cpu_class: 120 switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i)) 121 for i in xrange(np)] 122 123 for i in xrange(np): 124 if options.fast_forward: 125 testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) 126 switch_cpus[i].system = testsys
|
127 if not buildEnv['FULL_SYSTEM']:
128 switch_cpus[i].workload = testsys.cpu[i].workload
|
127 switch_cpus[i].workload = testsys.cpu[i].workload |
128 switch_cpus[i].clock = testsys.cpu[0].clock 129 # simulation period 130 if options.maxinsts: 131 switch_cpus[i].max_insts_any_thread = options.maxinsts 132 133 testsys.switch_cpus = switch_cpus 134 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] 135 136 if options.standard_switch: 137 if not options.caches: 138 # O3 CPU must have a cache to work. 139 print "O3 CPU must be used with caches" 140 sys.exit(1) 141 142 switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i)) 143 for i in xrange(np)] 144 switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i)) 145 for i in xrange(np)] 146 147 for i in xrange(np): 148 switch_cpus[i].system = testsys 149 switch_cpus_1[i].system = testsys
|
151 if not buildEnv['FULL_SYSTEM']:
152 switch_cpus[i].workload = testsys.cpu[i].workload
153 switch_cpus_1[i].workload = testsys.cpu[i].workload
|
150 switch_cpus[i].workload = testsys.cpu[i].workload 151 switch_cpus_1[i].workload = testsys.cpu[i].workload |
152 switch_cpus[i].clock = testsys.cpu[0].clock 153 switch_cpus_1[i].clock = testsys.cpu[0].clock 154 155 # if restoring, make atomic cpu simulate only a few instructions 156 if options.checkpoint_restore != None: 157 testsys.cpu[i].max_insts_any_thread = 1 158 # Fast forward to specified location if we are not restoring 159 elif options.fast_forward: 160 testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) 161 # Fast forward to a simpoint (warning: time consuming) 162 elif options.simpoint: 163 if testsys.cpu[i].workload[0].simpoint == 0: 164 fatal('simpoint not found') 165 testsys.cpu[i].max_insts_any_thread = \ 166 testsys.cpu[i].workload[0].simpoint 167 # No distance specified, just switch 168 else: 169 testsys.cpu[i].max_insts_any_thread = 1 170 171 # warmup period 172 if options.warmup_insts: 173 switch_cpus[i].max_insts_any_thread = options.warmup_insts 174 175 # simulation period 176 if options.maxinsts: 177 switch_cpus_1[i].max_insts_any_thread = options.maxinsts 178 179 testsys.switch_cpus = switch_cpus 180 testsys.switch_cpus_1 = switch_cpus_1 181 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] 182 switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] 183 184 # set the checkpoint in the cpu before m5.instantiate is called 185 if options.take_checkpoints != None and \ 186 (options.simpoint or options.at_instruction): 187 offset = int(options.take_checkpoints) 188 # Set an instruction break point 189 if options.simpoint: 190 for i in xrange(np): 191 if testsys.cpu[i].workload[0].simpoint == 0: 192 fatal('no simpoint for testsys.cpu[%d].workload[0]', i) 193 checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset 194 testsys.cpu[i].max_insts_any_thread = checkpoint_inst 195 # used for output below 196 options.take_checkpoints = checkpoint_inst 197 else: 198 options.take_checkpoints = offset 199 # Set all test cpus with the right number of instructions 200 # for the upcoming simulation 201 for i in xrange(np): 202 testsys.cpu[i].max_insts_any_thread = offset 203 204 checkpoint_dir = None 205 if options.checkpoint_restore != None: 206 from os.path import isdir, exists 207 from os import listdir 208 import re 209 210 if not isdir(cptdir): 211 fatal("checkpoint dir %s does not exist!", cptdir) 212 213 if options.at_instruction or options.simpoint: 214 inst = options.checkpoint_restore 215 if options.simpoint: 216 # assume workload 0 has the simpoint 217 if testsys.cpu[0].workload[0].simpoint == 0: 218 fatal('Unable to find simpoint') 219 inst += int(testsys.cpu[0].workload[0].simpoint) 220 221 checkpoint_dir = joinpath(cptdir, 222 "cpt.%s.%s" % (options.bench, inst)) 223 if not exists(checkpoint_dir): 224 fatal("Unable to find checkpoint directory %s", checkpoint_dir) 225 else: 226 dirs = listdir(cptdir) 227 expr = re.compile('cpt\.([0-9]*)') 228 cpts = [] 229 for dir in dirs: 230 match = expr.match(dir) 231 if match: 232 cpts.append(match.group(1)) 233 234 cpts.sort(lambda a,b: cmp(long(a), long(b))) 235 236 cpt_num = options.checkpoint_restore 237 238 if cpt_num > len(cpts): 239 fatal('Checkpoint %d not found', cpt_num) 240 241 ## Adjust max tick based on our starting tick 242 maxtick = maxtick - int(cpts[cpt_num - 1]) 243 checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1]) 244 245 m5.instantiate(checkpoint_dir) 246 247 if options.standard_switch or cpu_class: 248 if options.standard_switch: 249 print "Switch at instruction count:%s" % \ 250 str(testsys.cpu[0].max_insts_any_thread) 251 exit_event = m5.simulate() 252 elif cpu_class and options.fast_forward: 253 print "Switch at instruction count:%s" % \ 254 str(testsys.cpu[0].max_insts_any_thread) 255 exit_event = m5.simulate() 256 else: 257 print "Switch at curTick count:%s" % str(10000) 258 exit_event = m5.simulate(10000) 259 print "Switched CPUS @ tick %s" % (m5.curTick()) 260 261 # when you change to Timing (or Atomic), you halt the system 262 # given as argument. When you are finished with the system 263 # changes (including switchCpus), you must resume the system 264 # manually. You DON'T need to resume after just switching 265 # CPUs if you haven't changed anything on the system level. 266 267 m5.changeToTiming(testsys) 268 m5.switchCpus(switch_cpu_list) 269 m5.resume(testsys) 270 271 if options.standard_switch: 272 print "Switch at instruction count:%d" % \ 273 (testsys.switch_cpus[0].max_insts_any_thread) 274 275 #warmup instruction count may have already been set 276 if options.warmup_insts: 277 exit_event = m5.simulate() 278 else: 279 exit_event = m5.simulate(options.warmup) 280 print "Switching CPUS @ tick %s" % (m5.curTick()) 281 print "Simulation ends instruction count:%d" % \ 282 (testsys.switch_cpus_1[0].max_insts_any_thread) 283 m5.drain(testsys) 284 m5.switchCpus(switch_cpu_list1) 285 m5.resume(testsys) 286 287 num_checkpoints = 0 288 exit_cause = '' 289 290 # If we're taking and restoring checkpoints, use checkpoint_dir 291 # option only for finding the checkpoints to restore from. This 292 # lets us test checkpointing by restoring from one set of 293 # checkpoints, generating a second set, and then comparing them. 294 if options.take_checkpoints and options.checkpoint_restore: 295 if m5.options.outdir: 296 cptdir = m5.options.outdir 297 else: 298 cptdir = getcwd() 299 300 # Checkpoints being taken via the command line at <when> and at 301 # subsequent periods of <period>. Checkpoint instructions 302 # received from the benchmark running are ignored and skipped in 303 # favor of command line checkpoint instructions. 304 if options.take_checkpoints != None : 305 if options.at_instruction or options.simpoint: 306 checkpoint_inst = int(options.take_checkpoints) 307 308 # maintain correct offset if we restored from some instruction 309 if options.checkpoint_restore != None: 310 checkpoint_inst += options.checkpoint_restore 311 312 print "Creating checkpoint at inst:%d" % (checkpoint_inst) 313 exit_event = m5.simulate() 314 print "exit cause = %s" % (exit_event.getCause()) 315 316 # skip checkpoint instructions should they exist 317 while exit_event.getCause() == "checkpoint": 318 exit_event = m5.simulate() 319 320 if exit_event.getCause() == \ 321 "a thread reached the max instruction count": 322 m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \ 323 (options.bench, checkpoint_inst))) 324 print "Checkpoint written." 325 num_checkpoints += 1 326 327 if exit_event.getCause() == "user interrupt received": 328 exit_cause = exit_event.getCause(); 329 else: 330 when, period = options.take_checkpoints.split(",", 1) 331 when = int(when) 332 period = int(period) 333 334 exit_event = m5.simulate(when) 335 while exit_event.getCause() == "checkpoint": 336 exit_event = m5.simulate(when - m5.curTick()) 337 338 if exit_event.getCause() == "simulate() limit reached": 339 m5.checkpoint(joinpath(cptdir, "cpt.%d")) 340 num_checkpoints += 1 341 342 sim_ticks = when 343 exit_cause = "maximum %d checkpoints dropped" % max_checkpoints 344 while num_checkpoints < max_checkpoints and \ 345 exit_event.getCause() == "simulate() limit reached": 346 if (sim_ticks + period) > maxtick: 347 exit_event = m5.simulate(maxtick - sim_ticks) 348 exit_cause = exit_event.getCause() 349 break 350 else: 351 exit_event = m5.simulate(period) 352 sim_ticks += period 353 while exit_event.getCause() == "checkpoint": 354 exit_event = m5.simulate(sim_ticks - m5.curTick()) 355 if exit_event.getCause() == "simulate() limit reached": 356 m5.checkpoint(joinpath(cptdir, "cpt.%d")) 357 num_checkpoints += 1 358 359 if exit_event.getCause() != "simulate() limit reached": 360 exit_cause = exit_event.getCause(); 361 362 else: # no checkpoints being taken via this script 363 if options.fast_forward: 364 m5.stats.reset() 365 print "**** REAL SIMULATION ****" 366 exit_event = m5.simulate(maxtick) 367 368 while exit_event.getCause() == "checkpoint": 369 m5.checkpoint(joinpath(cptdir, "cpt.%d")) 370 num_checkpoints += 1 371 if num_checkpoints == max_checkpoints: 372 exit_cause = "maximum %d checkpoints dropped" % max_checkpoints 373 break 374 375 exit_event = m5.simulate(maxtick - m5.curTick()) 376 exit_cause = exit_event.getCause() 377 378 if exit_cause == '': 379 exit_cause = exit_event.getCause() 380 print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause) 381 382 if options.checkpoint_at_end: 383 m5.checkpoint(joinpath(cptdir, "cpt.%d")) 384
|