Path: blob/main_old/src/tests/test_utils/runner/HistogramWriter.cpp
1694 views
//1// Copyright 2020 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// HistogramWriter:6// Helper class for writing histogram-json-set-format files to JSON.78#include "HistogramWriter.h"910#include "common/debug.h"1112#include <rapidjson/document.h>1314#if !defined(ANGLE_HAS_HISTOGRAMS)15# error "Must have histograms enabled"16#endif // !defined(ANGLE_HAS_HISTOGRAMS)1718ANGLE_DISABLE_EXTRA_SEMI_WARNING19ANGLE_DISABLE_EXTRA_SEMI_STMT_WARNING20ANGLE_DISABLE_DESTRUCTOR_OVERRIDE_WARNING21ANGLE_DISABLE_SUGGEST_OVERRIDE_WARNINGS22#include "tracing/tracing/value/diagnostics/reserved_infos.h"23#include "tracing/tracing/value/histogram.h"24ANGLE_REENABLE_SUGGEST_OVERRIDE_WARNINGS25ANGLE_REENABLE_DESTRUCTOR_OVERRIDE_WARNING26ANGLE_REENABLE_EXTRA_SEMI_STMT_WARNING27ANGLE_REENABLE_EXTRA_SEMI_WARNING2829namespace js = rapidjson;30namespace proto = catapult::tracing::tracing::proto;3132namespace angle33{34namespace35{36std::string GetUnitAndDirection(proto::UnitAndDirection unit)37{38ASSERT(unit.improvement_direction() == proto::SMALLER_IS_BETTER);39ASSERT(unit.unit() == proto::MS);40return "ms_smallerIsBetter";41}42} // namespace4344HistogramWriter::HistogramWriter() = default;4546HistogramWriter::~HistogramWriter() = default;4748void HistogramWriter::addSample(const std::string &measurement,49const std::string &story,50double value,51const std::string &units)52{53std::string measurementAndStory = measurement + story;54if (mHistograms.count(measurementAndStory) == 0)55{56proto::UnitAndDirection unitAndDirection;57unitAndDirection.set_improvement_direction(proto::SMALLER_IS_BETTER);58unitAndDirection.set_unit(proto::MS);5960std::unique_ptr<catapult::HistogramBuilder> builder =61std::make_unique<catapult::HistogramBuilder>(measurement, unitAndDirection);6263// Set all summary options as false - we don't want to generate metric_std, metric_count,64// and so on for all metrics.65builder->SetSummaryOptions(proto::SummaryOptions());66mHistograms[measurementAndStory] = std::move(builder);6768proto::Diagnostic stories;69proto::GenericSet *genericSet = stories.mutable_generic_set();70genericSet->add_values(story);71mHistograms[measurementAndStory]->AddDiagnostic(catapult::kStoriesDiagnostic, stories);72}7374mHistograms[measurementAndStory]->AddSample(value);75}7677void HistogramWriter::getAsJSON(js::Document *doc) const78{79proto::HistogramSet histogramSet;8081for (const auto &histogram : mHistograms)82{83std::unique_ptr<proto::Histogram> proto = histogram.second->toProto();84histogramSet.mutable_histograms()->AddAllocated(proto.release());85}8687// Custom JSON serialization for histogram-json-set.88doc->SetArray();8990js::Document::AllocatorType &allocator = doc->GetAllocator();9192for (int histogramIndex = 0; histogramIndex < histogramSet.histograms_size(); ++histogramIndex)93{94const proto::Histogram &histogram = histogramSet.histograms(histogramIndex);9596js::Value obj(js::kObjectType);9798js::Value name(histogram.name(), allocator);99obj.AddMember("name", name, allocator);100101js::Value description(histogram.description(), allocator);102obj.AddMember("description", description, allocator);103104js::Value unitAndDirection(GetUnitAndDirection(histogram.unit()), allocator);105obj.AddMember("unit", unitAndDirection, allocator);106107if (histogram.has_diagnostics())108{109js::Value diags(js::kObjectType);110111for (const auto &mapIter : histogram.diagnostics().diagnostic_map())112{113js::Value key(mapIter.first, allocator);114const proto::Diagnostic &diagnostic = mapIter.second;115116if (!diagnostic.shared_diagnostic_guid().empty())117{118js::Value guid(diagnostic.shared_diagnostic_guid(), allocator);119diags.AddMember(key, guid, allocator);120}121else if (diagnostic.has_generic_set())122{123const proto::GenericSet genericSet = diagnostic.generic_set();124125js::Value setObj(js::kObjectType);126setObj.AddMember("type", "GenericSet", allocator);127128js::Value values(js::kArrayType);129130for (const std::string &value : genericSet.values())131{132js::Value valueStr(value, allocator);133values.PushBack(valueStr, allocator);134}135136setObj.AddMember("values", values, allocator);137138diags.AddMember(key, setObj, allocator);139}140else141{142UNREACHABLE();143}144}145146obj.AddMember("diagnostics", diags, allocator);147}148149js::Value sampleValues(js::kArrayType);150151for (int sampleIndex = 0; sampleIndex < histogram.sample_values_size(); ++sampleIndex)152{153js::Value sample(histogram.sample_values(sampleIndex));154sampleValues.PushBack(sample, allocator);155}156157obj.AddMember("sampleValues", sampleValues, allocator);158159js::Value maxNumSamplesValues(histogram.max_num_sample_values());160obj.AddMember("maxNumSamplesValues", maxNumSamplesValues, allocator);161162if (histogram.has_bin_boundaries())163{164js::Value binBoundaries(js::kArrayType);165166const proto::BinBoundaries &boundaries = histogram.bin_boundaries();167for (int binIndex = 0; binIndex < boundaries.bin_specs_size(); ++binIndex)168{169js::Value binSpec(boundaries.bin_specs(binIndex).bin_boundary());170binBoundaries.PushBack(binSpec, allocator);171}172173obj.AddMember("binBoundaries", binBoundaries, allocator);174}175176if (histogram.has_summary_options())177{178const proto::SummaryOptions &options = histogram.summary_options();179180js::Value summary(js::kObjectType);181182js::Value avg(options.avg());183js::Value count(options.count());184js::Value max(options.max());185js::Value min(options.min());186js::Value std(options.std());187js::Value sum(options.sum());188189summary.AddMember("avg", avg, allocator);190summary.AddMember("count", count, allocator);191summary.AddMember("max", max, allocator);192summary.AddMember("min", min, allocator);193summary.AddMember("std", std, allocator);194summary.AddMember("sum", sum, allocator);195196obj.AddMember("summaryOptions", summary, allocator);197}198199if (histogram.has_running())200{201const proto::RunningStatistics &running = histogram.running();202203js::Value stats(js::kArrayType);204205js::Value count(running.count());206js::Value max(running.max());207js::Value meanlogs(running.meanlogs());208js::Value mean(running.mean());209js::Value min(running.min());210js::Value sum(running.sum());211js::Value variance(running.variance());212213stats.PushBack(count, allocator);214stats.PushBack(max, allocator);215stats.PushBack(meanlogs, allocator);216stats.PushBack(mean, allocator);217stats.PushBack(min, allocator);218stats.PushBack(sum, allocator);219stats.PushBack(variance, allocator);220221obj.AddMember("running", stats, allocator);222}223224doc->PushBack(obj, allocator);225}226227for (const auto &diagnosticIt : histogramSet.shared_diagnostics())228{229const proto::Diagnostic &diagnostic = diagnosticIt.second;230231js::Value obj(js::kObjectType);232233js::Value name(diagnosticIt.first, allocator);234obj.AddMember("name", name, allocator);235236switch (diagnostic.diagnostic_oneof_case())237{238case proto::Diagnostic::kGenericSet:239{240js::Value type("GenericSet", allocator);241obj.AddMember("type", type, allocator);242243const proto::GenericSet &genericSet = diagnostic.generic_set();244245js::Value values(js::kArrayType);246247for (const std::string &value : genericSet.values())248{249js::Value valueStr(value, allocator);250values.PushBack(valueStr, allocator);251}252253obj.AddMember("values", values, allocator);254break;255}256257default:258UNREACHABLE();259}260261doc->PushBack(obj, allocator);262}263}264} // namespace angle265266267