source: benchmark/rmit.py @ 7a2a3af

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 7a2a3af was 7a2a3af, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Added more information to cycle output

  • Property mode set to 100755
File size: 6.3 KB
RevLine 
[7a2a3af]1#!/usr/bin/python3
2"""
3Python Script to implement R.M.I.T. testing : Randomized Multiple Interleaved Trials
4
5./rmit.py run COMMAND CANDIDATES
6-t trials
7-o option:values
8"""
9
10
11import argparse
12import itertools
13import os
14import random
15import re
16import subprocess
17import sys
18
19
20def parse_range(x):
21    result = []
22    for part in x.split(','):
23        if '-' in part:
24            a, b = part.split('-')
25            a, b = int(a), int(b)
26            result.extend(range(a, b + 1))
27        else:
28            a = int(part)
29            result.append(a)
30    return result
31
32class DependentOpt:
33        def __init__(self, key, value):
34                self.key = key
35                self.value = value
36                self.vars = re.findall("[a-zA-Z]", value)
37
38def parse_option(opt):
39        match = re.search("^(.*):(.*)$", opt)
40        if not match :
41                print('ERROR: extra options should match pattern .*:.*, got {}'.format(opt), file=sys.stderr)
42                sys.exit(1)
43
44        key    = match.group(1)
45        values = match.group(2)
46
47        try:
48                num = int(values)
49                return key, [num]
50        except:
51                pass
52
53        if re.search("^[0-9-,]+$", values):
54                values = parse_range(values)
55                return key, [v for v in values]
56        else:
57                return key, DependentOpt(key, values)
58
59def eval_one(fmt, vals):
60        orig = fmt
61        for k, v in vals:
62                fmt = fmt.replace(k, str(v))
63
64        if not re.search("^[0-9-/*+ ]+$", fmt):
65                print('ERROR: pattern option {} (interpreted as {}) could not be evaluated'.format(orig, fmt), file=sys.stderr)
66                sys.exit(1)
67
68        return eval(fmt)
69
70def eval_options(opts):
71        dependents = [d for d in opts.values() if type(d) is DependentOpt]
72        processed = []
73        nopts = []
74        for d in dependents:
75                processed.append(d.key)
76                lists = []
77                for dvar in d.vars:
78                        if not dvar in opts.keys():
79                                print('ERROR: extra pattern option {}:{} uses unknown key {}'.format(d.key,d.value,dvar), file=sys.stderr)
80                                sys.exit(1)
81
82                        lists.append([(dvar, o) for o in opts[dvar]])
83                        processed.append(dvar)
84
85                kopt = []
86                for vals in list(itertools.product(*lists)):
87                        res = ['-{}'.format(d.key), "{}".format(eval_one(d.value, vals))]
88                        for k, v in vals:
89                                res.extend(['-{}'.format(k), "{}".format(v)])
90                        kopt.append(res)
91                nopts.append(kopt)
92
93
94        for k, vals in opts.items():
95                if k not in processed:
96                        kopt = []
97                        for v in vals:
98                                kopt.append(['-{}'.format(k), "{}".format(v)])
99                        nopts.append(kopt)
100
101        return nopts
102
103if __name__ == "__main__":
104        # ================================================================================
105        # parse command line arguments
106        formats = ['raw', 'csv']
107        parser = argparse.ArgumentParser(description='Python Script to implement R.M.I.T. testing : Randomized Multiple Interleaved Trials')
108        parser.add_argument('--list', help='List all the commands that would be run', action='store_true')
109        parser.add_argument('--format', help='How to print the result', choices=formats, default='csv')
110        parser.add_argument('--file', nargs='?', type=argparse.FileType('w'), default=sys.stdout)
111        parser.add_argument('-t', '--trials', help='Number of trials to run per combinaison', type=int, default=3)
112        parser.add_argument('-o','--option',action='append')
113        parser.add_argument('command', metavar='command', type=str, nargs=1, help='the command prefix to run')
114        parser.add_argument('candidates', metavar='candidates', type=str, nargs='*', help='the candidate suffix to run')
115
116        try:
117                options =  parser.parse_args()
118        except:
119                print('ERROR: invalid arguments', file=sys.stderr)
120                parser.print_help(sys.stderr)
121                sys.exit(1)
122
123        # ================================================================================
124        # Identify the commands to run
125        commands = ["./" + options.command[0] + "-" + c for c in options.candidates]
126        for c in commands:
127                if not os.path.isfile(c):
128                        print('ERROR: invalid command {}, file does not exist'.format(c), file=sys.stderr)
129                        sys.exit(1)
130
131                if not os.access(c, os.X_OK):
132                        print('ERROR: invalid command {}, file not executable'.format(c), file=sys.stderr)
133                        sys.exit(1)
134
135
136        # ================================================================================
137        # Identify the options to run
138        opts = dict([parse_option(o) for o in options.option])
139
140        # Evaluate the options (options can depend on the value of other options)
141        opts = eval_options(opts)
142
143        # ================================================================================
144        # Figure out all the combinations to run
145        actions = []
146        for p in itertools.product(range(options.trials), commands, *opts):
147                act = [p[1]]
148                for o in p[2:]:
149                        act.extend(o)
150                actions.append(act)
151
152        # ================================================================================
153        # Figure out all the combinations to run
154        if options.list:
155                for a in actions:
156                        print(" ".join(a))
157                sys.exit(0)
158
159
160        # ================================================================================
161        # Prepare to run
162        random.shuffle(actions)
163
164        print("Running {} trials".format(len(actions)))
165        result = []
166
167        # ================================================================================
168        # Run
169        for i, a in enumerate(actions):
170                sa = " ".join(a)
171                print("{}/{} : {}          \r".format(i, len(actions), sa), end = '')
172                fields = {}
173                with subprocess.Popen( a, stdout  = subprocess.PIPE, stderr  = subprocess.PIPE) as proc:
174                        out, err = proc.communicate()
175                        if proc.returncode != 0:
176                                print("ERROR: command '{}' encountered error, returned code {}".format(sa, proc.returncode), file=sys.stderr)
177                                print(err.decode("utf-8"))
178                                sys.exit(1)
179                        for s in out.decode("utf-8").splitlines():
180                                match = re.search("^(.*):(.*)$", s)
181                                if match:
182                                        fields[match.group(1).strip()] = float(match.group(2).strip().replace(',',''))
183
184                result.append([a[0][2:], sa, fields])
185
186        print("Done                                                                                ")
187
188        # ================================================================================
189        # Print csv
190        if options.format == 'raw':
191                for r in result:
192                        print(r, file=options.file)
193                sys.exit(0)
194
195        # ================================================================================
196        # Print csv
197        if options.format == 'csv':
198                # Clean result
199                headers = ["series", "command"]
200                data = []
201                first = True
202                for r in result:
203                        if first:
204                                first = False
205                                headers.extend(r[2].keys())
206                        else :
207                                pass
208
209                        d = [r[0], r[1]]
210                        for k in headers[2:]:
211                                d.append(r[2][k])
212
213                        data.append(d)
214
215                # Print csv
216                print(",\t".join(headers), file=options.file)
217                for d in data:
218                        print(",\t".join(["{}".format(dd) for dd in d]), file=options.file)
219                sys.exit(0)
Note: See TracBrowser for help on using the repository browser.