remove version in all files
[dpdk.git] / app / test / graph_mempool.py
1 #!/usr/bin/env python
2
3 #   BSD LICENSE
4
5 #   Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
6 #   All rights reserved.
7
8 #   Redistribution and use in source and binary forms, with or without 
9 #   modification, are permitted provided that the following conditions 
10 #   are met:
11
12 #     * Redistributions of source code must retain the above copyright 
13 #       notice, this list of conditions and the following disclaimer.
14 #     * Redistributions in binary form must reproduce the above copyright 
15 #       notice, this list of conditions and the following disclaimer in 
16 #       the documentation and/or other materials provided with the 
17 #       distribution.
18 #     * Neither the name of Intel Corporation nor the names of its 
19 #       contributors may be used to endorse or promote products derived 
20 #       from this software without specific prior written permission.
21
22 #   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
23 #   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
24 #   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
25 #   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
26 #   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
27 #   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28 #   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
29 #   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
30 #   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34
35 import sys, re
36 import numpy as np
37 import matplotlib
38 matplotlib.use('Agg') # we don't want to use X11
39 import matplotlib.pyplot as plt
40 from matplotlib.ticker import FuncFormatter
41
42 INT = "([-+]?[0-9][0-9]*)"
43
44 class MempoolTest:
45     l = []
46
47     def __init__(self):
48         pass
49
50     # sort a test case list
51     def sort(self, x, y):
52         for t in [ "cache", "cores", "n_get_bulk", "n_put_bulk",
53                    "n_keep", "rate" ]:
54             if x[t] > y[t]:
55                 return 1
56             if x[t] < y[t]:
57                 return -1
58         return 0
59
60     # add a test case
61     def add(self, **args):
62         self.l.append(args)
63
64     # get an ordered list matching parameters
65     # ex: r.get(enq_core=1, deq_core=1)
66     def get(self, **args):
67         retlist = []
68         for t in self.l:
69             add_it = 1
70             for a in args:
71                 if args[a] != t[a]:
72                     add_it = 0
73                     break
74             if add_it:
75                 retlist.append(t)
76         retlist.sort(cmp=self.sort)
77         return retlist
78
79     # return an ordered list of all values for this param or param list
80     # ex: r.get_value_list("enq_core")
81     def get_value_list(self, param):
82         retlist = []
83         if type(param) is not list:
84             param = [param]
85         for t in self.l:
86             entry = []
87             for p in param:
88                 entry.append(t[p])
89             if len(entry) == 1:
90                 entry = entry[0]
91             else:
92                 entry = tuple(entry)
93             if not entry in retlist:
94                 retlist.append(entry)
95         retlist.sort()
96         return retlist
97
98 # read the file and return a MempoolTest object containing all data
99 def read_data_from_file(filename):
100
101     mempool_test = MempoolTest()
102
103     # parse the file: it produces a list of dict containing the data for
104     # each test case (each dict in the list corresponds to a line)
105     f = open(filename)
106     while True:
107         l = f.readline()
108
109         if l == "":
110             break
111
112         regexp  = "mempool_autotest "
113         regexp += "cache=%s cores=%s "%(INT, INT)
114         regexp += "n_get_bulk=%s n_put_bulk=%s "%(INT, INT)
115         regexp += "n_keep=%s rate_persec=%s"%(INT, INT)
116         m = re.match(regexp, l)
117         if m == None:
118             continue
119
120         mempool_test.add(cache = int(m.groups()[0]),
121                          cores = int(m.groups()[1]),
122                          n_get_bulk = int(m.groups()[2]),
123                          n_put_bulk = int(m.groups()[3]),
124                          n_keep = int(m.groups()[4]),
125                          rate = int(m.groups()[5]))
126
127     f.close()
128     return mempool_test
129
130 def millions(x, pos):
131     return '%1.1fM' % (x*1e-6)
132
133 # graph one, with specific parameters -> generate a .svg file
134 def graph_one(str, mempool_test, cache, cores, n_keep):
135     filename = "mempool_%d_%d_%d.svg"%(cache, cores, n_keep)
136
137     n_get_bulk_list = mempool_test.get_value_list("n_get_bulk")
138     N_n_get_bulk = len(n_get_bulk_list)
139     get_names = map(lambda x:"get=%d"%x, n_get_bulk_list)
140
141     n_put_bulk_list = mempool_test.get_value_list("n_put_bulk")
142     N_n_put_bulk = len(n_put_bulk_list)
143     put_names = map(lambda x:"put=%d"%x, n_put_bulk_list)
144
145     N = N_n_get_bulk * (N_n_put_bulk + 1)
146     rates = []
147
148     colors = []
149     for n_get_bulk in mempool_test.get_value_list("n_get_bulk"):
150         col = 0.
151         for n_put_bulk in mempool_test.get_value_list("n_put_bulk"):
152             col += 0.9 / len(mempool_test.get_value_list("n_put_bulk"))
153             r = mempool_test.get(cache=cache, cores=cores,
154                                  n_get_bulk=n_get_bulk,
155                                  n_put_bulk=n_put_bulk, n_keep=n_keep)
156             if len(r) != 0:
157                 r = r[0]["rate"]
158                 rates.append(r)
159             colors.append((1. - col, 0.2, col, 1.)) # rgba
160
161         rates.append(0)
162         colors.append((0.,0.,0.,0.))
163
164     ind = np.arange(N)  # the x locations for the groups
165     width = 1           # the width of the bars: can also be len(x) sequence
166
167
168     formatter = FuncFormatter(millions)
169     fig = plt.figure()
170     p = plt.bar(ind, tuple(rates), width, color=tuple(colors))
171     fig.axes[0].yaxis.set_major_formatter(formatter)
172
173     plt.ylabel('Obj/sec')
174     #plt.ylim(0, 400000000.)
175     title  = "Mempool autotest \"%s\"\n"%(str)
176     title += "cache=%d, core(s)=%d, n_keep=%d"%(cache, cores, n_keep)
177     plt.title(title)
178     ind_names = np.arange(N_n_get_bulk) * (N_n_put_bulk+1) + (N_n_put_bulk+1) / 2
179     plt.xticks(ind_names, tuple(get_names))
180     plt.legend(tuple([p[i] for i in range(N_n_put_bulk)]), tuple(put_names),
181                loc="upper left")
182     plt.savefig(filename)
183
184 if len(sys.argv) != 3:
185     print "usage: graph_mempool.py file title"
186     sys.exit(1)
187
188 mempool_test = read_data_from_file(sys.argv[1])
189
190 for cache, cores, n_keep in mempool_test.get_value_list(["cache", "cores",
191                                                          "n_keep"]):
192     graph_one(sys.argv[2], mempool_test, cache, cores, n_keep)