configs: Fix relative import in non-package in configs
[gem5.git] / configs / common / Simulation.py
1 # Copyright (c) 2012-2013 ARM Limited
2 # All rights reserved
3 #
4 # The license below extends only to copyright in the software and shall
5 # not be construed as granting a license to any other intellectual
6 # property including but not limited to intellectual property relating
7 # to a hardware implementation of the functionality of the software
8 # licensed hereunder. You may use the software subject to the license
9 # terms below provided that you ensure that this notice is replicated
10 # unmodified and in its entirety in all distributions of the software,
11 # modified or unmodified, in source code or in binary form.
12 #
13 # Copyright (c) 2006-2008 The Regents of The University of Michigan
14 # Copyright (c) 2010 Advanced Micro Devices, Inc.
15 # All rights reserved.
16 #
17 # Redistribution and use in source and binary forms, with or without
18 # modification, are permitted provided that the following conditions are
19 # met: redistributions of source code must retain the above copyright
20 # notice, this list of conditions and the following disclaimer;
21 # redistributions in binary form must reproduce the above copyright
22 # notice, this list of conditions and the following disclaimer in the
23 # documentation and/or other materials provided with the distribution;
24 # neither the name of the copyright holders nor the names of its
25 # contributors may be used to endorse or promote products derived from
26 # this software without specific prior written permission.
27 #
28 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
40 from __future__ import print_function
41 from __future__ import absolute_import
42
43 import sys
44 from os import getcwd
45 from os.path import join as joinpath
46
47 from common import CpuConfig
48 from common import ObjectList
49
50 import m5
51 from m5.defines import buildEnv
52 from m5.objects import *
53 from m5.util import *
54
55 addToPath('../common')
56
57 def getCPUClass(cpu_type):
58 """Returns the required cpu class and the mode of operation."""
59 cls = ObjectList.cpu_list.get(cpu_type)
60 return cls, cls.memory_mode()
61
62 def setCPUClass(options):
63 """Returns two cpu classes and the initial mode of operation.
64
65 Restoring from a checkpoint or fast forwarding through a benchmark
66 can be done using one type of cpu, and then the actual
67 simulation can be carried out using another type. This function
68 returns these two types of cpus and the initial mode of operation
69 depending on the options provided.
70 """
71
72 TmpClass, test_mem_mode = getCPUClass(options.cpu_type)
73 CPUClass = None
74 if TmpClass.require_caches() and \
75 not options.caches and not options.ruby:
76 fatal("%s must be used with caches" % options.cpu_type)
77
78 if options.checkpoint_restore != None:
79 if options.restore_with_cpu != options.cpu_type:
80 CPUClass = TmpClass
81 TmpClass, test_mem_mode = getCPUClass(options.restore_with_cpu)
82 elif options.fast_forward:
83 CPUClass = TmpClass
84 TmpClass = AtomicSimpleCPU
85 test_mem_mode = 'atomic'
86
87 # Ruby only supports atomic accesses in noncaching mode
88 if test_mem_mode == 'atomic' and options.ruby:
89 warn("Memory mode will be changed to atomic_noncaching")
90 test_mem_mode = 'atomic_noncaching'
91
92 return (TmpClass, test_mem_mode, CPUClass)
93
94 def setMemClass(options):
95 """Returns a memory controller class."""
96
97 return ObjectList.mem_list.get(options.mem_type)
98
99 def setWorkCountOptions(system, options):
100 if options.work_item_id != None:
101 system.work_item_id = options.work_item_id
102 if options.num_work_ids != None:
103 system.num_work_ids = options.num_work_ids
104 if options.work_begin_cpu_id_exit != None:
105 system.work_begin_cpu_id_exit = options.work_begin_cpu_id_exit
106 if options.work_end_exit_count != None:
107 system.work_end_exit_count = options.work_end_exit_count
108 if options.work_end_checkpoint_count != None:
109 system.work_end_ckpt_count = options.work_end_checkpoint_count
110 if options.work_begin_exit_count != None:
111 system.work_begin_exit_count = options.work_begin_exit_count
112 if options.work_begin_checkpoint_count != None:
113 system.work_begin_ckpt_count = options.work_begin_checkpoint_count
114 if options.work_cpus_checkpoint_count != None:
115 system.work_cpus_ckpt_count = options.work_cpus_checkpoint_count
116
117 def findCptDir(options, cptdir, testsys):
118 """Figures out the directory from which the checkpointed state is read.
119
120 There are two different ways in which the directories holding checkpoints
121 can be named --
122 1. cpt.<benchmark name>.<instruction count when the checkpoint was taken>
123 2. cpt.<some number, usually the tick value when the checkpoint was taken>
124
125 This function parses through the options to figure out which one of the
126 above should be used for selecting the checkpoint, and then figures out
127 the appropriate directory.
128 """
129
130 from os.path import isdir, exists
131 from os import listdir
132 import re
133
134 if not isdir(cptdir):
135 fatal("checkpoint dir %s does not exist!", cptdir)
136
137 cpt_starttick = 0
138 if options.at_instruction or options.simpoint:
139 inst = options.checkpoint_restore
140 if options.simpoint:
141 # assume workload 0 has the simpoint
142 if testsys.cpu[0].workload[0].simpoint == 0:
143 fatal('Unable to find simpoint')
144 inst += int(testsys.cpu[0].workload[0].simpoint)
145
146 checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst))
147 if not exists(checkpoint_dir):
148 fatal("Unable to find checkpoint directory %s", checkpoint_dir)
149
150 elif options.restore_simpoint_checkpoint:
151 # Restore from SimPoint checkpoints
152 # Assumes that the checkpoint dir names are formatted as follows:
153 dirs = listdir(cptdir)
154 expr = re.compile('cpt\.simpoint_(\d+)_inst_(\d+)' +
155 '_weight_([\d\.e\-]+)_interval_(\d+)_warmup_(\d+)')
156 cpts = []
157 for dir in dirs:
158 match = expr.match(dir)
159 if match:
160 cpts.append(dir)
161 cpts.sort()
162
163 cpt_num = options.checkpoint_restore
164 if cpt_num > len(cpts):
165 fatal('Checkpoint %d not found', cpt_num)
166 checkpoint_dir = joinpath(cptdir, cpts[cpt_num - 1])
167 match = expr.match(cpts[cpt_num - 1])
168 if match:
169 index = int(match.group(1))
170 start_inst = int(match.group(2))
171 weight_inst = float(match.group(3))
172 interval_length = int(match.group(4))
173 warmup_length = int(match.group(5))
174 print("Resuming from", checkpoint_dir)
175 simpoint_start_insts = []
176 simpoint_start_insts.append(warmup_length)
177 simpoint_start_insts.append(warmup_length + interval_length)
178 testsys.cpu[0].simpoint_start_insts = simpoint_start_insts
179 if testsys.switch_cpus != None:
180 testsys.switch_cpus[0].simpoint_start_insts = simpoint_start_insts
181
182 print("Resuming from SimPoint", end=' ')
183 print("#%d, start_inst:%d, weight:%f, interval:%d, warmup:%d" %
184 (index, start_inst, weight_inst, interval_length, warmup_length))
185
186 else:
187 dirs = listdir(cptdir)
188 expr = re.compile('cpt\.([0-9]+)')
189 cpts = []
190 for dir in dirs:
191 match = expr.match(dir)
192 if match:
193 cpts.append(match.group(1))
194
195 cpts.sort(lambda a,b: cmp(long(a), long(b)))
196
197 cpt_num = options.checkpoint_restore
198 if cpt_num > len(cpts):
199 fatal('Checkpoint %d not found', cpt_num)
200
201 cpt_starttick = int(cpts[cpt_num - 1])
202 checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1])
203
204 return cpt_starttick, checkpoint_dir
205
206 def scriptCheckpoints(options, maxtick, cptdir):
207 if options.at_instruction or options.simpoint:
208 checkpoint_inst = int(options.take_checkpoints)
209
210 # maintain correct offset if we restored from some instruction
211 if options.checkpoint_restore != None:
212 checkpoint_inst += options.checkpoint_restore
213
214 print("Creating checkpoint at inst:%d" % (checkpoint_inst))
215 exit_event = m5.simulate()
216 exit_cause = exit_event.getCause()
217 print("exit cause = %s" % exit_cause)
218
219 # skip checkpoint instructions should they exist
220 while exit_cause == "checkpoint":
221 exit_event = m5.simulate()
222 exit_cause = exit_event.getCause()
223
224 if exit_cause == "a thread reached the max instruction count":
225 m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \
226 (options.bench, checkpoint_inst)))
227 print("Checkpoint written.")
228
229 else:
230 when, period = options.take_checkpoints.split(",", 1)
231 when = int(when)
232 period = int(period)
233 num_checkpoints = 0
234
235 exit_event = m5.simulate(when - m5.curTick())
236 exit_cause = exit_event.getCause()
237 while exit_cause == "checkpoint":
238 exit_event = m5.simulate(when - m5.curTick())
239 exit_cause = exit_event.getCause()
240
241 if exit_cause == "simulate() limit reached":
242 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
243 num_checkpoints += 1
244
245 sim_ticks = when
246 max_checkpoints = options.max_checkpoints
247
248 while num_checkpoints < max_checkpoints and \
249 exit_cause == "simulate() limit reached":
250 if (sim_ticks + period) > maxtick:
251 exit_event = m5.simulate(maxtick - sim_ticks)
252 exit_cause = exit_event.getCause()
253 break
254 else:
255 exit_event = m5.simulate(period)
256 exit_cause = exit_event.getCause()
257 sim_ticks += period
258 while exit_event.getCause() == "checkpoint":
259 exit_event = m5.simulate(sim_ticks - m5.curTick())
260 if exit_event.getCause() == "simulate() limit reached":
261 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
262 num_checkpoints += 1
263
264 return exit_event
265
266 def benchCheckpoints(options, maxtick, cptdir):
267 exit_event = m5.simulate(maxtick - m5.curTick())
268 exit_cause = exit_event.getCause()
269
270 num_checkpoints = 0
271 max_checkpoints = options.max_checkpoints
272
273 while exit_cause == "checkpoint":
274 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
275 num_checkpoints += 1
276 if num_checkpoints == max_checkpoints:
277 exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
278 break
279
280 exit_event = m5.simulate(maxtick - m5.curTick())
281 exit_cause = exit_event.getCause()
282
283 return exit_event
284
285 # Set up environment for taking SimPoint checkpoints
286 # Expecting SimPoint files generated by SimPoint 3.2
287 def parseSimpointAnalysisFile(options, testsys):
288 import re
289
290 simpoint_filename, weight_filename, interval_length, warmup_length = \
291 options.take_simpoint_checkpoints.split(",", 3)
292 print("simpoint analysis file:", simpoint_filename)
293 print("simpoint weight file:", weight_filename)
294 print("interval length:", interval_length)
295 print("warmup length:", warmup_length)
296
297 interval_length = int(interval_length)
298 warmup_length = int(warmup_length)
299
300 # Simpoint analysis output starts interval counts with 0.
301 simpoints = []
302 simpoint_start_insts = []
303
304 # Read in SimPoint analysis files
305 simpoint_file = open(simpoint_filename)
306 weight_file = open(weight_filename)
307 while True:
308 line = simpoint_file.readline()
309 if not line:
310 break
311 m = re.match("(\d+)\s+(\d+)", line)
312 if m:
313 interval = int(m.group(1))
314 else:
315 fatal('unrecognized line in simpoint file!')
316
317 line = weight_file.readline()
318 if not line:
319 fatal('not enough lines in simpoint weight file!')
320 m = re.match("([0-9\.e\-]+)\s+(\d+)", line)
321 if m:
322 weight = float(m.group(1))
323 else:
324 fatal('unrecognized line in simpoint weight file!')
325
326 if (interval * interval_length - warmup_length > 0):
327 starting_inst_count = \
328 interval * interval_length - warmup_length
329 actual_warmup_length = warmup_length
330 else:
331 # Not enough room for proper warmup
332 # Just starting from the beginning
333 starting_inst_count = 0
334 actual_warmup_length = interval * interval_length
335
336 simpoints.append((interval, weight, starting_inst_count,
337 actual_warmup_length))
338
339 # Sort SimPoints by starting inst count
340 simpoints.sort(key=lambda obj: obj[2])
341 for s in simpoints:
342 interval, weight, starting_inst_count, actual_warmup_length = s
343 print(str(interval), str(weight), starting_inst_count,
344 actual_warmup_length)
345 simpoint_start_insts.append(starting_inst_count)
346
347 print("Total # of simpoints:", len(simpoints))
348 testsys.cpu[0].simpoint_start_insts = simpoint_start_insts
349
350 return (simpoints, interval_length)
351
352 def takeSimpointCheckpoints(simpoints, interval_length, cptdir):
353 num_checkpoints = 0
354 index = 0
355 last_chkpnt_inst_count = -1
356 for simpoint in simpoints:
357 interval, weight, starting_inst_count, actual_warmup_length = simpoint
358 if starting_inst_count == last_chkpnt_inst_count:
359 # checkpoint starting point same as last time
360 # (when warmup period longer than starting point)
361 exit_cause = "simpoint starting point found"
362 code = 0
363 else:
364 exit_event = m5.simulate()
365
366 # skip checkpoint instructions should they exist
367 while exit_event.getCause() == "checkpoint":
368 print("Found 'checkpoint' exit event...ignoring...")
369 exit_event = m5.simulate()
370
371 exit_cause = exit_event.getCause()
372 code = exit_event.getCode()
373
374 if exit_cause == "simpoint starting point found":
375 m5.checkpoint(joinpath(cptdir,
376 "cpt.simpoint_%02d_inst_%d_weight_%f_interval_%d_warmup_%d"
377 % (index, starting_inst_count, weight, interval_length,
378 actual_warmup_length)))
379 print("Checkpoint #%d written. start inst:%d weight:%f" %
380 (num_checkpoints, starting_inst_count, weight))
381 num_checkpoints += 1
382 last_chkpnt_inst_count = starting_inst_count
383 else:
384 break
385 index += 1
386
387 print('Exiting @ tick %i because %s' % (m5.curTick(), exit_cause))
388 print("%d checkpoints taken" % num_checkpoints)
389 sys.exit(code)
390
391 def restoreSimpointCheckpoint():
392 exit_event = m5.simulate()
393 exit_cause = exit_event.getCause()
394
395 if exit_cause == "simpoint starting point found":
396 print("Warmed up! Dumping and resetting stats!")
397 m5.stats.dump()
398 m5.stats.reset()
399
400 exit_event = m5.simulate()
401 exit_cause = exit_event.getCause()
402
403 if exit_cause == "simpoint starting point found":
404 print("Done running SimPoint!")
405 sys.exit(exit_event.getCode())
406
407 print('Exiting @ tick %i because %s' % (m5.curTick(), exit_cause))
408 sys.exit(exit_event.getCode())
409
410 def repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq):
411 print("starting switch loop")
412 while True:
413 exit_event = m5.simulate(switch_freq)
414 exit_cause = exit_event.getCause()
415
416 if exit_cause != "simulate() limit reached":
417 return exit_event
418
419 m5.switchCpus(testsys, repeat_switch_cpu_list)
420
421 tmp_cpu_list = []
422 for old_cpu, new_cpu in repeat_switch_cpu_list:
423 tmp_cpu_list.append((new_cpu, old_cpu))
424 repeat_switch_cpu_list = tmp_cpu_list
425
426 if (maxtick - m5.curTick()) <= switch_freq:
427 exit_event = m5.simulate(maxtick - m5.curTick())
428 return exit_event
429
430 def run(options, root, testsys, cpu_class):
431 if options.checkpoint_dir:
432 cptdir = options.checkpoint_dir
433 elif m5.options.outdir:
434 cptdir = m5.options.outdir
435 else:
436 cptdir = getcwd()
437
438 if options.fast_forward and options.checkpoint_restore != None:
439 fatal("Can't specify both --fast-forward and --checkpoint-restore")
440
441 if options.standard_switch and not options.caches:
442 fatal("Must specify --caches when using --standard-switch")
443
444 if options.standard_switch and options.repeat_switch:
445 fatal("Can't specify both --standard-switch and --repeat-switch")
446
447 if options.repeat_switch and options.take_checkpoints:
448 fatal("Can't specify both --repeat-switch and --take-checkpoints")
449
450 np = options.num_cpus
451 switch_cpus = None
452
453 if options.prog_interval:
454 for i in range(np):
455 testsys.cpu[i].progress_interval = options.prog_interval
456
457 if options.maxinsts:
458 for i in range(np):
459 testsys.cpu[i].max_insts_any_thread = options.maxinsts
460
461 if cpu_class:
462 switch_cpus = [cpu_class(switched_out=True, cpu_id=(i))
463 for i in range(np)]
464
465 for i in range(np):
466 if options.fast_forward:
467 testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
468 switch_cpus[i].system = testsys
469 switch_cpus[i].workload = testsys.cpu[i].workload
470 switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
471 switch_cpus[i].progress_interval = \
472 testsys.cpu[i].progress_interval
473 switch_cpus[i].isa = testsys.cpu[i].isa
474 # simulation period
475 if options.maxinsts:
476 switch_cpus[i].max_insts_any_thread = options.maxinsts
477 # Add checker cpu if selected
478 if options.checker:
479 switch_cpus[i].addCheckerCpu()
480 if options.bp_type:
481 bpClass = ObjectList.bp_list.get(options.bp_type)
482 switch_cpus[i].branchPred = bpClass()
483 if options.indirect_bp_type:
484 IndirectBPClass = ObjectList.indirect_bp_list.get(
485 options.indirect_bp_type)
486 switch_cpus[i].branchPred.indirectBranchPred = \
487 IndirectBPClass()
488
489 # If elastic tracing is enabled attach the elastic trace probe
490 # to the switch CPUs
491 if options.elastic_trace_en:
492 CpuConfig.config_etrace(cpu_class, switch_cpus, options)
493
494 testsys.switch_cpus = switch_cpus
495 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in range(np)]
496
497 if options.repeat_switch:
498 switch_class = getCPUClass(options.cpu_type)[0]
499 if switch_class.require_caches() and \
500 not options.caches:
501 print("%s: Must be used with caches" % str(switch_class))
502 sys.exit(1)
503 if not switch_class.support_take_over():
504 print("%s: CPU switching not supported" % str(switch_class))
505 sys.exit(1)
506
507 repeat_switch_cpus = [switch_class(switched_out=True, \
508 cpu_id=(i)) for i in range(np)]
509
510 for i in range(np):
511 repeat_switch_cpus[i].system = testsys
512 repeat_switch_cpus[i].workload = testsys.cpu[i].workload
513 repeat_switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
514 repeat_switch_cpus[i].isa = testsys.cpu[i].isa
515
516 if options.maxinsts:
517 repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts
518
519 if options.checker:
520 repeat_switch_cpus[i].addCheckerCpu()
521
522 testsys.repeat_switch_cpus = repeat_switch_cpus
523
524 if cpu_class:
525 repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i])
526 for i in range(np)]
527 else:
528 repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i])
529 for i in range(np)]
530
531 if options.standard_switch:
532 switch_cpus = [TimingSimpleCPU(switched_out=True, cpu_id=(i))
533 for i in range(np)]
534 switch_cpus_1 = [DerivO3CPU(switched_out=True, cpu_id=(i))
535 for i in range(np)]
536
537 for i in range(np):
538 switch_cpus[i].system = testsys
539 switch_cpus_1[i].system = testsys
540 switch_cpus[i].workload = testsys.cpu[i].workload
541 switch_cpus_1[i].workload = testsys.cpu[i].workload
542 switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain
543 switch_cpus_1[i].clk_domain = testsys.cpu[i].clk_domain
544 switch_cpus[i].isa = testsys.cpu[i].isa
545 switch_cpus_1[i].isa = testsys.cpu[i].isa
546
547 # if restoring, make atomic cpu simulate only a few instructions
548 if options.checkpoint_restore != None:
549 testsys.cpu[i].max_insts_any_thread = 1
550 # Fast forward to specified location if we are not restoring
551 elif options.fast_forward:
552 testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
553 # Fast forward to a simpoint (warning: time consuming)
554 elif options.simpoint:
555 if testsys.cpu[i].workload[0].simpoint == 0:
556 fatal('simpoint not found')
557 testsys.cpu[i].max_insts_any_thread = \
558 testsys.cpu[i].workload[0].simpoint
559 # No distance specified, just switch
560 else:
561 testsys.cpu[i].max_insts_any_thread = 1
562
563 # warmup period
564 if options.warmup_insts:
565 switch_cpus[i].max_insts_any_thread = options.warmup_insts
566
567 # simulation period
568 if options.maxinsts:
569 switch_cpus_1[i].max_insts_any_thread = options.maxinsts
570
571 # attach the checker cpu if selected
572 if options.checker:
573 switch_cpus[i].addCheckerCpu()
574 switch_cpus_1[i].addCheckerCpu()
575
576 testsys.switch_cpus = switch_cpus
577 testsys.switch_cpus_1 = switch_cpus_1
578 switch_cpu_list = [
579 (testsys.cpu[i], switch_cpus[i]) for i in range(np)
580 ]
581 switch_cpu_list1 = [
582 (switch_cpus[i], switch_cpus_1[i]) for i in range(np)
583 ]
584
585 # set the checkpoint in the cpu before m5.instantiate is called
586 if options.take_checkpoints != None and \
587 (options.simpoint or options.at_instruction):
588 offset = int(options.take_checkpoints)
589 # Set an instruction break point
590 if options.simpoint:
591 for i in range(np):
592 if testsys.cpu[i].workload[0].simpoint == 0:
593 fatal('no simpoint for testsys.cpu[%d].workload[0]', i)
594 checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
595 testsys.cpu[i].max_insts_any_thread = checkpoint_inst
596 # used for output below
597 options.take_checkpoints = checkpoint_inst
598 else:
599 options.take_checkpoints = offset
600 # Set all test cpus with the right number of instructions
601 # for the upcoming simulation
602 for i in range(np):
603 testsys.cpu[i].max_insts_any_thread = offset
604
605 if options.take_simpoint_checkpoints != None:
606 simpoints, interval_length = parseSimpointAnalysisFile(options, testsys)
607
608 checkpoint_dir = None
609 if options.checkpoint_restore:
610 cpt_starttick, checkpoint_dir = findCptDir(options, cptdir, testsys)
611 root.apply_config(options.param)
612 m5.instantiate(checkpoint_dir)
613
614 # Initialization is complete. If we're not in control of simulation
615 # (that is, if we're a slave simulator acting as a component in another
616 # 'master' simulator) then we're done here. The other simulator will
617 # call simulate() directly. --initialize-only is used to indicate this.
618 if options.initialize_only:
619 return
620
621 # Handle the max tick settings now that tick frequency was resolved
622 # during system instantiation
623 # NOTE: the maxtick variable here is in absolute ticks, so it must
624 # include any simulated ticks before a checkpoint
625 explicit_maxticks = 0
626 maxtick_from_abs = m5.MaxTick
627 maxtick_from_rel = m5.MaxTick
628 maxtick_from_maxtime = m5.MaxTick
629 if options.abs_max_tick:
630 maxtick_from_abs = options.abs_max_tick
631 explicit_maxticks += 1
632 if options.rel_max_tick:
633 maxtick_from_rel = options.rel_max_tick
634 if options.checkpoint_restore:
635 # NOTE: this may need to be updated if checkpoints ever store
636 # the ticks per simulated second
637 maxtick_from_rel += cpt_starttick
638 if options.at_instruction or options.simpoint:
639 warn("Relative max tick specified with --at-instruction or" \
640 " --simpoint\n These options don't specify the " \
641 "checkpoint start tick, so assuming\n you mean " \
642 "absolute max tick")
643 explicit_maxticks += 1
644 if options.maxtime:
645 maxtick_from_maxtime = m5.ticks.fromSeconds(options.maxtime)
646 explicit_maxticks += 1
647 if explicit_maxticks > 1:
648 warn("Specified multiple of --abs-max-tick, --rel-max-tick, --maxtime."\
649 " Using least")
650 maxtick = min([maxtick_from_abs, maxtick_from_rel, maxtick_from_maxtime])
651
652 if options.checkpoint_restore != None and maxtick < cpt_starttick:
653 fatal("Bad maxtick (%d) specified: " \
654 "Checkpoint starts starts from tick: %d", maxtick, cpt_starttick)
655
656 if options.standard_switch or cpu_class:
657 if options.standard_switch:
658 print("Switch at instruction count:%s" %
659 str(testsys.cpu[0].max_insts_any_thread))
660 exit_event = m5.simulate()
661 elif cpu_class and options.fast_forward:
662 print("Switch at instruction count:%s" %
663 str(testsys.cpu[0].max_insts_any_thread))
664 exit_event = m5.simulate()
665 else:
666 print("Switch at curTick count:%s" % str(10000))
667 exit_event = m5.simulate(10000)
668 print("Switched CPUS @ tick %s" % (m5.curTick()))
669
670 m5.switchCpus(testsys, switch_cpu_list)
671
672 if options.standard_switch:
673 print("Switch at instruction count:%d" %
674 (testsys.switch_cpus[0].max_insts_any_thread))
675
676 #warmup instruction count may have already been set
677 if options.warmup_insts:
678 exit_event = m5.simulate()
679 else:
680 exit_event = m5.simulate(options.standard_switch)
681 print("Switching CPUS @ tick %s" % (m5.curTick()))
682 print("Simulation ends instruction count:%d" %
683 (testsys.switch_cpus_1[0].max_insts_any_thread))
684 m5.switchCpus(testsys, switch_cpu_list1)
685
686 # If we're taking and restoring checkpoints, use checkpoint_dir
687 # option only for finding the checkpoints to restore from. This
688 # lets us test checkpointing by restoring from one set of
689 # checkpoints, generating a second set, and then comparing them.
690 if (options.take_checkpoints or options.take_simpoint_checkpoints) \
691 and options.checkpoint_restore:
692
693 if m5.options.outdir:
694 cptdir = m5.options.outdir
695 else:
696 cptdir = getcwd()
697
698 if options.take_checkpoints != None :
699 # Checkpoints being taken via the command line at <when> and at
700 # subsequent periods of <period>. Checkpoint instructions
701 # received from the benchmark running are ignored and skipped in
702 # favor of command line checkpoint instructions.
703 exit_event = scriptCheckpoints(options, maxtick, cptdir)
704
705 # Take SimPoint checkpoints
706 elif options.take_simpoint_checkpoints != None:
707 takeSimpointCheckpoints(simpoints, interval_length, cptdir)
708
709 # Restore from SimPoint checkpoints
710 elif options.restore_simpoint_checkpoint != None:
711 restoreSimpointCheckpoint()
712
713 else:
714 if options.fast_forward:
715 m5.stats.reset()
716 print("**** REAL SIMULATION ****")
717
718 # If checkpoints are being taken, then the checkpoint instruction
719 # will occur in the benchmark code it self.
720 if options.repeat_switch and maxtick > options.repeat_switch:
721 exit_event = repeatSwitch(testsys, repeat_switch_cpu_list,
722 maxtick, options.repeat_switch)
723 else:
724 exit_event = benchCheckpoints(options, maxtick, cptdir)
725
726 print('Exiting @ tick %i because %s' %
727 (m5.curTick(), exit_event.getCause()))
728 if options.checkpoint_at_end:
729 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
730
731 if exit_event.getCode() != 0:
732 print("Simulated exit code not 0! Exit code is", exit_event.getCode())