diff options
| author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-02-22 00:38:14 -0500 |
|---|---|---|
| committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-02-22 00:38:14 -0500 |
| commit | 65fa321d63cfd3a38309b7ec8907df5c4a8d26b6 (patch) | |
| tree | 01b3da5865e6494d097bc5c582f903a357cbef41 | |
| parent | 9e80e0d0b43a92cf12ffdc306b324c06142c97ff (diff) | |
finally usable plotters!
| -rwxr-xr-x[-rw-r--r--] | gnuplot.py | 11 | ||||
| -rwxr-xr-x | plot.py | 138 |
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 | ||
| 1 | import defapp | 2 | import defapp |
| 2 | from subprocess import Popen, PIPE | 3 | from subprocess import Popen, PIPE |
| 3 | from optparse import make_option as o | 4 | from 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 | ||
| 77 | def gnuplot(*args, **kargs): | ||
| 78 | cmd = gnuplot_cmd(*args, **kargs) | ||
| 79 | pipe2gnuplot(cmd) | ||
| 80 | |||
| 76 | def eps2pdf(file): | 81 | def 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 | ||
| 105 | class Plotter(defapp.App): | 112 | class 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 | ||
| 137 | if __name__ == "__main__": | 144 | if __name__ == "__main__": |
| 138 | Plotter().launch() | 145 | GnuPlotter().launch() |
| @@ -0,0 +1,138 @@ | |||
| 1 | #!/usr/bin/env python | ||
| 2 | import defapp | ||
| 3 | from os.path import splitext, basename | ||
| 4 | from optparse import make_option as o | ||
| 5 | from tempfile import NamedTemporaryFile as Tmp | ||
| 6 | |||
| 7 | from gnuplot import gnuplot, FORMATS | ||
| 8 | |||
| 9 | options = [ | ||
| 10 | o('-f', '--format', action='store', dest='format', type='choice', | ||
| 11 | choices=FORMATS, help='output format'), | ||
| 12 | ] | ||
| 13 | |||
| 14 | defaults = { | ||
| 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 | |||
| 25 | def 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 | |||
| 35 | def 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 | |||
| 53 | def 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 | |||
| 74 | class 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 | |||
| 137 | if __name__ == "__main__": | ||
| 138 | SchedPlotter().launch() | ||
