blob: a87cd20d6cf29ae6bae0fc7911c763bca6e482cc [file] [log] [blame] [edit]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ML_BENCHMARK_DRIVER_COMMON_UTILS_H_
#define ML_BENCHMARK_DRIVER_COMMON_UTILS_H_
#include <algorithm>
#include <cstdint>
#include <string>
#include <vector>
#include <base/check.h>
#include "proto/benchmark_config.pb.h"
namespace chrome {
namespace ml_benchmark {
// The percentiles expected to be reported in percentile_latencies_in_us in
// BenchmarkResults. May also be used for custom metrics, such as CPU time.
constexpr int32_t kLatencyPercentiles[] = {50, 90, 95, 99};
// Serializes a BenchmarkResults into a buffer as expected by benchmark_start.
// Allocates a buffer, whose location and size are returned in `results_data`
// and `results_size`, and must be freed using FreeSerializedResults.
int32_t SerializeResults(const BenchmarkResults& results,
void** results_data,
int32_t* results_size);
// Generates a BenchmarkResults proto containing an error code and message,
// and directly serializes it into a buffer as expected by benchmark_start.
// Allocates a buffer, whose location and size are returned in `results_data`
// and `results_size`, and must be freed using FreeSerializedResults.
int32_t SerializeError(const std::string& error_message,
BenchmarkReturnStatus status,
void** results_data,
int32_t* results_size);
// Frees a buffer returned by SerializeResults or SerializeError, as needed by
// free_benchmark_results. Does nothing if called with nullptr.
void FreeSerializedResults(void* results_data);
// Taken from chromium source cc/base/rolling_time_delta_history.cc
// http://shortn/_mIhMWhPIUF and simplified since we're using a vector
// and can index directly.
// `samples` should be sorted before calling.
// Returns the smallest sample that is greater than or equal to the specified
// percent of samples. If there aren't any samples, returns 0.
template <typename T>
T ComputePercentile(const std::vector<T>& samples, double percent) {
if (samples.size() == 0)
return T(0);
CHECK(std::is_sorted(samples.begin(), samples.end()));
double fraction = percent / 100.0;
if (fraction <= 0.0)
return *(samples.begin());
if (fraction >= 1.0)
return *(samples.rbegin());
size_t index = static_cast<size_t>(std::ceil(fraction * samples.size())) - 1;
return samples[index];
}
// Fills in percentile_latencies_in_us in `results` with the percentiles
// expected by the framework, as listed in kLatencyPercentiles.
// The percentiles are extracted from `latencies`, which must be given in
// microseconds, and must be sorted before calling.
template <typename T>
void SetPercentileLatencies(BenchmarkResults& results,
const std::vector<T>& latencies) {
auto& percentile_latencies = *results.mutable_percentile_latencies_in_us();
for (const int32_t percentile : kLatencyPercentiles) {
percentile_latencies[percentile] = ComputePercentile(latencies, percentile);
}
}
} // namespace ml_benchmark
} // namespace chrome
#endif // ML_BENCHMARK_DRIVER_COMMON_UTILS_H_