///|
/// A reproducible benchmark measurement row.
pub struct BenchmarkMeasurement {
name : String
workload : String
input_size : Int
operations : Int
checksum : String
notes : String
}
///|
/// Aggregate throughput metadata for benchmark output.
pub struct BenchmarkReport {
title : String
toolchain : String
measurements : Array[BenchmarkMeasurement]
total_operations : Int
total_input : Int
}
///|
/// Create an empty benchmark report.
pub fn BenchmarkReport::new(
title : String,
toolchain : String,
) -> BenchmarkReport {
{ title, toolchain, measurements: [], total_operations: 0, total_input: 0 }
}
///|
/// Add a measured workload row.
pub fn BenchmarkReport::add(
self : BenchmarkReport,
name : String,
workload : String,
input_size : Int,
operations : Int,
checksum : String,
notes : String,
) -> BenchmarkReport {
let measurements = self.measurements.copy()
measurements.push({ name, workload, input_size, operations, checksum, notes })
{
title: self.title,
toolchain: self.toolchain,
measurements,
total_operations: self.total_operations + operations.max(0),
total_input: self.total_input + input_size.max(0),
}
}
///|
/// Calculate a stable checksum for a numeric benchmark result.
pub fn benchmark_checksum(data : Array[Double]) -> String {
waveform_checksum(data)
}
///|
/// Create a measurement row from an output trace.
pub fn benchmark_trace_measurement(
name : String,
workload : String,
input : Trace,
output : Trace,
operations : Int,
notes : String,
) -> BenchmarkMeasurement {
{
name,
workload,
input_size: input.npts(),
operations,
checksum: benchmark_checksum(output.data),
notes,
}
}
///|
/// Export benchmark measurements as CSV.
pub fn benchmark_report_to_csv(report : BenchmarkReport) -> String {
let mut output = "name,workload,input_size,operations,checksum,notes\n"
for measurement in report.measurements {
output = output +
measurement.name +
"," +
measurement.workload +
"," +
measurement.input_size.to_string() +
"," +
measurement.operations.to_string() +
"," +
measurement.checksum +
"," +
measurement.notes +
"\n"
}
output
}
///|
/// Render a benchmark report in Markdown.
pub fn benchmark_report_to_markdown(report : BenchmarkReport) -> String {
let mut output = "# " +
report.title +
"\n\nToolchain: `" +
report.toolchain +
"`\n\n"
output += "| Workload | Input | Operations | Checksum |\n|---|---:|---:|---|\n"
for measurement in report.measurements {
output += "| " +
measurement.workload +
" | " +
measurement.input_size.to_string() +
" | " +
measurement.operations.to_string() +
" | `" +
measurement.checksum +
"` |\n"
}
output += "\nTotal input samples: " + report.total_input.to_string() + "\n"
output += "Total operations: " + report.total_operations.to_string() + "\n"
output
}
///|
/// Format benchmark report totals.
pub fn benchmark_report_summary(report : BenchmarkReport) -> String {
"measurements=" +
report.measurements.length().to_string() +
" input=" +
report.total_input.to_string() +
" operations=" +
report.total_operations.to_string()
}