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