stats.py revision 1596
1#!/usr/bin/env python
2from __future__ import division
3import re, sys, math
4
5
6def usage():
7    print '''\
8Usage: %s [-E] [-F] [-d <db> ] [-g <get> ] [-h <host>] [-p]
9       [-s <system>] [-r <runs> ] [-T <samples>] [-u <username>]
10       <command> [command args]
11
12       commands    extra parameters   description
13       ----------- ------------------ ---------------------------------------
14       bins        [regex]            List bins (only matching regex)
15       formula     <formula>          Evaluated formula specified
16       formulas    [regex]            List formulas (only matching regex)
17       runs        none               List all runs in database
18       samples     none               List samples present in database
19       stability   <pairnum> <stats>  Calculated statistical info about stats
20       stat        <regex>            Show stat data (only matching regex)
21       stats       [regex]            List all stats (only matching regex)
22
23       database    <command>          Where command is drop, init, or clean
24
25''' % sys.argv[0]
26    sys.exit(1)
27
28def getopts(list, flags):
29    import getopt
30    try:
31        opts, args = getopt.getopt(list, flags)
32    except getopt.GetoptError:
33        usage()
34
35    return opts, args
36
37def printval(name, value, invert = False):
38    if invert and value != 0.0:
39        value = 1 / value
40
41    if value == (1e300*1e300):
42        return
43
44    if printval.mode == 'G':
45        print '%s:    %g' % (name, value)
46    elif printval.mode != 'F' and value > 1e6:
47        print '%s:    %0.5e' % (name, value)
48    else:
49        print '%s:    %f' % (name, value)
50
51printval.mode = 'G'
52
53def unique(list):
54    set = {}
55    map(set.__setitem__, list, [])
56    return set.keys()
57
58def graphdata68(runs, options, tag, label, value):
59    import info
60    configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ]
61    benchmarks = [ 'm', 's', 'snt', 'nb1', 'w1', 'w2', 'w3', 'w4', 'nm', 'ns', 'nw1', 'nw2', 'nw3' ]
62    dmas = [ 'x' ]
63    caches = [ '2', '4' ]
64
65    names = []
66
67    bench_system = {
68        'm' : 'client',
69        's' : 'client',
70        'snt' : 'client',
71        'nb1' : 'server',
72        'nb2' : 'server',
73        'nt1' : 'server',
74        'nt2' : 'server',
75        'w1' : 'server',
76        'w2' : 'server',
77        'w3' : 'server',
78        'w4' : 'server',
79        'w1s' : 'server',
80        'w2s' : 'server',
81        'w3s' : 'server',
82        'ns' : 'natbox',
83        'nm' : 'natbox',
84        'nw1' : 'natbox',
85        'nw2' : 'natbox',
86        'nw3' : 'natbox'
87        }
88
89    for bench in benchmarks:
90        if bench_system[bench] != options.system:
91            continue
92
93        for dma in dmas:
94            for cache in caches:
95                    names.append([bench, dma, cache])
96
97    for bench,dma,cache in names:
98        base = '%s.%s.%s' % (bench, dma, cache)
99        fname = 'data/%s.%s.68.dat' % (tag, base)
100        f = open(fname, 'w')
101        print >>f, '#set TITLE = '
102        print >>f, '#set ylbl = %s' % label
103        #print >>f, '#set sublabels = %s' % ' '.join(configs)
104        print >>f, '#set sublabels = ste hte htd ocm occ ocs'
105
106        for speed,freq in zip(['s', '6', '8', 'q'],['4GHz', '6GHz','8GHz', '10GHz']):
107            print >>f, '"%s"' % freq,
108            for conf in configs:
109                name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed)
110                run = info.source.allRunNames[name]
111                info.display_run = run.run;
112                val = float(value)
113                if val == 1e300*1e300:
114                    print >>f, 0.0,
115                else:
116                    print >>f, "%f" % val,
117            print >>f
118        f.close()
119
120def graphdata(runs, options, tag, label, value):
121    if options.graph68:
122        graphdata68(runs, options, tag, label, value)
123        return
124
125    import info
126    configs = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp' ]
127    #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'nt2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'nw2', 'nw3' ]
128    #benchmarks = [ 'm', 's', 'nb1', 'nb2', 'nt1', 'w1', 'w2', 'w3', 'ns', 'nm', 'w1s' ]
129    benchmarks = [ 'm', 's', 'nb1', 'nb2', 'w1', 'w2', 'w3', 'w4', 'ns', 'nm', 'nw1', 'snt' ]
130    #dmas = [ 'x', 'd', 'b' ]
131    dmas = [ 'x' ]
132    caches = [ '2', '4' ]
133
134    names = []
135
136    bench_system = {
137        'm' : 'client',
138        's' : 'client',
139        'snt' : 'client',
140        'nb1' : 'server',
141        'nb2' : 'server',
142        'nt1' : 'server',
143        'nt2' : 'server',
144        'w1' : 'server',
145        'w2' : 'server',
146        'w3' : 'server',
147        'w4' : 'server',
148        'w1s' : 'server',
149        'w2s' : 'server',
150        'w3s' : 'server',
151        'ns' : 'natbox',
152        'nm' : 'natbox',
153        'nw1' : 'natbox',
154        'nw2' : 'natbox',
155        'nw3' : 'natbox'
156        }
157
158    for bench in benchmarks:
159        if bench_system[bench] != options.system:
160            continue
161
162        for dma in dmas:
163            for cache in caches:
164                    names.append([bench, dma, cache])
165
166    for bench,dma,cache in names:
167        base = '%s.%s.%s' % (bench, dma, cache)
168        fname = 'data/%s.%s.dat' % (tag, base)
169        f = open(fname, 'w')
170        print >>f, '#set TITLE = '
171        print >>f, '#set ylbl = %s' % label
172        #print >>f, '#set sublabels = %s' % ' '.join(configs)
173        print >>f, '#set sublabels = ste hte htd ocm occ ocs'
174
175        for speed,freq in zip(['s', 'q'],['4GHz','10GHz']):
176            print >>f, '"%s"' % freq,
177            for conf in configs:
178                name = '%s.%s.%s.%s.%s' % (conf, bench, dma, cache, speed)
179                run = info.source.allRunNames[name]
180                info.display_run = run.run;
181                val = float(value)
182                if val == 1e300*1e300:
183                    print >>f, 0.0,
184                else:
185                    print >>f, "%f" % val,
186            print >>f
187        f.close()
188
189def printdata(runs, value, invert = False):
190    import info
191    for run in runs:
192        info.display_run = run.run;
193        val = float(value)
194        printval(run.name, val)
195
196class CommandException(Exception):
197    pass
198
199def commands(options, command, args):
200    if command == 'database':
201        if len(args) == 0: raise CommandException
202
203        import dbinit
204        mydb = dbinit.MyDB(options)
205
206        if args[0] == 'drop':
207            if len(args) > 2: raise CommandException
208            mydb.admin()
209            mydb.drop()
210            if len(args) == 2 and args[1] == 'init':
211                mydb.create()
212                mydb.connect()
213                mydb.populate()
214            mydb.close()
215            return
216
217        if args[0] == 'init':
218            if len(args) > 1: raise CommandException
219            mydb.admin()
220            mydb.create()
221            mydb.connect()
222            mydb.populate()
223            mydb.close()
224            return
225
226        if args[0] == 'clean':
227            if len(args) > 1: raise CommandException
228            mydb.connect()
229            mydb.clean()
230            return
231
232        raise CommandException
233
234    import db, info
235    info.source = db.Database()
236    info.source.host = options.host
237    info.source.db = options.db
238    info.source.passwd = options.passwd
239    info.source.user = options.user
240    info.source.connect()
241    info.source.update_dict(globals())
242
243    if type(options.get) is str:
244        info.source.get = options.get
245
246    if options.runs is None:
247        runs = info.source.allRuns
248    else:
249        rx = re.compile(options.runs)
250        runs = []
251        for run in info.source.allRuns:
252            if rx.match(run.name):
253                runs.append(run)
254
255    info.display_run = runs[0].run
256
257    if command == 'runs':
258        user = None
259        opts, args = getopts(args, '-u')
260        if len(args):
261            raise CommandException
262        for o,a in opts:
263            if o == '-u':
264                user = a
265        info.source.listRuns(user)
266        return
267
268    if command == 'stability':
269        if len(args) < 2:
270            raise CommandException
271
272        try:
273            merge = int(args[0])
274        except ValueError:
275            usage()
276        stats = info.source.getStat(args[1])
277        info.source.get = "sum"
278
279
280        #loop through all the stats selected
281        for stat in stats:
282
283            print "%s:" % stat.name
284            print "%-20s %12s %12s %4s %5s %5s %5s %10s" % \
285                  ("run name", "average", "stdev", ">10%", ">1SDV", ">2SDV", "SAMP", "CV")
286            print "%-20s %12s %12s %4s %5s %5s %5s %10s" % \
287                  ("--------------------", "------------",
288                   "------------", "----", "-----", "-----", "-----", "----------")
289            #loop through all the selected runs
290            for run in runs:
291                info.display_run = run.run;
292                runTicks = info.source.retTicks([ run ])
293                #throw away the first one, it's 0
294                runTicks.pop(0)
295                info.globalTicks = runTicks
296                avg = 0
297                stdev = 0
298                numoutsideavg  = 0
299                numoutside1std = 0
300                numoutside2std = 0
301                pairRunTicks = []
302                if float(stat) == 1e300*1e300:
303                    continue
304                for t in range(0, len(runTicks)-(merge-1), merge):
305                    tempPair = []
306                    for p in range(0,merge):
307                        tempPair.append(runTicks[t+p])
308                    pairRunTicks.append(tempPair)
309                #loop through all the various ticks for each run
310                for tick in pairRunTicks:
311                    info.globalTicks = tick
312                    avg += float(stat)
313                avg /= len(pairRunTicks)
314                for tick in pairRunTicks:
315                    info.globalTicks = tick
316                    val = float(stat)
317                    stdev += pow((val-avg),2)
318                stdev = math.sqrt(stdev / len(pairRunTicks))
319                for tick in pairRunTicks:
320                    info.globalTicks = tick
321                    val = float(stat)
322                    if (val < (avg * .9)) or (val > (avg * 1.1)):
323                        numoutsideavg += 1
324                    if (val < (avg - stdev)) or (val > (avg + stdev)):
325                        numoutside1std += 1
326                    if (val < (avg - (2*stdev))) or (val > (avg + (2*stdev))):
327                        numoutside2std += 1
328                if avg > 1000:
329                    print "%-20s %12s %12s %4s %5s %5s %5s %10s" % \
330                          (run.name, "%.1f" % avg, "%.1f" % stdev,
331                           "%d" % numoutsideavg, "%d" % numoutside1std,
332                           "%d" % numoutside2std, "%d" % len(pairRunTicks),
333                           "%.3f" % (stdev/avg*100))
334                elif avg > 100:
335                    print "%-20s %12s %12s %4s %5s %5s %5s %10s" % \
336                          (run.name, "%.1f" % avg, "%.1f" % stdev,
337                           "%d" % numoutsideavg, "%d" % numoutside1std,
338                           "%d" % numoutside2std, "%d" % len(pairRunTicks),
339                           "%.5f" % (stdev/avg*100))
340                else:
341                    print "%-20s %12s %12s %4s %5s %5s %5s %10s" % \
342                          (run.name, "%.5f" % avg, "%.5f" % stdev,
343                           "%d" % numoutsideavg, "%d" % numoutside1std,
344                           "%d" % numoutside2std, "%d" % len(pairRunTicks),
345                           "%.7f" % (stdev/avg*100))
346        return
347
348    if command == 'stats':
349        if len(args) == 0:
350            info.source.listStats()
351        elif len(args) == 1:
352            info.source.listStats(args[0])
353        else:
354            raise CommandException
355
356        return
357
358    if command == 'stat':
359        if len(args) != 1:
360            raise CommandException
361
362        stats = info.source.getStat(args[0])
363        for stat in stats:
364            if options.graph:
365                graphdata(runs, options, stat.name, stat.name, stat)
366            else:
367                if options.ticks:
368                   print 'only displaying sample %s' % options.ticks
369                   info.globalTicks = [ int(x) for x in options.ticks.split() ]
370
371                if options.binned:
372                    print 'kernel ticks'
373                    stat.bins = 'kernel'
374                    printdata(runs, stat)
375
376                    print 'idle ticks'
377                    stat.bins = 'idle'
378                    printdata(runs, stat)
379
380                    print 'user ticks'
381                    stat.bins = 'user'
382                    printdata(runs, stat)
383
384                    print 'interrupt ticks'
385                    stat.bins = 'interrupt'
386                    printdata(runs, stat)
387
388                    print 'total ticks'
389
390                stat.bins = None
391                print stat.name
392                printdata(runs, stat)
393        return
394
395    if command == 'formula':
396        if len(args) != 1:
397            raise CommandException
398
399        stats = eval(args[0])
400        for stat in stats:
401            if options.graph:
402                graphdata(runs, options, stat.name, stat.name, stat)
403            else:
404                if options.binned:
405                    print 'kernel ticks'
406                    stat.bins = 'kernel'
407                    printdata(runs, stat)
408
409                    print 'idle ticks'
410                    stat.bins = 'idle'
411                    printdata(runs, stat)
412
413                    print 'user ticks'
414                    stat.bins = 'user'
415                    printdata(runs, stat)
416
417                    print 'interrupt ticks'
418                    stat.bins = 'interrupt'
419                    printdata(runs, stat)
420
421                    print 'total ticks'
422
423                stat.bins = None
424                print args[0]
425                printdata(runs, stat)
426        return
427
428    if command == 'bins':
429        if len(args) == 0:
430            info.source.listBins()
431        elif len(args) == 1:
432            info.source.listBins(args[0])
433        else:
434            raise CommandException
435
436        return
437
438    if command == 'formulas':
439        if len(args) == 0:
440            info.source.listFormulas()
441        elif len(args) == 1:
442            info.source.listFormulas(args[0])
443        else:
444            raise CommandException
445
446        return
447
448    if command == 'samples':
449        if len(args):
450            raise CommandException
451
452        info.source.listTicks(runs)
453        return
454
455    if len(args):
456        raise CommandException
457
458    system = info.source.__dict__[options.system]
459
460    if command == 'usertime':
461        import copy
462        kernel = copy.copy(system.full_cpu.numCycles)
463        kernel.bins = 'kernel'
464
465        user = copy.copy(system.full_cpu.numCycles)
466        user.bins = 'user'
467
468        if options.graph:
469            graphdata(runs, options, 'usertime', 'User Fraction',
470                      user / system.full_cpu.numCycles)
471        else:
472            printdata(runs, user / system.full_cpu.numCycles)
473        return
474
475    if command == 'ticks':
476        if options.binned:
477            print 'kernel ticks'
478            system.full_cpu.numCycles.bins = 'kernel'
479            printdata(runs, system.full_cpu.numCycles)
480
481            print 'idle ticks'
482            system.full_cpu.numCycles.bins = 'idle'
483            printdata(runs, system.full_cpu.numCycles)
484
485            print 'user ticks'
486            system.full_cpu.numCycles.bins = 'user'
487            printdata(runs, system.full_cpu.numCycles)
488
489            print 'total ticks'
490
491        system.full_cpu.numCycles.bins = None
492        printdata(runs, system.full_cpu.numCycles)
493        return
494
495    if command == 'packets':
496        packets = system.tsunami.etherdev.rxPackets
497        if options.graph:
498            graphdata(runs, options, 'packets', 'Packets', packets)
499        else:
500            printdata(runs, packets)
501        return
502
503    if command == 'ppt' or command == 'tpp':
504        ppt = system.tsunami.etherdev.rxPackets / sim_ticks
505        printdata(runs, ppt, command == 'tpp')
506        return
507
508    if command == 'pps':
509        pps = system.tsunami.etherdev.rxPackets / sim_seconds
510        if options.graph:
511            graphdata(runs, options, 'pps', 'Packets/s', pps)
512        else:
513            printdata(runs, pps)
514        return
515
516    if command == 'bpt' or command == 'tpb':
517        bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes
518        bpt = bytes / sim_ticks * 8
519        if options.graph:
520            graphdata(runs, options, 'bpt', 'bps / Hz', bpt)
521        else:
522            printdata(runs, bpt, command == 'tpb')
523        return
524
525    if command == 'bptb' or command == 'tpbb':
526        bytes = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes
527
528        print 'kernel stats'
529        bytes.bins = 'kernel'
530        printdata(runs, bytes / ticks)
531
532        print 'idle stats'
533        bytes.bins = 'idle'
534        printdata(runs, bytes / ticks)
535
536        print 'user stats'
537        bytes.bins = 'user'
538        printdata(runs, bytes / ticks)
539
540        return
541
542    if command == 'bytes':
543        stat = system.tsunami.etherdev.rxBytes + system.tsunami.etherdev.txBytes
544
545        if options.binned:
546            print '%s kernel stats' % stat.name
547            stat.bins = 'kernel'
548            printdata(runs, stat)
549
550            print '%s idle stats' % stat.name
551            stat.bins = 'idle'
552            printdata(runs, stat)
553
554            print '%s user stats' % stat.name
555            stat.bins = 'user'
556            printdata(runs, stat)
557
558            print '%s total stats' % stat.name
559            stat.bins = None
560
561        printdata(runs, stat)
562        return
563
564    if command == 'rxbps':
565        gbps = system.tsunami.etherdev.rxBandwidth / 1e9
566        if options.graph:
567            graphdata(runs, options, 'rxbps', 'Bandwidth (Gbps)',  gbps)
568        else:
569            printdata(runs, gbps)
570        return
571
572    if command == 'txbps':
573        gbps = system.tsunami.etherdev.txBandwidth / 1e9
574        if options.graph:
575            graphdata(runs, options, 'txbps', 'Bandwidth (Gbps)',  gbps)
576        else:
577            printdata(runs, gbps)
578        return
579
580    if command == 'bps':
581        rxbps = system.tsunami.etherdev.rxBandwidth
582        txbps = system.tsunami.etherdev.txBandwidth
583        gbps = (rxbps + txbps) / 1e9
584        if options.graph:
585            graphdata(runs, options, 'bps', 'Bandwidth (Gbps)',  gbps)
586        else:
587            printdata(runs, gbps)
588        return
589
590    if command == 'misses':
591        stat = system.L2.overall_mshr_misses
592        if options.binned:
593            print '%s kernel stats' % stat.name
594            stat.bins = 'kernel'
595            printdata(runs, stat)
596
597            print '%s idle stats' % stat.name
598            stat.bins = 'idle'
599            printdata(runs, stat)
600
601            print '%s user stats' % stat.name
602            stat.bins = 'user'
603            printdata(runs, stat)
604
605            print '%s total stats' % stat.name
606
607        stat.bins = None
608        if options.graph:
609            graphdata(runs, options, 'misses', 'Overall MSHR Misses', stat)
610        else:
611            printdata(runs, stat)
612        return
613
614    if command == 'mpkb':
615        misses = system.L2.overall_mshr_misses
616        rxbytes = system.tsunami.etherdev.rxBytes
617        txbytes = system.tsunami.etherdev.txBytes
618
619        if options.binned:
620            print 'mpkb kernel stats'
621            misses.bins = 'kernel'
622            mpkb = misses / ((rxbytes + txbytes) / 1024)
623            printdata(runs, mpkb)
624
625            print 'mpkb idle stats'
626            misses.bins = 'idle'
627            mpkb = misses / ((rxbytes + txbytes) / 1024)
628            printdata(runs, mpkb)
629
630            print 'mpkb user stats'
631            misses.bins = 'user'
632            mpkb = misses / ((rxbytes + txbytes) / 1024)
633            printdata(runs, mpkb)
634
635            print 'mpkb total stats'
636
637        mpkb = misses / ((rxbytes + txbytes) / 1024)
638        misses.bins = None
639        if options.graph:
640            graphdata(runs, options, 'mpkb', 'Misses / KB',  mpkb)
641        else:
642            printdata(runs, mpkb)
643        return
644
645    if command == 'ipkb':
646        interrupts = system.full_cpu.kern.faults[4]
647        rxbytes = system.tsunami.etherdev.rxBytes
648        txbytes = system.tsunami.etherdev.txBytes
649
650        if options.binned:
651            print 'ipkb kernel stats'
652            interrupts.bins = 'kernel'
653            ipkb = interrupts / ((rxbytes + txbytes) / 1024)
654            printdata(runs, ipkb)
655
656            print 'ipkb idle stats'
657            interrupts.bins = 'idle'
658            ipkb = interrupts / ((rxbytes + txbytes) / 1024)
659            printdata(runs, ipkb)
660
661            print 'ipkb user stats'
662            interrupts.bins = 'user'
663            ipkb = interrupts / ((rxbytes + txbytes) / 1024)
664            printdata(runs, ipkb)
665
666            print 'ipkb total stats'
667
668        ipkb = interrupts / ((rxbytes + txbytes) / 1024)
669        interrupts.bins = None
670        if options.graph:
671            graphdata(runs, options, 'ipkb', 'Interrupts / KB',  ipkb)
672        else:
673            printdata(runs, ipkb)
674        return
675
676    if command == 'execute':
677        printdata(runs, system.full_cpu.ISSUE__count)
678        return
679
680    if command == 'commit':
681        printdata(runs, system.full_cpu.COM__count)
682        return
683
684    if command == 'fetch':
685        printdata(runs, system.full_cpu.FETCH__count)
686        return
687
688    if command == 'bpp':
689        ed = system.tsunami.etherdev
690        bpp = (ed.rxBytes + ed.txBytes) / (ed.rxPackets + ed.txPackets)
691        if options.graph:
692            graphdata(runs, options, 'bpp', 'Bytes / Packet',  bpp)
693        else:
694            printdata(runs, bpp)
695        return
696
697    if command == 'rxbpp':
698        bpp = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.rxPackets
699        if options.graph:
700            graphdata(runs, options, 'rxbpp', 'Receive Bytes / Packet',  bpp)
701        else:
702            printdata(runs, bpp)
703        return
704
705    if command == 'txbpp':
706        bpp = system.tsunami.etherdev.txBytes / system.tsunami.etherdev.txPackets
707        if options.graph:
708            graphdata(runs, options, 'txbpp', 'Transmit Bytes / Packet',  bpp)
709        else:
710            printdata(runs, bpp)
711        return
712
713    if command == 'rtp':
714        rtp = system.tsunami.etherdev.rxPackets / system.tsunami.etherdev.txPackets
715        if options.graph:
716            graphdata(runs, options, 'rtp', 'rxPackets / txPackets',  rtp)
717        else:
718            printdata(runs, rtp)
719        return
720
721    if command == 'rtb':
722        rtb = system.tsunami.etherdev.rxBytes / system.tsunami.etherdev.txBytes
723        if options.graph:
724            graphdata(runs, options, 'rtb', 'rxBytes / txBytes',  rtb)
725        else:
726            printdata(runs, rtb)
727        return
728
729    raise CommandException
730
731
732class Options: pass
733
734if __name__ == '__main__':
735    import getpass
736
737    options = Options()
738    options.host = 'zizzer.pool'
739    options.db = None
740    options.passwd = ''
741    options.user = getpass.getuser()
742    options.runs = None
743    options.system = 'client'
744    options.get = None
745    options.binned = False
746    options.graph = False
747    options.graph68 = False
748    options.ticks = False
749
750    opts, args = getopts(sys.argv[1:], '-6BEFGd:g:h:pr:s:u:T:')
751    for o,a in opts:
752        if o == '-6':
753            options.graph68 = True
754        if o == '-B':
755            options.binned = True
756        if o == '-E':
757            printval.mode = 'E'
758        if o == '-F':
759            printval.mode = 'F'
760        if o == '-G':
761            options.graph = True;
762        if o == '-d':
763            options.db = a
764        if o == '-g':
765            options.get = a
766        if o == '-h':
767            options.host = a
768        if o == '-p':
769            options.passwd = getpass.getpass()
770        if o == '-r':
771            options.runs = a
772        if o == '-u':
773            options.user = a
774        if o == '-s':
775            options.system = a
776        if o == '-T':
777            options.ticks = a
778
779    if len(args) == 0:
780        usage()
781
782    command = args[0]
783    args = args[1:]
784
785    try:
786        commands(options, command, args)
787    except CommandException:
788        usage()
789