xref: /freebsd-src/contrib/cortex-strings/scripts/plot.py (revision 8c4282b370bd66908b45b6a223226a9fc2b69d57)
1*09a53ad8SAndrew Turner"""Plot the results for each test.  Spits out a set of images into the
2*09a53ad8SAndrew Turnercurrent directory.
3*09a53ad8SAndrew Turner"""
4*09a53ad8SAndrew Turner
5*09a53ad8SAndrew Turnerimport libplot
6*09a53ad8SAndrew Turner
7*09a53ad8SAndrew Turnerimport fileinput
8*09a53ad8SAndrew Turnerimport collections
9*09a53ad8SAndrew Turnerimport pprint
10*09a53ad8SAndrew Turner
11*09a53ad8SAndrew Turnerimport pylab
12*09a53ad8SAndrew Turner
13*09a53ad8SAndrew TurnerRecord = collections.namedtuple('Record', 'variant test size loops src_alignment dst_alignment run_id rawtime comment time bytes rate')
14*09a53ad8SAndrew Turner
15*09a53ad8SAndrew Turnerdef unique(rows, name):
16*09a53ad8SAndrew Turner    """Takes a list of values, pulls out the named field, and returns
17*09a53ad8SAndrew Turner    a list of the unique values of this field.
18*09a53ad8SAndrew Turner    """
19*09a53ad8SAndrew Turner    return sorted(set(getattr(x, name) for x in rows))
20*09a53ad8SAndrew Turner
21*09a53ad8SAndrew Turnerdef to_float(v):
22*09a53ad8SAndrew Turner    """Convert a string into a better type.
23*09a53ad8SAndrew Turner
24*09a53ad8SAndrew Turner    >>> to_float('foo')
25*09a53ad8SAndrew Turner    'foo'
26*09a53ad8SAndrew Turner    >>> to_float('1.23')
27*09a53ad8SAndrew Turner    1.23
28*09a53ad8SAndrew Turner    >>> to_float('45')
29*09a53ad8SAndrew Turner    45
30*09a53ad8SAndrew Turner    """
31*09a53ad8SAndrew Turner    try:
32*09a53ad8SAndrew Turner        if '.' in v:
33*09a53ad8SAndrew Turner            return float(v)
34*09a53ad8SAndrew Turner        else:
35*09a53ad8SAndrew Turner            return int(v)
36*09a53ad8SAndrew Turner    except:
37*09a53ad8SAndrew Turner        return v
38*09a53ad8SAndrew Turner
39*09a53ad8SAndrew Turnerdef parse():
40*09a53ad8SAndrew Turner    # Split the input up
41*09a53ad8SAndrew Turner    rows = [x.strip().split(':') for x in fileinput.input()]
42*09a53ad8SAndrew Turner    # Automatically turn numbers into the base type
43*09a53ad8SAndrew Turner    rows = [[to_float(y) for y in x] for x in rows]
44*09a53ad8SAndrew Turner
45*09a53ad8SAndrew Turner    # Scan once to calculate the overhead
46*09a53ad8SAndrew Turner    r = [Record(*(x + [0, 0, 0])) for x in rows]
47*09a53ad8SAndrew Turner    bounces = pylab.array([(x.loops, x.rawtime) for x in r if x.test == 'bounce'])
48*09a53ad8SAndrew Turner    fit = pylab.polyfit(bounces[:,0], bounces[:,1], 1)
49*09a53ad8SAndrew Turner
50*09a53ad8SAndrew Turner    records = []
51*09a53ad8SAndrew Turner
52*09a53ad8SAndrew Turner    for row in rows:
53*09a53ad8SAndrew Turner        # Make a dummy record so we can use the names
54*09a53ad8SAndrew Turner        r1 = Record(*(row + [0, 0, 0]))
55*09a53ad8SAndrew Turner
56*09a53ad8SAndrew Turner        bytes = r1.size * r1.loops
57*09a53ad8SAndrew Turner        # Calculate the bounce time
58*09a53ad8SAndrew Turner        delta = pylab.polyval(fit, [r1.loops])
59*09a53ad8SAndrew Turner        time = r1.rawtime - delta
60*09a53ad8SAndrew Turner        rate = bytes / time
61*09a53ad8SAndrew Turner
62*09a53ad8SAndrew Turner        records.append(Record(*(row + [time, bytes, rate])))
63*09a53ad8SAndrew Turner
64*09a53ad8SAndrew Turner    return records
65*09a53ad8SAndrew Turner
66*09a53ad8SAndrew Turnerdef plot(records, field, scale, ylabel):
67*09a53ad8SAndrew Turner    variants = unique(records, 'variant')
68*09a53ad8SAndrew Turner    tests = unique(records, 'test')
69*09a53ad8SAndrew Turner
70*09a53ad8SAndrew Turner    colours = libplot.make_colours()
71*09a53ad8SAndrew Turner
72*09a53ad8SAndrew Turner    # A little hack.  We want the 'all' record to be drawn last so
73*09a53ad8SAndrew Turner    # that it's obvious on the graph.  Assume that no tests come
74*09a53ad8SAndrew Turner    # before it alphabetically
75*09a53ad8SAndrew Turner    variants.reverse()
76*09a53ad8SAndrew Turner
77*09a53ad8SAndrew Turner    for test in tests:
78*09a53ad8SAndrew Turner        for variant in variants:
79*09a53ad8SAndrew Turner            v = [x for x in records if x.test==test and x.variant==variant]
80*09a53ad8SAndrew Turner            v.sort(key=lambda x: x.size)
81*09a53ad8SAndrew Turner            V = pylab.array([(x.size, getattr(x, field)) for x in v])
82*09a53ad8SAndrew Turner
83*09a53ad8SAndrew Turner            # Ensure our results appear
84*09a53ad8SAndrew Turner            order = 1 if variant == 'this' else 0
85*09a53ad8SAndrew Turner
86*09a53ad8SAndrew Turner            try:
87*09a53ad8SAndrew Turner                # A little hack.  We want the 'all' to be obvious on
88*09a53ad8SAndrew Turner                # the graph
89*09a53ad8SAndrew Turner                if variant == 'all':
90*09a53ad8SAndrew Turner                    pylab.scatter(V[:,0], V[:,1]/scale, label=variant)
91*09a53ad8SAndrew Turner                    pylab.plot(V[:,0], V[:,1]/scale)
92*09a53ad8SAndrew Turner                else:
93*09a53ad8SAndrew Turner                    pylab.plot(V[:,0], V[:,1]/scale, label=variant,
94*09a53ad8SAndrew Turner                            zorder=order, c = colours.next())
95*09a53ad8SAndrew Turner
96*09a53ad8SAndrew Turner            except Exception, ex:
97*09a53ad8SAndrew Turner                # michaelh1 likes to run this script while the test is
98*09a53ad8SAndrew Turner                # still running which can lead to bad data
99*09a53ad8SAndrew Turner                print ex, 'on %s of %s' % (variant, test)
100*09a53ad8SAndrew Turner
101*09a53ad8SAndrew Turner        pylab.legend(loc='lower right', ncol=2, prop={'size': 'small'})
102*09a53ad8SAndrew Turner        pylab.xlabel('Block size (B)')
103*09a53ad8SAndrew Turner        pylab.ylabel(ylabel)
104*09a53ad8SAndrew Turner        pylab.title('%s %s' % (test, field))
105*09a53ad8SAndrew Turner        pylab.grid()
106*09a53ad8SAndrew Turner
107*09a53ad8SAndrew Turner        pylab.savefig('%s-%s.png' % (test, field), dpi=100)
108*09a53ad8SAndrew Turner        pylab.semilogx(basex=2)
109*09a53ad8SAndrew Turner        pylab.savefig('%s-%s-semilog.png' % (test, field), dpi=100)
110*09a53ad8SAndrew Turner        pylab.clf()
111*09a53ad8SAndrew Turner
112*09a53ad8SAndrew Turnerdef test():
113*09a53ad8SAndrew Turner    import doctest
114*09a53ad8SAndrew Turner    doctest.testmod()
115*09a53ad8SAndrew Turner
116*09a53ad8SAndrew Turnerdef main():
117*09a53ad8SAndrew Turner    records = parse()
118*09a53ad8SAndrew Turner
119*09a53ad8SAndrew Turner    plot(records, 'rate', 1024**2, 'Rate (MB/s)')
120*09a53ad8SAndrew Turner    plot(records, 'time', 1, 'Total time (s)')
121*09a53ad8SAndrew Turner
122*09a53ad8SAndrew Turnerif __name__ == '__main__':
123*09a53ad8SAndrew Turner    main()
124