1#!/usr/bin/env python 2 3# Copyright (c) 2003-2004 The Regents of The University of Michigan 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are 8# met: redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer; 10# redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution; 13# neither the name of the copyright holders nor the names of its 14# contributors may be used to endorse or promote products derived from 15# this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28# 29# Authors: Nathan Binkert 30 31from __future__ import division 32import re, sys, math 33 34def usage(): 35 print '''\ 36Usage: %s [-E] [-F] [ -G <get> ] [-d <db> ] [-g <graphdir> ] [-h <host>] [-p] 37 [-s <system>] [-r <runs> ] [-T <samples>] [-u <username>] 38 <command> [command args] 39 40 commands extra parameters description 41 ----------- ------------------ ---------------------------------------
|
42 bins [regex] List bins (only matching regex)
|
42 formula <formula> Evaluated formula specified 43 formulas [regex] List formulas (only matching regex) 44 runs none List all runs in database 45 samples none List samples present in database 46 stability <pairnum> <stats> Calculated statistical info about stats 47 stat <regex> Show stat data (only matching regex) 48 stats [regex] List all stats (only matching regex) 49 50 database <command> Where command is drop, init, or clean 51 52''' % sys.argv[0] 53 sys.exit(1) 54 55def getopts(list, flags): 56 import getopt 57 try: 58 opts, args = getopt.getopt(list, flags) 59 except getopt.GetoptError: 60 usage() 61 62 return opts, args 63 64class CommandException(Exception): 65 pass 66 67def commands(options, command, args): 68 if command == 'database': 69 if len(args) == 0: raise CommandException 70 71 import dbinit 72 mydb = dbinit.MyDB(options) 73 74 if args[0] == 'drop': 75 if len(args) > 2: raise CommandException 76 mydb.admin() 77 mydb.drop() 78 if len(args) == 2 and args[1] == 'init': 79 mydb.create() 80 mydb.connect() 81 mydb.populate() 82 mydb.close() 83 return 84 85 if args[0] == 'init': 86 if len(args) > 1: raise CommandException 87 mydb.admin() 88 mydb.create() 89 mydb.connect() 90 mydb.populate() 91 mydb.close() 92 return 93 94 if args[0] == 'clean': 95 if len(args) > 1: raise CommandException 96 mydb.connect() 97 mydb.clean() 98 return 99 100 raise CommandException 101 102 import db 103 source = db.Database() 104 source.host = options.host 105 source.db = options.db 106 source.passwd = options.passwd 107 source.user = options.user 108 source.connect() 109 #source.update_dict(globals()) 110 111 if type(options.method) is str: 112 source.method = options.method 113 114 if options.runs is None: 115 runs = source.allRuns 116 else: 117 rx = re.compile(options.runs) 118 runs = [] 119 for run in source.allRuns: 120 if rx.match(run.name): 121 runs.append(run) 122 123 if command == 'runs': 124 user = None 125 opts, args = getopts(args, '-u') 126 if len(args): 127 raise CommandException 128 for o,a in opts: 129 if o == '-u': 130 user = a 131 source.listRuns(user) 132 return 133 134 if command == 'stats': 135 if len(args) == 0: 136 source.listStats() 137 elif len(args) == 1: 138 source.listStats(args[0]) 139 else: 140 raise CommandException 141 142 return 143
|
145 if command == 'bins':
146 if len(args) == 0:
147 source.listBins()
148 elif len(args) == 1:
149 source.listBins(args[0])
150 else:
151 raise CommandException
152
153 return
154
|
144 if command == 'formulas': 145 if len(args) == 0: 146 source.listFormulas() 147 elif len(args) == 1: 148 source.listFormulas(args[0]) 149 else: 150 raise CommandException 151 152 return 153 154 if command == 'samples': 155 if len(args): 156 raise CommandException 157 158 source.listTicks(runs) 159 return 160 161 if command == 'stability': 162 if len(args) < 2: 163 raise CommandException 164 165 try: 166 merge = int(args[0]) 167 except ValueError: 168 usage() 169 stats = source.getStat(args[1]) 170 source.method = 'sum' 171 172 def disp(*args): 173 print "%-35s %12s %12s %4s %5s %5s %5s %10s" % args 174 175 # temporary variable containing a bunch of dashes 176 d = '-' * 100 177 178 #loop through all the stats selected 179 for stat in stats: 180 print "%s:" % stat.name 181 disp("run name", "average", "stdev", ">10%", ">1SDV", ">2SDV", 182 "SAMP", "CV") 183 disp(d[:35], d[:12], d[:12], d[:4], d[:5], d[:5], d[:5], d[:10]) 184 185 #loop through all the selected runs 186 for run in runs: 187 runTicks = source.retTicks([ run ]) 188 #throw away the first one, it's 0 189 runTicks.pop(0) 190 source.ticks = runTicks 191 avg = 0 192 stdev = 0 193 numoutsideavg = 0 194 numoutside1std = 0 195 numoutside2std = 0 196 pairRunTicks = [] 197 if value(stat, run.run) == 1e300*1e300: 198 continue 199 for t in range(0, len(runTicks)-(merge-1), merge): 200 tempPair = [] 201 for p in range(0,merge): 202 tempPair.append(runTicks[t+p]) 203 pairRunTicks.append(tempPair) 204 #loop through all the various ticks for each run 205 for tick in pairRunTicks: 206 source.ticks = tick 207 avg += value(stat, run.run) 208 avg /= len(pairRunTicks) 209 for tick in pairRunTicks: 210 source.ticks = tick 211 val = value(stat, run.run) 212 stdev += pow((val-avg),2) 213 stdev = math.sqrt(stdev / len(pairRunTicks)) 214 for tick in pairRunTicks: 215 source.ticks = tick 216 val = value(stat, run.run) 217 if (val < (avg * .9)) or (val > (avg * 1.1)): 218 numoutsideavg += 1 219 if (val < (avg - stdev)) or (val > (avg + stdev)): 220 numoutside1std += 1 221 if (val < (avg - (2*stdev))) or (val > (avg + (2*stdev))): 222 numoutside2std += 1 223 if avg > 1000: 224 disp(run.name, "%.1f" % avg, "%.1f" % stdev, 225 "%d" % numoutsideavg, "%d" % numoutside1std, 226 "%d" % numoutside2std, "%d" % len(pairRunTicks), 227 "%.3f" % (stdev/avg*100)) 228 elif avg > 100: 229 disp(run.name, "%.1f" % avg, "%.1f" % stdev, 230 "%d" % numoutsideavg, "%d" % numoutside1std, 231 "%d" % numoutside2std, "%d" % len(pairRunTicks), 232 "%.5f" % (stdev/avg*100)) 233 else: 234 disp(run.name, "%.5f" % avg, "%.5f" % stdev, 235 "%d" % numoutsideavg, "%d" % numoutside1std, 236 "%d" % numoutside2std, "%d" % len(pairRunTicks), 237 "%.7f" % (stdev/avg*100)) 238 return 239 240 if command == 'all': 241 if len(args): 242 raise CommandException 243 244 all = [ 'bps', 'misses', 'mpkb', 'ipkb', 'pps', 'bpt' ] 245 for command in all: 246 commands(options, command, args) 247 248 if options.ticks: 249 if not options.graph: 250 print 'only displaying sample %s' % options.ticks 251 source.ticks = [ int(x) for x in options.ticks.split() ] 252 253 from output import StatOutput 254 output = StatOutput(options.jobfile, source) 255 output.xlabel = 'System Configuration' 256 output.colormap = 'RdYlGn' 257 258 if command == 'stat' or command == 'formula': 259 if len(args) != 1: 260 raise CommandException 261 262 if command == 'stat': 263 stats = source.getStat(args[0]) 264 if command == 'formula': 265 stats = eval(args[0]) 266 267 for stat in stats: 268 output.stat = stat 269 output.ylabel = stat.name 270 if options.graph: 271 output.graph(stat.name, options.graphdir) 272 else:
|
284 output.display(stat.name, options.binned, options.printmode)
|
273 output.display(stat.name, options.printmode) |
274 275 return 276 277 if len(args): 278 raise CommandException 279 280 from info import ProxyGroup 281 proxy = ProxyGroup(system = source[options.system]) 282 system = proxy.system 283 284 etherdev = system.tsunami.etherdev0 285 bytes = etherdev.rxBytes + etherdev.txBytes 286 kbytes = bytes / 1024 287 packets = etherdev.rxPackets + etherdev.txPackets 288 289 def display(): 290 if options.graph: 291 output.graph(command, options.graphdir, proxy) 292 else:
|
304 output.display(command, options.binned, options.printmode)
|
293 output.display(command, options.printmode) |
294
|
306 if command == 'usertime':
307 import copy
308 user = copy.copy(system.run0.numCycles)
309 user.bins = 'user'
310
311 output.stat = user / system.run0.numCycles
312 output.ylabel = 'User Fraction'
313
314 display()
315 return
316
|
295 if command == 'ticks': 296 output.stat = system.run0.numCycles
|
319 output.binstats = [ system.run0.numCycles ]
|
297 298 display() 299 return 300 301 if command == 'bytes': 302 output.stat = bytes 303 display() 304 return 305 306 if command == 'packets': 307 output.stat = packets 308 display() 309 return 310 311 if command == 'ppt' or command == 'tpp': 312 output.stat = packets / system.run0.numCycles 313 output.invert = command == 'tpp' 314 display() 315 return 316 317 if command == 'pps': 318 output.stat = packets / source['sim_seconds'] 319 output.ylabel = 'Packets/s' 320 display() 321 return 322 323 if command == 'bpt' or command == 'tpb': 324 output.stat = bytes / system.run0.numCycles * 8 325 output.ylabel = 'bps / Hz' 326 output.invert = command == 'tpb' 327 display() 328 return 329 330 if command in ('rxbps', 'txbps', 'bps'): 331 if command == 'rxbps': 332 output.stat = etherdev.rxBandwidth / 1e9 333 if command == 'txbps': 334 output.stat = etherdev.txBandwidth / 1e9 335 if command == 'bps': 336 output.stat = (etherdev.rxBandwidth + etherdev.txBandwidth) / 1e9 337 338 output.ylabel = 'Bandwidth (Gbps)' 339 output.ylim = [ 0.0, 10.0 ] 340 display() 341 return 342 343 if command == 'bpp': 344 output.stat = bytes / packets 345 output.ylabel = 'Bytes / Packet' 346 display() 347 return 348 349 if command == 'rxbpp': 350 output.stat = etherdev.rxBytes / etherdev.rxPackets 351 output.ylabel = 'Receive Bytes / Packet' 352 display() 353 return 354 355 if command == 'txbpp': 356 output.stat = etherdev.txBytes / etherdev.txPackets 357 output.ylabel = 'Transmit Bytes / Packet' 358 display() 359 return 360 361 if command == 'rtp': 362 output.stat = etherdev.rxPackets / etherdev.txPackets 363 output.ylabel = 'rxPackets / txPackets' 364 display() 365 return 366 367 if command == 'rtb': 368 output.stat = etherdev.rxBytes / etherdev.txBytes 369 output.ylabel = 'rxBytes / txBytes' 370 display() 371 return 372 373 misses = system.l2.overall_mshr_misses 374 375 if command == 'misses': 376 output.stat = misses 377 output.ylabel = 'Overall MSHR Misses' 378 display() 379 return 380 381 if command == 'mpkb': 382 output.stat = misses / (bytes / 1024)
|
406 output.binstats = [ misses ]
|
383 output.ylabel = 'Misses / KB' 384 display() 385 return 386 387 if command == 'ipkb': 388 interrupts = system.run0.kern.faults[4] 389 output.stat = interrupts / kbytes
|
414 output.binstats = [ interrupts ]
|
390 output.ylabel = 'Interrupts / KB' 391 display() 392 return 393 394 if command == 'execute': 395 output.stat = system.run0.ISSUE__count 396 display() 397 return 398 399 if command == 'commit': 400 output.stat = system.run0.COM__count 401 display() 402 return 403 404 if command == 'fetch': 405 output.stat = system.run0.FETCH__count 406 display() 407 return 408 409 raise CommandException 410 411 412class Options: pass 413 414if __name__ == '__main__': 415 import getpass 416 from jobfile import JobFile 417 418 options = Options() 419 options.host = None 420 options.db = None 421 options.passwd = '' 422 options.user = getpass.getuser() 423 options.runs = None 424 options.system = 'client' 425 options.method = None
|
451 options.binned = False
|
426 options.graph = False 427 options.ticks = False 428 options.printmode = 'G' 429 jobfilename = 'Test.py' 430 options.jobfile = None 431 options.all = False 432
|
459 opts, args = getopts(sys.argv[1:], '-BEFJad:g:h:j:m:pr:s:u:T:')
|
433 opts, args = getopts(sys.argv[1:], '-EFJad:g:h:j:m:pr:s:u:T:') |
434 for o,a in opts:
|
461 if o == '-B':
462 options.binned = True
|
435 if o == '-E': 436 options.printmode = 'E' 437 if o == '-F': 438 options.printmode = 'F' 439 if o == '-a': 440 options.all = True 441 if o == '-d': 442 options.db = a 443 if o == '-g': 444 options.graph = True; 445 options.graphdir = a 446 if o == '-h': 447 options.host = a 448 if o == '-J': 449 jobfilename = None 450 if o == '-j': 451 jobfilename = a 452 if o == '-m': 453 options.method = a 454 if o == '-p': 455 options.passwd = getpass.getpass() 456 if o == '-r': 457 options.runs = a 458 if o == '-u': 459 options.user = a 460 if o == '-s': 461 options.system = a 462 if o == '-T': 463 options.ticks = a 464 465 if jobfilename: 466 options.jobfile = JobFile(jobfilename) 467 if not options.host: 468 options.host = options.jobfile.dbhost 469 if not options.db: 470 options.db = options.jobfile.statdb 471 472 if not options.host: 473 sys.exit('Database server must be provided from a jobfile or -h') 474 475 if not options.db: 476 sys.exit('Database name must be provided from a jobfile or -d') 477 478 if len(args) == 0: 479 usage() 480 481 command = args[0] 482 args = args[1:] 483 484 try: 485 commands(options, command, args) 486 except CommandException: 487 usage()
|