OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 * | 6 * |
7 * Classes for writing out bench results in various formats. | 7 * Classes for writing out bench results in various formats. |
8 */ | 8 */ |
9 | 9 |
10 #ifndef SkPictureResultsWriter_DEFINED | 10 #ifndef SkPictureResultsWriter_DEFINED |
11 #define SkPictureResultsWriter_DEFINED | 11 #define SkPictureResultsWriter_DEFINED |
12 | 12 |
13 | |
14 #include "PictureRenderer.h" | |
13 #include "BenchLogger.h" | 15 #include "BenchLogger.h" |
14 #include "ResultsWriter.h" | 16 #include "ResultsWriter.h" |
15 #include "SkJSONCPP.h" | 17 #include "SkJSONCPP.h" |
16 #include "SkStream.h" | 18 #include "SkStream.h" |
17 #include "SkString.h" | 19 #include "SkString.h" |
18 #include "SkTArray.h" | 20 #include "SkTArray.h" |
19 #include "TimerData.h" | 21 #include "TimerData.h" |
20 | 22 |
23 using namespace sk_tools; | |
jcgregorio
2014/06/23 19:02:44
I'm leery of blanket using statements like this, d
kelvinly
2014/06/23 20:32:46
Done.
| |
24 | |
21 /** | 25 /** |
22 * Base class for writing picture bench results. | 26 * Base class for writing picture bench results. |
23 */ | 27 */ |
24 class PictureResultsWriter : SkNoncopyable { | 28 class PictureResultsWriter : SkNoncopyable { |
25 public: | 29 public: |
26 enum TileFlags {kPurging, kAvg}; | 30 enum TileFlags {kPurging, kAvg}; |
27 | 31 |
28 PictureResultsWriter() {} | 32 PictureResultsWriter() {} |
29 virtual ~PictureResultsWriter() {} | 33 virtual ~PictureResultsWriter() {} |
30 | 34 |
31 virtual void bench(const char name[], int32_t x, int32_t y) = 0; | 35 virtual void bench(const char name[], int32_t x, int32_t y) = 0; |
32 virtual void tileConfig(SkString configName) = 0; | 36 virtual void logRenderer(PictureRenderer *pr) = 0; |
33 virtual void tileMeta(int x, int y, int tx, int ty) = 0; | 37 virtual void tileMeta(int x, int y, int tx, int ty) = 0; |
34 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) = 0; | 38 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) = 0; |
35 virtual void tileData( | 39 virtual void tileData( |
36 TimerData* data, | 40 TimerData* data, |
37 const char format[], | 41 const char format[], |
38 const TimerData::Result result, | 42 const TimerData::Result result, |
39 uint32_t timerTypes, | 43 uint32_t timerTypes, |
40 int numInnerLoops = 1) = 0; | 44 int numInnerLoops = 1) = 0; |
41 virtual void end() = 0; | 45 virtual void end() = 0; |
42 }; | 46 }; |
43 | 47 |
44 /** | 48 /** |
45 * This class allows bench data to be piped into multiple | 49 * This class allows bench data to be piped into multiple |
46 * PictureResultWriter classes. It does not own any classes | 50 * PictureResultWriter classes. It does not own any classes |
47 * passed to it, so the owner is required to manage any classes | 51 * passed to it, so the owner is required to manage any classes |
48 * passed to PictureResultsMultiWriter */ | 52 * passed to PictureResultsMultiWriter */ |
49 class PictureResultsMultiWriter : public PictureResultsWriter { | 53 class PictureResultsMultiWriter : public PictureResultsWriter { |
50 public: | 54 public: |
51 PictureResultsMultiWriter() | 55 PictureResultsMultiWriter() |
52 : fWriters() {} | 56 : fWriters() {} |
53 void add(PictureResultsWriter* newWriter) { | 57 void add(PictureResultsWriter* newWriter) { |
54 fWriters.push_back(newWriter); | 58 fWriters.push_back(newWriter); |
55 } | 59 } |
56 virtual ~PictureResultsMultiWriter() {} | 60 virtual ~PictureResultsMultiWriter() {} |
57 virtual void bench(const char name[], int32_t x, int32_t y) { | 61 virtual void bench(const char name[], int32_t x, int32_t y) { |
58 for(int i=0; i<fWriters.count(); ++i) { | 62 for(int i=0; i<fWriters.count(); ++i) { |
59 fWriters[i]->bench(name, x, y); | 63 fWriters[i]->bench(name, x, y); |
60 } | 64 } |
61 } | 65 } |
62 virtual void tileConfig(SkString configName) { | 66 virtual void logRenderer(PictureRenderer *pr) { |
63 for(int i=0; i<fWriters.count(); ++i) { | 67 for(int i=0; i<fWriters.count(); ++i) { |
64 fWriters[i]->tileConfig(configName); | 68 fWriters[i]->logRenderer(pr); |
65 } | 69 } |
66 } | 70 } |
67 virtual void tileMeta(int x, int y, int tx, int ty) { | 71 virtual void tileMeta(int x, int y, int tx, int ty) { |
68 for(int i=0; i<fWriters.count(); ++i) { | 72 for(int i=0; i<fWriters.count(); ++i) { |
69 fWriters[i]->tileMeta(x, y, tx, ty); | 73 fWriters[i]->tileMeta(x, y, tx, ty); |
70 } | 74 } |
71 } | 75 } |
72 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) { | 76 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) { |
73 for(int i=0; i<fWriters.count(); ++i) { | 77 for(int i=0; i<fWriters.count(); ++i) { |
74 fWriters[i]->addTileFlag(flag); | 78 fWriters[i]->addTileFlag(flag); |
(...skipping 30 matching lines...) Expand all Loading... | |
105 } | 109 } |
106 } | 110 } |
107 public: | 111 public: |
108 PictureResultsLoggerWriter(BenchLogger* log) | 112 PictureResultsLoggerWriter(BenchLogger* log) |
109 : fLogger(log), currentLine() {} | 113 : fLogger(log), currentLine() {} |
110 virtual void bench(const char name[], int32_t x, int32_t y) { | 114 virtual void bench(const char name[], int32_t x, int32_t y) { |
111 SkString result; | 115 SkString result; |
112 result.printf("running bench [%i %i] %s ", x, y, name); | 116 result.printf("running bench [%i %i] %s ", x, y, name); |
113 this->logProgress(result.c_str()); | 117 this->logProgress(result.c_str()); |
114 } | 118 } |
115 virtual void tileConfig(SkString configName) { | 119 virtual void logRenderer(PictureRenderer* renderer) { |
116 currentLine = configName; | 120 currentLine = renderer->getConfigName(); |
117 } | 121 } |
118 virtual void tileMeta(int x, int y, int tx, int ty) { | 122 virtual void tileMeta(int x, int y, int tx, int ty) { |
119 currentLine.appendf(": tile [%i,%i] out of [%i,%i]", x, y, tx, ty); | 123 currentLine.appendf(": tile [%i,%i] out of [%i,%i]", x, y, tx, ty); |
120 } | 124 } |
121 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) { | 125 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) { |
122 if(flag == PictureResultsWriter::kPurging) { | 126 if(flag == PictureResultsWriter::kPurging) { |
123 currentLine.append(" <withPurging>"); | 127 currentLine.append(" <withPurging>"); |
124 } else if(flag == PictureResultsWriter::kAvg) { | 128 } else if(flag == PictureResultsWriter::kAvg) { |
125 currentLine.append(" <averaged>"); | 129 currentLine.append(" <averaged>"); |
126 } | 130 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 * } | 169 * } |
166 * ] | 170 * ] |
167 * } | 171 * } |
168 * ] | 172 * ] |
169 * } | 173 * } |
170 * ] | 174 * ] |
171 * }*/ | 175 * }*/ |
172 | 176 |
173 class PictureJSONResultsWriter : public PictureResultsWriter { | 177 class PictureJSONResultsWriter : public PictureResultsWriter { |
174 public: | 178 public: |
175 PictureJSONResultsWriter(const char filename[]) | 179 PictureJSONResultsWriter(const char filename[], |
176 : fFilename(filename), | 180 const char builderName[], |
jcgregorio
2014/06/23 19:02:44
Align with first param decl.
kelvinly
2014/06/23 20:32:46
Done.
| |
177 fRoot(), | 181 int buildNumber, |
178 fCurrentBench(NULL), | 182 int timestamp, |
179 fCurrentTileSet(NULL), | 183 const char gitHash[], |
180 fCurrentTile(NULL) {} | 184 int gitNumber) |
185 : fStream(filename), | |
jcgregorio
2014/06/23 19:02:44
I believe this should be:
: fStream(filename)
, f
kelvinly
2014/06/23 20:32:46
Won't compile the other way
jcgregorio
2014/06/23 20:40:44
Sorry, wasn't commenting on the order, just the fo
kelvinly
2014/06/23 20:49:27
Ah, my bad, fixed
| |
186 fParams(), | |
187 fConfigString() { | |
188 const char keys[6][32] = { | |
jcgregorio
2014/06/23 19:02:44
Why not const char *keys[6] = {"role", ...
Also,
kelvinly
2014/06/23 20:32:46
Moved this to a function in ResultsWriter.cpp, to
| |
189 "role", "os", "model", "gpu", "arch", "configuration"}; | |
190 const int numKeys = 6; | |
jcgregorio
2014/06/23 19:02:44
Is 6 just the size of keys? I'm pretty sure we hav
kelvinly
2014/06/23 20:32:46
Um, would you happen to know it off the top of you
jcgregorio
2014/06/23 20:40:44
Good question, I usually rely on grepping the sour
| |
191 fBuilderName = SkString(builderName); | |
192 fBuildNumber = buildNumber; | |
193 fTimestamp = timestamp; | |
194 fGitHash = SkString(gitHash); | |
195 fGitNumber = gitNumber; | |
196 fBuilderData = Json::Value(); | |
197 | |
198 if(fBuilderName.size() > 0) { | |
199 SkTArray<SkString> splitBuilder; | |
200 SkStrSplit(builderName, "-", &splitBuilder); | |
201 for(int i = 0; i < numKeys && i < splitBuilder.count(); i++) { | |
202 fBuilderData[keys[i]] = splitBuilder[i].c_str(); | |
203 } | |
204 fBuilderData["builderName"] = builderName; | |
205 if(numKeys < splitBuilder.count()) { | |
206 SkString extras; | |
207 for(int i = numKeys; i < splitBuilder.count(); i++) { | |
208 extras.append(splitBuilder[i]); | |
209 if(i != splitBuilder.count() - 1) { | |
210 extras.append("-"); | |
211 } | |
212 } | |
213 fBuilderData["badParams"] = extras.c_str(); | |
214 } | |
215 } | |
216 } | |
181 | 217 |
182 virtual void bench(const char name[], int32_t x, int32_t y) { | 218 virtual void bench(const char name[], int32_t x, int32_t y) { |
183 SkString sk_name(name); | 219 fBenchName = SkString(name); |
184 sk_name.append("_"); | |
185 sk_name.appendS32(x); | |
186 sk_name.append("_"); | |
187 sk_name.appendS32(y); | |
188 Json::Value* bench_node = SkFindNamedNode(&fRoot["benches"], sk_name.c_s tr()); | |
189 fCurrentBench = &(*bench_node)["tileSets"]; | |
190 } | 220 } |
191 virtual void tileConfig(SkString configName) { | 221 virtual void logRenderer(PictureRenderer* pr) { |
192 SkASSERT(fCurrentBench != NULL); | 222 fParams = pr->getJSONConfig(); |
193 fCurrentTileSet = SkFindNamedNode(fCurrentBench, configName.c_str()); | 223 fConfigString = pr->getConfigName(); |
194 fCurrentTile = &(*fCurrentTileSet)["tiles"][0]; | |
195 } | 224 } |
196 virtual void tileMeta(int x, int y, int tx, int ty) { | 225 // Apparently tiles aren't used, so tileMeta is empty |
197 SkASSERT(fCurrentTileSet != NULL); | 226 virtual void tileMeta(int x, int y, int tx, int ty) { ; } |
198 (*fCurrentTileSet)["tx"] = tx; | 227 // Same here |
jcgregorio
2014/06/23 19:02:44
As the code changes "Same here" may make less sens
kelvinly
2014/06/23 20:32:46
Done.
| |
199 (*fCurrentTileSet)["ty"] = ty; | 228 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) { ; } |
200 fCurrentTile = &(*fCurrentTileSet)["tiles"][x+tx*y]; | |
201 } | |
202 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) { | |
203 SkASSERT(fCurrentTile != NULL); | |
204 if(flag == PictureResultsWriter::kPurging) { | |
205 (*fCurrentTile)["flags"]["purging"] = true; | |
206 } else if(flag == PictureResultsWriter::kAvg) { | |
207 (*fCurrentTile)["flags"]["averaged"] = true; | |
208 } | |
209 } | |
210 virtual void tileData( | 229 virtual void tileData( |
211 TimerData* data, | 230 TimerData* data, |
212 const char format[], | 231 const char format[], |
213 const TimerData::Result result, | 232 const TimerData::Result result, |
214 uint32_t timerTypes, | 233 uint32_t timerTypes, |
215 int numInnerLoops = 1) { | 234 int numInnerLoops = 1) { |
216 SkASSERT(fCurrentTile != NULL); | 235 Json::Value newData = data->getJSON(timerTypes, result, numInnerLoops); |
217 (*fCurrentTile)["data"] = data->getJSON(timerTypes, result, numInnerLoop s); | 236 Json::Value combinedParams(fBuilderData); |
237 for(Json::ValueIterator iter = fParams.begin(); iter != fParams.end(); | |
238 iter++) { | |
239 combinedParams[iter.key().asString()]= *iter; | |
240 } | |
241 // For each set of timer data | |
242 for(Json::ValueIterator iter = newData.begin(); iter != newData.end(); | |
243 iter++) { | |
244 Json::Value data; | |
245 data["buildNumber"] = fBuildNumber; | |
246 data["timestamp"] = fTimestamp; | |
247 data["gitHash"] = fGitHash.c_str(); | |
248 data["gitNumber"] = fGitNumber; | |
249 data["isTrybot"] = fBuilderName.endsWith("Trybot"); | |
250 | |
251 data["params"] = combinedParams; | |
252 data["params"]["benchName"] = fBenchName.c_str(); | |
253 | |
254 // Not including skpSize because that's deprecated? | |
255 data["key"] = makeKey(iter.key().asString().c_str()).c_str(); | |
256 // Get the data | |
257 SkTArray<double> times; | |
258 Json::Value val = *iter; | |
259 for(Json::ValueIterator vals = val.begin(); vals != val.end(); | |
260 vals++) { | |
261 times.push_back((*vals).asDouble()); | |
262 } | |
263 // Because there's no sort I'll just remove the smallest | |
jcgregorio
2014/06/23 19:02:44
qsort?
kelvinly
2014/06/23 20:32:46
Can you get the raw array out of an SkTArray?
jcgregorio
2014/06/23 20:40:44
begin()?
On 2014/06/23 20:32:46, kelvinly wrote:
kelvinly
2014/06/23 20:49:27
I don't think we have a begin(): https://code.goog
jcgregorio
2014/06/23 20:52:59
Don't reference code.google.com, that's not canoni
kelvinly
2014/06/23 21:10:48
Fixed
| |
264 // 25% of values | |
265 int numValues = times.count(); | |
266 double currentMin = 10000000.0f; | |
267 for(int i = 0; i < numValues; i++) { | |
268 if(times[i] < currentMin) { | |
269 currentMin = times[i]; | |
270 } | |
271 } | |
272 for(int i = 0; i < numValues*0.25f; i++) { | |
273 double localMin = currentMin; | |
274 for(int j = 0; j < numValues; j++) { | |
275 if(times[i] > currentMin && times[i] < localMin) { | |
276 localMin = times[i]; | |
277 } | |
278 } | |
279 currentMin = localMin; | |
280 } | |
281 data["value"] = currentMin; | |
282 data["params"]["measurementType"] = iter.key().asString(); | |
283 fStream.writeText(Json::FastWriter().write(data).c_str()); | |
284 } | |
218 } | 285 } |
219 virtual void end() { | 286 virtual void end() { |
220 SkFILEWStream stream(fFilename.c_str()); | 287 fStream.flush(); |
221 stream.writeText(Json::FastWriter().write(fRoot).c_str()); | |
222 stream.flush(); | |
223 } | 288 } |
224 private: | 289 private: |
225 SkString fFilename; | 290 SkString makeKey(const char measurementType[]) { |
226 Json::Value fRoot; | 291 SkString tmp(fBuilderName); |
227 Json::Value *fCurrentBench; | 292 tmp.append("_"); |
228 Json::Value *fCurrentTileSet; | 293 tmp.append(fBenchName); |
229 Json::Value *fCurrentTile; | 294 tmp.append("_"); |
295 tmp.append(fConfigString); | |
296 tmp.append("_"); | |
297 tmp.append(measurementType); | |
298 return tmp; | |
299 } | |
300 | |
301 SkFILEWStream fStream; | |
302 Json::Value fBuilderData; | |
303 SkString fBenchName; | |
304 Json::Value fParams; | |
305 | |
306 SkString fConfigString; | |
307 SkString fBuilderName; | |
308 int fBuildNumber; | |
309 int fTimestamp; | |
310 SkString fGitHash; | |
311 int fGitNumber; | |
230 }; | 312 }; |
231 | 313 |
232 #endif | 314 #endif |
OLD | NEW |