aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2009-02-22 00:38:14 -0500
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2009-02-22 00:38:14 -0500
commit65fa321d63cfd3a38309b7ec8907df5c4a8d26b6 (patch)
tree01b3da5865e6494d097bc5c582f903a357cbef41
parent9e80e0d0b43a92cf12ffdc306b324c06142c97ff (diff)
finally usable plotters!
-rwxr-xr-x[-rw-r--r--]gnuplot.py11
-rwxr-xr-xplot.py138
2 files changed, 147 insertions, 2 deletions
diff --git a/gnuplot.py b/gnuplot.py
index d610875..e16de77 100644..100755
--- a/gnuplot.py
+++ b/gnuplot.py
@@ -1,3 +1,4 @@
1#!/usr/bin/env python
1import defapp 2import defapp
2from subprocess import Popen, PIPE 3from subprocess import Popen, PIPE
3from optparse import make_option as o 4from optparse import make_option as o
@@ -73,6 +74,10 @@ def pipe2gnuplot(cmds):
73 proc.stdin.close() 74 proc.stdin.close()
74 proc.wait() 75 proc.wait()
75 76
77def gnuplot(*args, **kargs):
78 cmd = gnuplot_cmd(*args, **kargs)
79 pipe2gnuplot(cmd)
80
76def eps2pdf(file): 81def eps2pdf(file):
77 Popen(['ps2pdf', '-dEPSCrop', '%s.eps' % file]).wait() 82 Popen(['ps2pdf', '-dEPSCrop', '%s.eps' % file]).wait()
78 83
@@ -100,9 +105,11 @@ defaults = {
100 'ylabel' : None, 105 'ylabel' : None,
101 'xrange' : None, 106 'xrange' : None,
102 'yrange' : None, 107 'yrange' : None,
108 'xticks' : None,
109 'yticks' : None,
103 } 110 }
104 111
105class Plotter(defapp.App): 112class GnuPlotter(defapp.App):
106 def __init__(self): 113 def __init__(self):
107 defapp.App.__init__(self, options, defaults, no_std_opts=True) 114 defapp.App.__init__(self, options, defaults, no_std_opts=True)
108 115
@@ -135,4 +142,4 @@ class Plotter(defapp.App):
135 self.out(cmd) 142 self.out(cmd)
136 143
137if __name__ == "__main__": 144if __name__ == "__main__":
138 Plotter().launch() 145 GnuPlotter().launch()
diff --git a/plot.py b/plot.py
new file mode 100755
index 0000000..c0218e9
--- /dev/null
+++ b/plot.py
@@ -0,0 +1,138 @@
1#!/usr/bin/env python
2import defapp
3from os.path import splitext, basename
4from optparse import make_option as o
5from tempfile import NamedTemporaryFile as Tmp
6
7from gnuplot import gnuplot, FORMATS
8
9options = [
10 o('-f', '--format', action='store', dest='format', type='choice',
11 choices=FORMATS, help='output format'),
12 ]
13
14defaults = {
15 'format' : 'show',
16 'xrange' : (0.5, 32.5),
17 'yrange' : (-0.05, 1.05),
18 'xticks' : (0, 2),
19 'yticks' : (0, 0.1),
20 'title' : None,
21 'xlabel' : 'task set utilization cap (prior to inflation)',
22 'ylabel' : 'ratio of schedulable task sets',
23 }
24
25def decode(name):
26 params = {}
27 parts = name.split('_')
28 for p in parts:
29 kv = p.split('=')
30 k = kv[0]
31 v = kv[1] if len(kv) > 1 else None
32 params[k] = v
33 return params
34
35def get_data_tmpfile(datafile):
36 """Removes all comments form datafile, stores result in a temp file.
37 The temp file is returned."""
38 count = 0
39 f = open(datafile, 'r')
40 d = Tmp()
41 for line in f:
42 if len(line) > 1 and line[0] != '#':
43 d.write(line)
44 count += 1
45 f.close()
46 d.flush()
47 if count > 0:
48 return d
49 else:
50 del d # removes temp file
51 return None
52
53def scenario_heading(conf):
54 dist = 'unknown distribution'
55 if 'dist' in conf:
56 if conf['dist'] == 'uni':
57 dist = 'uniformly distributed'
58 if 'light' in conf:
59 dist = dist + ' in [0.001, 0.1]'
60 elif 'medium' in conf:
61 dist = dist + ' in [0.1, 0.4]'
62 elif 'heavy' in conf:
63 dist = dist + ' in [0.5, 0.9]'
64 elif conf['dist'] == 'bimo':
65 dist = 'bimodially distributed'
66 if 'light' in conf:
67 dist = dist + 'in [0.001, 0.5] (8/9) and [0.5, 0.9] (1/9)'
68 elif 'medium' in conf:
69 dist = dist + 'in [0.001, 0.5] (6/9) and [0.5, 0.9] (3/9)'
70 elif 'heavy' in conf:
71 dist = dist + 'in [0.001, 0.5] (4/9) and [0.5, 0.9] (5/9)'
72 return dist
73
74class SchedPlotter(defapp.App):
75 def __init__(self):
76 defapp.App.__init__(self, options, defaults, no_std_opts=True)
77
78 def plot(self, graphs, title, name, conf):
79 gnuplot(graphs, title=title,
80 xlabel=self.options.xlabel,
81 ylabel=self.options.ylabel +
82 (' [soft]' if 'soft' in conf else ' [hard]'),
83 xrange=self.options.xrange,
84 yrange=self.options.yrange,
85 xticks=self.options.xticks,
86 yticks=self.options.yticks,
87 format=self.options.format,
88 fname=name)
89
90 def plot_spec(self, tmpfile, name, conf):
91 title = 'release overhead speculation: ' + scenario_heading(conf)
92 graphs = [
93 (tmpfile, 1, 2, 'G-EDF (100% release)'),
94 (tmpfile, 1, 3, 'G-EDF ( 75% release)'),
95 (tmpfile, 1, 4, 'G-EDF ( 50% release)'),
96 (tmpfile, 1, 5, 'G-EDF ( 25% release)'),
97 (tmpfile, 1, 6, 'G-EDF ( 0% release)'),
98 (tmpfile, 1, 7, 'G-EDF (no overheads)'),
99 ]
100 self.plot(graphs, title, name, conf)
101
102 def plot_spec2(self, tmpfile, name, conf):
103 title = 'service processor speculation: ' + scenario_heading(conf)
104 graphs = [
105 (tmpfile, 1, 2, 'G-EDF ( 25% release, 100% rest)'),
106 (tmpfile, 1, 3, 'G-EDF (100% release, 0% rest)'),
107 (tmpfile, 1, 4, 'G-EDF (service cpu, 100% preempt)'),
108 (tmpfile, 1, 5, 'G-EDF (service cpu, 150% preempt)'),
109 ]
110 self.plot(graphs, title, name, conf)
111
112 def plot_file(self, datafile):
113 bname = basename(datafile)
114 name, ext = splitext(bname)
115 if ext != '.csv':
116 self.err("Warning: '%s' doesn't look like a CSV file."
117 % bname)
118 conf = decode(name)
119 tmpfile = get_data_tmpfile(datafile)
120 if tmpfile:
121 if 'spec' in conf:
122 self.plot_spec(tmpfile.name, name, conf)
123 elif 'spec2' in conf:
124 self.plot_spec2(tmpfile.name, name, conf)
125 else:
126 self.err("Skipped '%s'; unkown experiment type."
127 % bname)
128 del tmpfile # removes temp file
129 else:
130 self.err("Skipped '%s'; it dosn't appear to contain data."
131 % bname)
132
133 def default(self, _):
134 for datafile in self.args:
135 self.plot_file(datafile)
136
137if __name__ == "__main__":
138 SchedPlotter().launch()