OLD | NEW |
---|---|
1 ''' | 1 ''' |
2 Created on May 19, 2011 | 2 Created on May 19, 2011 |
3 | 3 |
4 @author: bungeman | 4 @author: bungeman |
5 ''' | 5 ''' |
6 | 6 |
7 import re | 7 import re |
8 import math | 8 import math |
9 | 9 |
10 # bench representation algorithm constant names | 10 # bench representation algorithm constant names |
(...skipping 21 matching lines...) Expand all Loading... | |
32 SETTINGS_RE_COMPILED = re.compile(SETTINGS_RE) | 32 SETTINGS_RE_COMPILED = re.compile(SETTINGS_RE) |
33 BENCH_RE_COMPILED = re.compile(BENCH_RE) | 33 BENCH_RE_COMPILED = re.compile(BENCH_RE) |
34 TIME_RE_COMPILED = re.compile(TIME_RE) | 34 TIME_RE_COMPILED = re.compile(TIME_RE) |
35 CONFIG_RE_COMPILED = re.compile(CONFIG_RE) | 35 CONFIG_RE_COMPILED = re.compile(CONFIG_RE) |
36 TILE_RE_COMPILED = re.compile(TILE_RE) | 36 TILE_RE_COMPILED = re.compile(TILE_RE) |
37 TILE_LAYOUT_RE_COMPILED = re.compile(TILE_LAYOUT_RE) | 37 TILE_LAYOUT_RE_COMPILED = re.compile(TILE_LAYOUT_RE) |
38 | 38 |
39 class BenchDataPoint: | 39 class BenchDataPoint: |
40 """A single data point produced by bench. | 40 """A single data point produced by bench. |
41 | 41 |
42 (str, str, str, float, {str:str}, str, [floats])""" | 42 (str, str, str, float, {str:str}, str, [floats], [floats])""" |
borenet
2014/03/12 15:54:32
I'd really prefer to have these parameters documen
benchen
2014/03/12 16:22:51
They are member variables. I added explanations in
borenet
2014/03/12 17:13:06
Thanks. This is okay, but I'd still prefer the do
| |
43 def __init__(self, bench, config, time_type, time, settings, | 43 def __init__(self, bench, config, time_type, time, settings, |
44 tile_layout='', per_tile_values=[]): | 44 tile_layout='', per_tile_values=[], per_iter_time=[]): |
45 self.bench = bench | 45 self.bench = bench |
46 self.config = config | 46 self.config = config |
47 self.time_type = time_type | 47 self.time_type = time_type |
48 self.time = time | 48 self.time = time |
49 self.settings = settings | 49 self.settings = settings |
50 # how tiles cover the whole picture. '5x3' means 5 columns and 3 rows. | 50 # how tiles cover the whole picture. '5x3' means 5 columns and 3 rows. |
51 self.tile_layout = tile_layout | 51 self.tile_layout = tile_layout |
52 # list of per_tile bench values, if applicable | 52 # list of per_tile bench values, if applicable |
53 self.per_tile_values = per_tile_values | 53 self.per_tile_values = per_tile_values |
54 # list of per-iteration bench time | |
55 self.per_iter_time = per_iter_time | |
54 | 56 |
55 def __repr__(self): | 57 def __repr__(self): |
56 return "BenchDataPoint(%s, %s, %s, %s, %s)" % ( | 58 return "BenchDataPoint(%s, %s, %s, %s, %s)" % ( |
57 str(self.bench), | 59 str(self.bench), |
58 str(self.config), | 60 str(self.config), |
59 str(self.time_type), | 61 str(self.time_type), |
60 str(self.time), | 62 str(self.time), |
61 str(self.settings), | 63 str(self.settings), |
62 ) | 64 ) |
63 | 65 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 x = int(round(0.25 * self._len + 0.5)) | 104 x = int(round(0.25 * self._len + 0.5)) |
103 else: | 105 else: |
104 raise Exception("invalid representation algorithm %s!" % | 106 raise Exception("invalid representation algorithm %s!" % |
105 representation) | 107 representation) |
106 self._rep = self._data[x - 1] | 108 self._rep = self._data[x - 1] |
107 | 109 |
108 def compute(self): | 110 def compute(self): |
109 return self._rep | 111 return self._rep |
110 | 112 |
111 def _ParseAndStoreTimes(config_re_compiled, is_per_tile, line, bench, | 113 def _ParseAndStoreTimes(config_re_compiled, is_per_tile, line, bench, |
112 value_dic, layout_dic, representation=None): | 114 value_dic, layout_dic): |
113 """Parses given bench time line with regex and adds data to value_dic. | 115 """Parses given bench time line with regex and adds data to value_dic. |
114 | 116 |
115 config_re_compiled: precompiled regular expression for parsing the config | 117 config_re_compiled: precompiled regular expression for parsing the config |
116 line. | 118 line. |
117 is_per_tile: boolean indicating whether this is a per-tile bench. | 119 is_per_tile: boolean indicating whether this is a per-tile bench. |
118 If so, we add tile layout into layout_dic as well. | 120 If so, we add tile layout into layout_dic as well. |
119 line: input string line to parse. | 121 line: input string line to parse. |
120 bench: name of bench for the time values. | 122 bench: name of bench for the time values. |
121 value_dic: dictionary to store bench values. See bench_dic in parse() below. | 123 value_dic: dictionary to store bench values. See bench_dic in parse() below. |
122 layout_dic: dictionary to store tile layouts. See parse() for descriptions. | 124 layout_dic: dictionary to store tile layouts. See parse() for descriptions. |
123 representation: should match one of the ALGORITHM_XXX types.""" | 125 """ |
124 | 126 |
125 for config in config_re_compiled.finditer(line): | 127 for config in config_re_compiled.finditer(line): |
126 current_config = config.group(1) | 128 current_config = config.group(1) |
127 tile_layout = '' | 129 tile_layout = '' |
128 if is_per_tile: # per-tile bench, add name prefix | 130 if is_per_tile: # per-tile bench, add name prefix |
129 current_config = 'tile_' + current_config | 131 current_config = 'tile_' + current_config |
130 layouts = TILE_LAYOUT_RE_COMPILED.search(line) | 132 layouts = TILE_LAYOUT_RE_COMPILED.search(line) |
131 if layouts and len(layouts.groups()) == 2: | 133 if layouts and len(layouts.groups()) == 2: |
132 tile_layout = '%sx%s' % layouts.groups() | 134 tile_layout = '%sx%s' % layouts.groups() |
133 times = config.group(2) | 135 times = config.group(2) |
134 for new_time in TIME_RE_COMPILED.finditer(times): | 136 for new_time in TIME_RE_COMPILED.finditer(times): |
135 current_time_type = new_time.group(1) | 137 current_time_type = new_time.group(1) |
136 iters = [float(i) for i in | 138 iters = [float(i) for i in |
137 new_time.group(2).strip().split(',')] | 139 new_time.group(2).strip().split(',')] |
138 value_dic.setdefault(bench, {}).setdefault( | 140 value_dic.setdefault(bench, {}).setdefault( |
139 current_config, {}).setdefault(current_time_type, []).append( | 141 current_config, {}).setdefault(current_time_type, []).append( |
140 _ListAlgorithm(iters, representation).compute()) | 142 iters) |
141 layout_dic.setdefault(bench, {}).setdefault( | 143 layout_dic.setdefault(bench, {}).setdefault( |
142 current_config, {}).setdefault(current_time_type, tile_layout) | 144 current_config, {}).setdefault(current_time_type, tile_layout) |
143 | 145 |
144 # TODO(bensong): switch to reading JSON output when available. This way we don't | 146 # TODO(bensong): switch to reading JSON output when available. This way we don't |
145 # need the RE complexities. | 147 # need the RE complexities. |
146 def parse(settings, lines, representation=None): | 148 def parse(settings, lines, representation=None): |
147 """Parses bench output into a useful data structure. | 149 """Parses bench output into a useful data structure. |
148 | 150 |
149 ({str:str}, __iter__ -> str) -> [BenchDataPoint] | 151 ({str:str}, __iter__ -> str) -> [BenchDataPoint] |
150 representation is one of the ALGORITHM_XXX types.""" | 152 representation is one of the ALGORITHM_XXX types.""" |
151 | 153 |
152 benches = [] | 154 benches = [] |
153 current_bench = None | 155 current_bench = None |
154 bench_dic = {} # [bench][config][time_type] -> [list of bench values] | 156 # [bench][config][time_type] -> [[per-iter values]] where per-tile config |
157 # has per-iter value list for each tile [[<tile1_iter1>,<tile1_iter2>,...], | |
158 # [<tile2_iter1>,<tile2_iter2>,...],...], while non-per-tile config only | |
159 # contains one list of iterations [[iter1, iter2, ...]]. | |
160 bench_dic = {} | |
155 # [bench][config][time_type] -> tile_layout | 161 # [bench][config][time_type] -> tile_layout |
156 layout_dic = {} | 162 layout_dic = {} |
157 | 163 |
158 for line in lines: | 164 for line in lines: |
159 | 165 |
160 # see if this line is a settings line | 166 # see if this line is a settings line |
161 settingsMatch = SETTINGS_RE_COMPILED.search(line) | 167 settingsMatch = SETTINGS_RE_COMPILED.search(line) |
162 if (settingsMatch): | 168 if (settingsMatch): |
163 settings = dict(settings) | 169 settings = dict(settings) |
164 for settingMatch in PER_SETTING_RE_COMPILED.finditer(settingsMatch.g roup(1)): | 170 for settingMatch in PER_SETTING_RE_COMPILED.finditer(settingsMatch.g roup(1)): |
165 if (settingMatch.group(2)): | 171 if (settingMatch.group(2)): |
166 settings[settingMatch.group(1)] = settingMatch.group(2) | 172 settings[settingMatch.group(1)] = settingMatch.group(2) |
167 else: | 173 else: |
168 settings[settingMatch.group(1)] = True | 174 settings[settingMatch.group(1)] = True |
169 | 175 |
170 # see if this line starts a new bench | 176 # see if this line starts a new bench |
171 new_bench = BENCH_RE_COMPILED.search(line) | 177 new_bench = BENCH_RE_COMPILED.search(line) |
172 if new_bench: | 178 if new_bench: |
173 current_bench = new_bench.group(1) | 179 current_bench = new_bench.group(1) |
174 | 180 |
175 # add configs on this line to the bench_dic | 181 # add configs on this line to the bench_dic |
176 if current_bench: | 182 if current_bench: |
177 if line.startswith(' tile_') : | 183 if line.startswith(' tile_') : |
178 _ParseAndStoreTimes(TILE_RE_COMPILED, True, line, current_bench, | 184 _ParseAndStoreTimes(TILE_RE_COMPILED, True, line, current_bench, |
179 bench_dic, layout_dic, representation) | 185 bench_dic, layout_dic) |
180 else: | 186 else: |
181 _ParseAndStoreTimes(CONFIG_RE_COMPILED, False, line, | 187 _ParseAndStoreTimes(CONFIG_RE_COMPILED, False, line, |
182 current_bench, | 188 current_bench, bench_dic, layout_dic) |
183 bench_dic, layout_dic, representation) | |
184 | 189 |
185 # append benches to list, use the total time as final bench value. | 190 # append benches to list |
186 for bench in bench_dic: | 191 for bench in bench_dic: |
187 for config in bench_dic[bench]: | 192 for config in bench_dic[bench]: |
188 for time_type in bench_dic[bench][config]: | 193 for time_type in bench_dic[bench][config]: |
189 tile_layout = '' | 194 tile_layout = '' |
190 per_tile_values = [] | 195 per_tile_values = [] # empty for non-per-tile configs |
196 per_iter_time = [] # empty for per-tile configs | |
197 bench_summary = None # a single final bench value | |
191 if len(bench_dic[bench][config][time_type]) > 1: | 198 if len(bench_dic[bench][config][time_type]) > 1: |
192 # per-tile values, extract tile_layout | 199 # per-tile config; compute representation for each tile |
193 per_tile_values = bench_dic[bench][config][time_type] | 200 per_tile_values = [ |
201 _ListAlgorithm(iters, representation).compute() | |
202 for iters in bench_dic[bench][config][time_type]] | |
203 # use sum of each tile representation for total bench value | |
204 bench_summary = sum(per_tile_values) | |
205 # extract tile layout | |
194 tile_layout = layout_dic[bench][config][time_type] | 206 tile_layout = layout_dic[bench][config][time_type] |
207 else: | |
208 # get the list of per-iteration values | |
209 per_iter_time = bench_dic[bench][config][time_type][0] | |
210 bench_summary = _ListAlgorithm( | |
211 per_iter_time, representation).compute() | |
195 benches.append(BenchDataPoint( | 212 benches.append(BenchDataPoint( |
196 bench, | 213 bench, |
197 config, | 214 config, |
198 time_type, | 215 time_type, |
199 sum(bench_dic[bench][config][time_type]), | 216 bench_summary, |
200 settings, | 217 settings, |
201 tile_layout, | 218 tile_layout, |
202 per_tile_values)) | 219 per_tile_values, |
220 per_iter_time)) | |
203 | 221 |
204 return benches | 222 return benches |
205 | 223 |
206 class LinearRegression: | 224 class LinearRegression: |
207 """Linear regression data based on a set of data points. | 225 """Linear regression data based on a set of data points. |
208 | 226 |
209 ([(Number,Number)]) | 227 ([(Number,Number)]) |
210 There must be at least two points for this to make sense.""" | 228 There must be at least two points for this to make sense.""" |
211 def __init__(self, points): | 229 def __init__(self, points): |
212 n = len(points) | 230 n = len(points) |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 """ | 309 """ |
292 return '<a href="http://code.google.com/p/skia/source/detail?r=%s">%s</a>'%( | 310 return '<a href="http://code.google.com/p/skia/source/detail?r=%s">%s</a>'%( |
293 revision_number, revision_number) | 311 revision_number, revision_number) |
294 | 312 |
295 def main(): | 313 def main(): |
296 foo = [[0.0, 0.0], [0.0, 1.0], [0.0, 2.0], [0.0, 3.0]] | 314 foo = [[0.0, 0.0], [0.0, 1.0], [0.0, 2.0], [0.0, 3.0]] |
297 LinearRegression(foo) | 315 LinearRegression(foo) |
298 | 316 |
299 if __name__ == "__main__": | 317 if __name__ == "__main__": |
300 main() | 318 main() |
OLD | NEW |