Simulation.py (8919:c1366a30d5eb) Simulation.py (9129:b57966a6c512)
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
83def setWorkCountOptions(system, options):
84 if options.work_item_id != None:
85 system.work_item_id = options.work_item_id
86 if options.work_begin_cpu_id_exit != None:
87 system.work_begin_cpu_id_exit = options.work_begin_cpu_id_exit
88 if options.work_end_exit_count != None:
89 system.work_end_exit_count = options.work_end_exit_count
90 if options.work_end_checkpoint_count != None:
91 system.work_end_ckpt_count = options.work_end_checkpoint_count
92 if options.work_begin_exit_count != None:
93 system.work_begin_exit_count = options.work_begin_exit_count
94 if options.work_begin_checkpoint_count != None:
95 system.work_begin_ckpt_count = options.work_begin_checkpoint_count
96 if options.work_cpus_checkpoint_count != None:
97 system.work_cpus_ckpt_count = options.work_cpus_checkpoint_count
98
99def run(options, root, testsys, cpu_class):
100 if options.maxtick:
101 maxtick = options.maxtick
102 elif options.maxtime:
103 simtime = m5.ticks.seconds(simtime)
104 print "simulating for: ", simtime
105 maxtick = simtime
106 else:
107 maxtick = m5.MaxTick
108
109 if options.checkpoint_dir:
110 cptdir = options.checkpoint_dir
111 elif m5.options.outdir:
112 cptdir = m5.options.outdir
113 else:
114 cptdir = getcwd()
115
116 if options.fast_forward and options.checkpoint_restore != None:
117 fatal("Can't specify both --fast-forward and --checkpoint-restore")
118
119 if options.standard_switch and not options.caches:
120 fatal("Must specify --caches when using --standard-switch")
121
122 np = options.num_cpus
123 max_checkpoints = options.max_checkpoints
124 switch_cpus = None
125
126 if options.prog_interval:
127 for i in xrange(np):
128 testsys.cpu[i].progress_interval = options.prog_interval
129
130 if options.maxinsts:
131 for i in xrange(np):
132 testsys.cpu[i].max_insts_any_thread = options.maxinsts
133
134 if cpu_class:
135 switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i))
136 for i in xrange(np)]
137
138 for i in xrange(np):
139 if options.fast_forward:
140 testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
141 switch_cpus[i].system = testsys
142 switch_cpus[i].workload = testsys.cpu[i].workload
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
83def setWorkCountOptions(system, options):
84 if options.work_item_id != None:
85 system.work_item_id = options.work_item_id
86 if options.work_begin_cpu_id_exit != None:
87 system.work_begin_cpu_id_exit = options.work_begin_cpu_id_exit
88 if options.work_end_exit_count != None:
89 system.work_end_exit_count = options.work_end_exit_count
90 if options.work_end_checkpoint_count != None:
91 system.work_end_ckpt_count = options.work_end_checkpoint_count
92 if options.work_begin_exit_count != None:
93 system.work_begin_exit_count = options.work_begin_exit_count
94 if options.work_begin_checkpoint_count != None:
95 system.work_begin_ckpt_count = options.work_begin_checkpoint_count
96 if options.work_cpus_checkpoint_count != None:
97 system.work_cpus_ckpt_count = options.work_cpus_checkpoint_count
98
99def run(options, root, testsys, cpu_class):
100 if options.maxtick:
101 maxtick = options.maxtick
102 elif options.maxtime:
103 simtime = m5.ticks.seconds(simtime)
104 print "simulating for: ", simtime
105 maxtick = simtime
106 else:
107 maxtick = m5.MaxTick
108
109 if options.checkpoint_dir:
110 cptdir = options.checkpoint_dir
111 elif m5.options.outdir:
112 cptdir = m5.options.outdir
113 else:
114 cptdir = getcwd()
115
116 if options.fast_forward and options.checkpoint_restore != None:
117 fatal("Can't specify both --fast-forward and --checkpoint-restore")
118
119 if options.standard_switch and not options.caches:
120 fatal("Must specify --caches when using --standard-switch")
121
122 np = options.num_cpus
123 max_checkpoints = options.max_checkpoints
124 switch_cpus = None
125
126 if options.prog_interval:
127 for i in xrange(np):
128 testsys.cpu[i].progress_interval = options.prog_interval
129
130 if options.maxinsts:
131 for i in xrange(np):
132 testsys.cpu[i].max_insts_any_thread = options.maxinsts
133
134 if cpu_class:
135 switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i))
136 for i in xrange(np)]
137
138 for i in xrange(np):
139 if options.fast_forward:
140 testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
141 switch_cpus[i].system = testsys
142 switch_cpus[i].workload = testsys.cpu[i].workload
143 switch_cpus[i].clock = testsys.cpu[0].clock
143 switch_cpus[i].clock = testsys.cpu[i].clock
144 # simulation period
145 if options.maxinsts:
146 switch_cpus[i].max_insts_any_thread = options.maxinsts
147 # Add checker cpu if selected
148 if options.checker:
149 switch_cpus[i].addCheckerCpu()
150
151 testsys.switch_cpus = switch_cpus
152 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
153
154 if options.standard_switch:
155 if not options.caches:
156 # O3 CPU must have a cache to work.
157 print "O3 CPU must be used with caches"
158 sys.exit(1)
159
160 switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i))
161 for i in xrange(np)]
162 switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i))
163 for i in xrange(np)]
164
165 for i in xrange(np):
166 switch_cpus[i].system = testsys
167 switch_cpus_1[i].system = testsys
168 switch_cpus[i].workload = testsys.cpu[i].workload
169 switch_cpus_1[i].workload = testsys.cpu[i].workload
144 # simulation period
145 if options.maxinsts:
146 switch_cpus[i].max_insts_any_thread = options.maxinsts
147 # Add checker cpu if selected
148 if options.checker:
149 switch_cpus[i].addCheckerCpu()
150
151 testsys.switch_cpus = switch_cpus
152 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
153
154 if options.standard_switch:
155 if not options.caches:
156 # O3 CPU must have a cache to work.
157 print "O3 CPU must be used with caches"
158 sys.exit(1)
159
160 switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i))
161 for i in xrange(np)]
162 switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i))
163 for i in xrange(np)]
164
165 for i in xrange(np):
166 switch_cpus[i].system = testsys
167 switch_cpus_1[i].system = testsys
168 switch_cpus[i].workload = testsys.cpu[i].workload
169 switch_cpus_1[i].workload = testsys.cpu[i].workload
170 switch_cpus[i].clock = testsys.cpu[0].clock
171 switch_cpus_1[i].clock = testsys.cpu[0].clock
170 switch_cpus[i].clock = testsys.cpu[i].clock
171 switch_cpus_1[i].clock = testsys.cpu[i].clock
172
173 # if restoring, make atomic cpu simulate only a few instructions
174 if options.checkpoint_restore != None:
175 testsys.cpu[i].max_insts_any_thread = 1
176 # Fast forward to specified location if we are not restoring
177 elif options.fast_forward:
178 testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
179 # Fast forward to a simpoint (warning: time consuming)
180 elif options.simpoint:
181 if testsys.cpu[i].workload[0].simpoint == 0:
182 fatal('simpoint not found')
183 testsys.cpu[i].max_insts_any_thread = \
184 testsys.cpu[i].workload[0].simpoint
185 # No distance specified, just switch
186 else:
187 testsys.cpu[i].max_insts_any_thread = 1
188
189 # warmup period
190 if options.warmup_insts:
191 switch_cpus[i].max_insts_any_thread = options.warmup_insts
192
193 # simulation period
194 if options.maxinsts:
195 switch_cpus_1[i].max_insts_any_thread = options.maxinsts
196
197 # attach the checker cpu if selected
198 if options.checker:
199 switch_cpus[i].addCheckerCpu()
200 switch_cpus_1[i].addCheckerCpu()
201
202 testsys.switch_cpus = switch_cpus
203 testsys.switch_cpus_1 = switch_cpus_1
204 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
205 switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)]
206
207 # set the checkpoint in the cpu before m5.instantiate is called
208 if options.take_checkpoints != None and \
209 (options.simpoint or options.at_instruction):
210 offset = int(options.take_checkpoints)
211 # Set an instruction break point
212 if options.simpoint:
213 for i in xrange(np):
214 if testsys.cpu[i].workload[0].simpoint == 0:
215 fatal('no simpoint for testsys.cpu[%d].workload[0]', i)
216 checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
217 testsys.cpu[i].max_insts_any_thread = checkpoint_inst
218 # used for output below
219 options.take_checkpoints = checkpoint_inst
220 else:
221 options.take_checkpoints = offset
222 # Set all test cpus with the right number of instructions
223 # for the upcoming simulation
224 for i in xrange(np):
225 testsys.cpu[i].max_insts_any_thread = offset
226
227 checkpoint_dir = None
228 if options.checkpoint_restore != None:
229 from os.path import isdir, exists
230 from os import listdir
231 import re
232
233 if not isdir(cptdir):
234 fatal("checkpoint dir %s does not exist!", cptdir)
235
236 if options.at_instruction or options.simpoint:
237 inst = options.checkpoint_restore
238 if options.simpoint:
239 # assume workload 0 has the simpoint
240 if testsys.cpu[0].workload[0].simpoint == 0:
241 fatal('Unable to find simpoint')
242 inst += int(testsys.cpu[0].workload[0].simpoint)
243
244 checkpoint_dir = joinpath(cptdir,
245 "cpt.%s.%s" % (options.bench, inst))
246 if not exists(checkpoint_dir):
247 fatal("Unable to find checkpoint directory %s", checkpoint_dir)
248 else:
249 dirs = listdir(cptdir)
250 expr = re.compile('cpt\.([0-9]*)')
251 cpts = []
252 for dir in dirs:
253 match = expr.match(dir)
254 if match:
255 cpts.append(match.group(1))
256
257 cpts.sort(lambda a,b: cmp(long(a), long(b)))
258
259 cpt_num = options.checkpoint_restore
260
261 if cpt_num > len(cpts):
262 fatal('Checkpoint %d not found', cpt_num)
263
264 ## Adjust max tick based on our starting tick
265 maxtick = maxtick - int(cpts[cpt_num - 1])
266 checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1])
267
268 m5.instantiate(checkpoint_dir)
269
270 if options.standard_switch or cpu_class:
271 if options.standard_switch:
272 print "Switch at instruction count:%s" % \
273 str(testsys.cpu[0].max_insts_any_thread)
274 exit_event = m5.simulate()
275 elif cpu_class and options.fast_forward:
276 print "Switch at instruction count:%s" % \
277 str(testsys.cpu[0].max_insts_any_thread)
278 exit_event = m5.simulate()
279 else:
280 print "Switch at curTick count:%s" % str(10000)
281 exit_event = m5.simulate(10000)
282 print "Switched CPUS @ tick %s" % (m5.curTick())
283
284 # when you change to Timing (or Atomic), you halt the system
285 # given as argument. When you are finished with the system
286 # changes (including switchCpus), you must resume the system
287 # manually. You DON'T need to resume after just switching
288 # CPUs if you haven't changed anything on the system level.
289
290 m5.changeToTiming(testsys)
291 m5.switchCpus(switch_cpu_list)
292 m5.resume(testsys)
293
294 if options.standard_switch:
295 print "Switch at instruction count:%d" % \
296 (testsys.switch_cpus[0].max_insts_any_thread)
297
298 #warmup instruction count may have already been set
299 if options.warmup_insts:
300 exit_event = m5.simulate()
301 else:
302 exit_event = m5.simulate(options.warmup)
303 print "Switching CPUS @ tick %s" % (m5.curTick())
304 print "Simulation ends instruction count:%d" % \
305 (testsys.switch_cpus_1[0].max_insts_any_thread)
306 m5.drain(testsys)
307 m5.switchCpus(switch_cpu_list1)
308 m5.resume(testsys)
309
310 num_checkpoints = 0
311 exit_cause = ''
312
313 # If we're taking and restoring checkpoints, use checkpoint_dir
314 # option only for finding the checkpoints to restore from. This
315 # lets us test checkpointing by restoring from one set of
316 # checkpoints, generating a second set, and then comparing them.
317 if options.take_checkpoints and options.checkpoint_restore:
318 if m5.options.outdir:
319 cptdir = m5.options.outdir
320 else:
321 cptdir = getcwd()
322
323 # Checkpoints being taken via the command line at <when> and at
324 # subsequent periods of <period>. Checkpoint instructions
325 # received from the benchmark running are ignored and skipped in
326 # favor of command line checkpoint instructions.
327 if options.take_checkpoints != None :
328 if options.at_instruction or options.simpoint:
329 checkpoint_inst = int(options.take_checkpoints)
330
331 # maintain correct offset if we restored from some instruction
332 if options.checkpoint_restore != None:
333 checkpoint_inst += options.checkpoint_restore
334
335 print "Creating checkpoint at inst:%d" % (checkpoint_inst)
336 exit_event = m5.simulate()
337 print "exit cause = %s" % (exit_event.getCause())
338
339 # skip checkpoint instructions should they exist
340 while exit_event.getCause() == "checkpoint":
341 exit_event = m5.simulate()
342
343 if exit_event.getCause() == \
344 "a thread reached the max instruction count":
345 m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \
346 (options.bench, checkpoint_inst)))
347 print "Checkpoint written."
348 num_checkpoints += 1
349
350 if exit_event.getCause() == "user interrupt received":
351 exit_cause = exit_event.getCause();
352 else:
353 when, period = options.take_checkpoints.split(",", 1)
354 when = int(when)
355 period = int(period)
356
357 exit_event = m5.simulate(when)
358 while exit_event.getCause() == "checkpoint":
359 exit_event = m5.simulate(when - m5.curTick())
360
361 if exit_event.getCause() == "simulate() limit reached":
362 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
363 num_checkpoints += 1
364
365 sim_ticks = when
366 exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
367 while num_checkpoints < max_checkpoints and \
368 exit_event.getCause() == "simulate() limit reached":
369 if (sim_ticks + period) > maxtick:
370 exit_event = m5.simulate(maxtick - sim_ticks)
371 exit_cause = exit_event.getCause()
372 break
373 else:
374 exit_event = m5.simulate(period)
375 sim_ticks += period
376 while exit_event.getCause() == "checkpoint":
377 exit_event = m5.simulate(sim_ticks - m5.curTick())
378 if exit_event.getCause() == "simulate() limit reached":
379 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
380 num_checkpoints += 1
381
382 if exit_event.getCause() != "simulate() limit reached":
383 exit_cause = exit_event.getCause();
384
385 else: # no checkpoints being taken via this script
386 if options.fast_forward:
387 m5.stats.reset()
388 print "**** REAL SIMULATION ****"
389 exit_event = m5.simulate(maxtick)
390
391 while exit_event.getCause() == "checkpoint":
392 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
393 num_checkpoints += 1
394 if num_checkpoints == max_checkpoints:
395 exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
396 break
397
398 exit_event = m5.simulate(maxtick - m5.curTick())
399 exit_cause = exit_event.getCause()
400
401 if exit_cause == '':
402 exit_cause = exit_event.getCause()
403 print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)
404
405 if options.checkpoint_at_end:
406 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
407
172
173 # if restoring, make atomic cpu simulate only a few instructions
174 if options.checkpoint_restore != None:
175 testsys.cpu[i].max_insts_any_thread = 1
176 # Fast forward to specified location if we are not restoring
177 elif options.fast_forward:
178 testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
179 # Fast forward to a simpoint (warning: time consuming)
180 elif options.simpoint:
181 if testsys.cpu[i].workload[0].simpoint == 0:
182 fatal('simpoint not found')
183 testsys.cpu[i].max_insts_any_thread = \
184 testsys.cpu[i].workload[0].simpoint
185 # No distance specified, just switch
186 else:
187 testsys.cpu[i].max_insts_any_thread = 1
188
189 # warmup period
190 if options.warmup_insts:
191 switch_cpus[i].max_insts_any_thread = options.warmup_insts
192
193 # simulation period
194 if options.maxinsts:
195 switch_cpus_1[i].max_insts_any_thread = options.maxinsts
196
197 # attach the checker cpu if selected
198 if options.checker:
199 switch_cpus[i].addCheckerCpu()
200 switch_cpus_1[i].addCheckerCpu()
201
202 testsys.switch_cpus = switch_cpus
203 testsys.switch_cpus_1 = switch_cpus_1
204 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
205 switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)]
206
207 # set the checkpoint in the cpu before m5.instantiate is called
208 if options.take_checkpoints != None and \
209 (options.simpoint or options.at_instruction):
210 offset = int(options.take_checkpoints)
211 # Set an instruction break point
212 if options.simpoint:
213 for i in xrange(np):
214 if testsys.cpu[i].workload[0].simpoint == 0:
215 fatal('no simpoint for testsys.cpu[%d].workload[0]', i)
216 checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
217 testsys.cpu[i].max_insts_any_thread = checkpoint_inst
218 # used for output below
219 options.take_checkpoints = checkpoint_inst
220 else:
221 options.take_checkpoints = offset
222 # Set all test cpus with the right number of instructions
223 # for the upcoming simulation
224 for i in xrange(np):
225 testsys.cpu[i].max_insts_any_thread = offset
226
227 checkpoint_dir = None
228 if options.checkpoint_restore != None:
229 from os.path import isdir, exists
230 from os import listdir
231 import re
232
233 if not isdir(cptdir):
234 fatal("checkpoint dir %s does not exist!", cptdir)
235
236 if options.at_instruction or options.simpoint:
237 inst = options.checkpoint_restore
238 if options.simpoint:
239 # assume workload 0 has the simpoint
240 if testsys.cpu[0].workload[0].simpoint == 0:
241 fatal('Unable to find simpoint')
242 inst += int(testsys.cpu[0].workload[0].simpoint)
243
244 checkpoint_dir = joinpath(cptdir,
245 "cpt.%s.%s" % (options.bench, inst))
246 if not exists(checkpoint_dir):
247 fatal("Unable to find checkpoint directory %s", checkpoint_dir)
248 else:
249 dirs = listdir(cptdir)
250 expr = re.compile('cpt\.([0-9]*)')
251 cpts = []
252 for dir in dirs:
253 match = expr.match(dir)
254 if match:
255 cpts.append(match.group(1))
256
257 cpts.sort(lambda a,b: cmp(long(a), long(b)))
258
259 cpt_num = options.checkpoint_restore
260
261 if cpt_num > len(cpts):
262 fatal('Checkpoint %d not found', cpt_num)
263
264 ## Adjust max tick based on our starting tick
265 maxtick = maxtick - int(cpts[cpt_num - 1])
266 checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1])
267
268 m5.instantiate(checkpoint_dir)
269
270 if options.standard_switch or cpu_class:
271 if options.standard_switch:
272 print "Switch at instruction count:%s" % \
273 str(testsys.cpu[0].max_insts_any_thread)
274 exit_event = m5.simulate()
275 elif cpu_class and options.fast_forward:
276 print "Switch at instruction count:%s" % \
277 str(testsys.cpu[0].max_insts_any_thread)
278 exit_event = m5.simulate()
279 else:
280 print "Switch at curTick count:%s" % str(10000)
281 exit_event = m5.simulate(10000)
282 print "Switched CPUS @ tick %s" % (m5.curTick())
283
284 # when you change to Timing (or Atomic), you halt the system
285 # given as argument. When you are finished with the system
286 # changes (including switchCpus), you must resume the system
287 # manually. You DON'T need to resume after just switching
288 # CPUs if you haven't changed anything on the system level.
289
290 m5.changeToTiming(testsys)
291 m5.switchCpus(switch_cpu_list)
292 m5.resume(testsys)
293
294 if options.standard_switch:
295 print "Switch at instruction count:%d" % \
296 (testsys.switch_cpus[0].max_insts_any_thread)
297
298 #warmup instruction count may have already been set
299 if options.warmup_insts:
300 exit_event = m5.simulate()
301 else:
302 exit_event = m5.simulate(options.warmup)
303 print "Switching CPUS @ tick %s" % (m5.curTick())
304 print "Simulation ends instruction count:%d" % \
305 (testsys.switch_cpus_1[0].max_insts_any_thread)
306 m5.drain(testsys)
307 m5.switchCpus(switch_cpu_list1)
308 m5.resume(testsys)
309
310 num_checkpoints = 0
311 exit_cause = ''
312
313 # If we're taking and restoring checkpoints, use checkpoint_dir
314 # option only for finding the checkpoints to restore from. This
315 # lets us test checkpointing by restoring from one set of
316 # checkpoints, generating a second set, and then comparing them.
317 if options.take_checkpoints and options.checkpoint_restore:
318 if m5.options.outdir:
319 cptdir = m5.options.outdir
320 else:
321 cptdir = getcwd()
322
323 # Checkpoints being taken via the command line at <when> and at
324 # subsequent periods of <period>. Checkpoint instructions
325 # received from the benchmark running are ignored and skipped in
326 # favor of command line checkpoint instructions.
327 if options.take_checkpoints != None :
328 if options.at_instruction or options.simpoint:
329 checkpoint_inst = int(options.take_checkpoints)
330
331 # maintain correct offset if we restored from some instruction
332 if options.checkpoint_restore != None:
333 checkpoint_inst += options.checkpoint_restore
334
335 print "Creating checkpoint at inst:%d" % (checkpoint_inst)
336 exit_event = m5.simulate()
337 print "exit cause = %s" % (exit_event.getCause())
338
339 # skip checkpoint instructions should they exist
340 while exit_event.getCause() == "checkpoint":
341 exit_event = m5.simulate()
342
343 if exit_event.getCause() == \
344 "a thread reached the max instruction count":
345 m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \
346 (options.bench, checkpoint_inst)))
347 print "Checkpoint written."
348 num_checkpoints += 1
349
350 if exit_event.getCause() == "user interrupt received":
351 exit_cause = exit_event.getCause();
352 else:
353 when, period = options.take_checkpoints.split(",", 1)
354 when = int(when)
355 period = int(period)
356
357 exit_event = m5.simulate(when)
358 while exit_event.getCause() == "checkpoint":
359 exit_event = m5.simulate(when - m5.curTick())
360
361 if exit_event.getCause() == "simulate() limit reached":
362 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
363 num_checkpoints += 1
364
365 sim_ticks = when
366 exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
367 while num_checkpoints < max_checkpoints and \
368 exit_event.getCause() == "simulate() limit reached":
369 if (sim_ticks + period) > maxtick:
370 exit_event = m5.simulate(maxtick - sim_ticks)
371 exit_cause = exit_event.getCause()
372 break
373 else:
374 exit_event = m5.simulate(period)
375 sim_ticks += period
376 while exit_event.getCause() == "checkpoint":
377 exit_event = m5.simulate(sim_ticks - m5.curTick())
378 if exit_event.getCause() == "simulate() limit reached":
379 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
380 num_checkpoints += 1
381
382 if exit_event.getCause() != "simulate() limit reached":
383 exit_cause = exit_event.getCause();
384
385 else: # no checkpoints being taken via this script
386 if options.fast_forward:
387 m5.stats.reset()
388 print "**** REAL SIMULATION ****"
389 exit_event = m5.simulate(maxtick)
390
391 while exit_event.getCause() == "checkpoint":
392 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
393 num_checkpoints += 1
394 if num_checkpoints == max_checkpoints:
395 exit_cause = "maximum %d checkpoints dropped" % max_checkpoints
396 break
397
398 exit_event = m5.simulate(maxtick - m5.curTick())
399 exit_cause = exit_event.getCause()
400
401 if exit_cause == '':
402 exit_cause = exit_event.getCause()
403 print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)
404
405 if options.checkpoint_at_end:
406 m5.checkpoint(joinpath(cptdir, "cpt.%d"))
407