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