1e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org/* 2e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org * Copyright 2013 Google Inc. 3e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org * 4e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 5e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org * found in the LICENSE file. 6e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org * 7e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org * Classes for writing out bench results in various formats. 8e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org */ 9f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina 10e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org#ifndef SkResultsWriter_DEFINED 11e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org#define SkResultsWriter_DEFINED 12e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org 13f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "BenchLogger.h" 14e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org#include "SkJSONCPP.h" 15877a52ae61f41f0b519a906ed2460d44746de8e1borenet#include "SkOSFile.h" 16e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org#include "SkStream.h" 17e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org#include "SkString.h" 18e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org#include "SkTypes.h" 19e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org 20e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org/** 21e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org * Base class for writing out the bench results. 22e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org * 231915b62637bea20e1471a8a358b22e9e47a4a385mtklein * Default implementation does nothing. 24e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org */ 25e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.orgclass ResultsWriter : SkNoncopyable { 26e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.orgpublic: 271915b62637bea20e1471a8a358b22e9e47a4a385mtklein virtual ~ResultsWriter() {} 28e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org 291915b62637bea20e1471a8a358b22e9e47a4a385mtklein // Record one key value pair that makes up a unique key for this type of run, e.g. 301915b62637bea20e1471a8a358b22e9e47a4a385mtklein // builder name, machine type, Debug/Release, etc. 311915b62637bea20e1471a8a358b22e9e47a4a385mtklein virtual void key(const char name[], const char value[]) {} 32bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 331915b62637bea20e1471a8a358b22e9e47a4a385mtklein // Record one key value pair that describes the run instance, e.g. git hash, build number. 341915b62637bea20e1471a8a358b22e9e47a4a385mtklein virtual void property(const char name[], const char value[]) {} 35e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org 361915b62637bea20e1471a8a358b22e9e47a4a385mtklein // Denote the start of a specific benchmark. Once bench is called, 37051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein // then config and metric can be called multiple times to record runs. 381915b62637bea20e1471a8a358b22e9e47a4a385mtklein virtual void bench(const char name[], int32_t x, int32_t y) {} 39e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org 401915b62637bea20e1471a8a358b22e9e47a4a385mtklein // Record the specific configuration a bench is run under, such as "8888". 411915b62637bea20e1471a8a358b22e9e47a4a385mtklein virtual void config(const char name[]) {} 42e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org 431915b62637bea20e1471a8a358b22e9e47a4a385mtklein // Record the options for a configuration, such as "GL_RENDERER". 441915b62637bea20e1471a8a358b22e9e47a4a385mtklein virtual void configOption(const char name[], const char* value) {} 45bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 461915b62637bea20e1471a8a358b22e9e47a4a385mtklein // Record a single test metric. 47051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein virtual void metric(const char name[], double ms) {} 48e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein 49e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein // Flush to storage now please. 50e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein virtual void flush() {} 51bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio}; 52bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 53bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio/** 54bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio NanoJSONResultsWriter writes the test results out in the following 55bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio format: 56bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 57bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio { 58bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio "key": { 59bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio "arch": "Arm7", 60bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio "gpu": "SGX540", 61bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio "os": "Android", 62bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio "model": "GalaxyNexus", 63bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 64bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio "gitHash": "d1830323662ae8ae06908b97f15180fd25808894", 651915b62637bea20e1471a8a358b22e9e47a4a385mtklein "build_number": "1234", 66bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio "results" : { 67bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio "Xfermode_Luminosity_640_480" : { 68bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio "8888" : { 69bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio "median_ms" : 143.188128906250, 70bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio "min_ms" : 143.835957031250, 71bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio ... 72bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio }, 73bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio ... 74bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio*/ 75bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorioclass NanoJSONResultsWriter : public ResultsWriter { 76bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregoriopublic: 771915b62637bea20e1471a8a358b22e9e47a4a385mtklein explicit NanoJSONResultsWriter(const char filename[]) 78bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio : fFilename(filename) 79bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio , fRoot() 80bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio , fResults(fRoot["results"]) 8196fcdcc219d2a0d3579719b84b28bede76efba64halcanary , fBench(nullptr) 8296fcdcc219d2a0d3579719b84b28bede76efba64halcanary , fConfig(nullptr) {} 831915b62637bea20e1471a8a358b22e9e47a4a385mtklein 841915b62637bea20e1471a8a358b22e9e47a4a385mtklein ~NanoJSONResultsWriter() { 85e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein this->flush(); 86bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 871915b62637bea20e1471a8a358b22e9e47a4a385mtklein 881915b62637bea20e1471a8a358b22e9e47a4a385mtklein // Added under "key". 89e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt void key(const char name[], const char value[]) override { 90bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio fRoot["key"][name] = value; 91bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 921915b62637bea20e1471a8a358b22e9e47a4a385mtklein // Inserted directly into the root. 93e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt void property(const char name[], const char value[]) override { 941915b62637bea20e1471a8a358b22e9e47a4a385mtklein fRoot[name] = value; 95bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 96e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt void bench(const char name[], int32_t x, int32_t y) override { 97bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio SkString id = SkStringPrintf( "%s_%d_%d", name, x, y); 98bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio fResults[id.c_str()] = Json::Value(Json::objectValue); 99bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio fBench = &fResults[id.c_str()]; 100bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 101e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt void config(const char name[]) override { 10249f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fBench); 103bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio fConfig = &(*fBench)[name]; 104bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 105e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt void configOption(const char name[], const char* value) override { 106bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio (*fConfig)["options"][name] = value; 107bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 108e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt void metric(const char name[], double ms) override { 109bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio // Don't record if nan, or -nan. 110bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio if (sk_double_isnan(ms)) { 111bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio return; 112bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 11349f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fConfig); 114e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org (*fConfig)[name] = ms; 115e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org } 11697133ade536f6333a2dbaec8be6f8347bb12bd79commit-bot@chromium.org 117e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein // Flush to storage now please. 118e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt void flush() override { 119877a52ae61f41f0b519a906ed2460d44746de8e1borenet SkString dirname = SkOSPath::Dirname(fFilename.c_str()); 120877a52ae61f41f0b519a906ed2460d44746de8e1borenet if (!sk_exists(dirname.c_str(), kWrite_SkFILE_Flag)) { 121877a52ae61f41f0b519a906ed2460d44746de8e1borenet if (!sk_mkdir(dirname.c_str())) { 122877a52ae61f41f0b519a906ed2460d44746de8e1borenet SkDebugf("Failed to create directory."); 123877a52ae61f41f0b519a906ed2460d44746de8e1borenet } 124877a52ae61f41f0b519a906ed2460d44746de8e1borenet } 125e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein SkFILEWStream stream(fFilename.c_str()); 126e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein stream.writeText(Json::StyledWriter().write(fRoot).c_str()); 127e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein stream.flush(); 128e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein } 129e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein 1301915b62637bea20e1471a8a358b22e9e47a4a385mtkleinprivate: 131e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org SkString fFilename; 132e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org Json::Value fRoot; 133e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org Json::Value& fResults; 134e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org Json::Value* fBench; 135e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org Json::Value* fConfig; 136e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org}; 137e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org 138bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 139e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org#endif 140