Skip to content

Commit

Permalink
improve accuracy of columns in CSV reports
Browse files Browse the repository at this point in the history
  • Loading branch information
sayon committed Dec 2, 2024
1 parent 2b79711 commit 40324a6
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 14 deletions.
34 changes: 22 additions & 12 deletions benchmark_analyzer/src/benchmark/format/csv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use std::fmt::Write;

use super::Benchmark;
use super::IBenchmarkSerializer;
use crate::benchmark::group::element::selector::Selector;
use crate::benchmark::group::element::Element;
use crate::benchmark::metadata::Metadata;

/// Serialize the benchmark to CSV in the following format:
/// "group_name", "element_name", "size_str", "cycles", "ergs", "gas"
Expand All @@ -18,23 +20,31 @@ impl IBenchmarkSerializer for Csv {

fn serialize_to_string(&self, benchmark: &Benchmark) -> Result<String, Self::Err> {
let mut result = String::with_capacity(estimate_csv_size(benchmark));
result.push_str(r#""group", "test", "size", "cycles", "ergs", "gas""#);
result.push_str(
r#""group", "mode", "path", "case", "input", "size", "cycles", "ergs", "gas""#,
);
result.push('\n');
for (group_name, group) in &benchmark.groups {
for (
element_name,
Element {
size,
cycles,
ergs,
gas,
},
) in &group.elements
for Element {
metadata:
Metadata {
selector: Selector { path, case, input },
mode,
group: _,
},
size,
cycles,
ergs,
gas,
} in group.elements.values()
{
let size_str = size.map_or(String::from(""), |s| format!("{}", s));
let size_str = size.map_or(String::from(""), |s| s.to_string());
let mode = mode.as_deref().unwrap_or_default();
let input = input.clone().map(|s| s.to_string()).unwrap_or_default();
let case = case.as_deref().unwrap_or_default();
writeln!(
&mut result,
"\"{group_name}\", \"{element_name}\", {size_str}, {cycles}, {ergs}, {gas}",
r#""{group_name}", "{mode}", "{path}", "{case}", "{input}", {size_str}, {cycles}, {ergs}, {gas}"#,
)?;
}
}
Expand Down
54 changes: 54 additions & 0 deletions benchmark_analyzer/src/benchmark/group/element/input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//!
//! Identifier for the test input. Describes the input type and position but not the actual contents.
//!
use serde::Deserialize;
use serde::Serialize;

///
/// Identifier for the test input. Describes the input type and position but not the actual contents.
///
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub enum Input {
/// The contract deploy, regardless of target.
Deployer {
/// Contract identifier, usually file name and contract name separated by a colon.
contract_identifier: String,
},
/// The contract call.
Runtime {
/// Index in the array of inputs.
input_index: usize,
/// Input name, provided in the test description.
name: String,
},
/// The storage empty check.
StorageEmpty {
/// Index in the array of inputs.
input_index: usize,
},
/// Check account balance.
Balance {
/// Index in the array of inputs.
input_index: usize,
},
}

impl std::fmt::Display for Input {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Input::Deployer {
contract_identifier,
} => f.write_fmt(format_args!("#deployer:{contract_identifier}")),
Input::Runtime { input_index, name } => {
f.write_fmt(format_args!("{name}:{input_index}"))
}
Input::StorageEmpty { input_index } => {
f.write_fmt(format_args!("#storage_empty_check:{input_index}"))
}
Input::Balance { input_index } => {
f.write_fmt(format_args!("#balance_check:{input_index}"))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@
//! The benchmark element.
//!
pub mod input;
pub mod selector;

use serde::Deserialize;
use serde::Serialize;

use crate::benchmark::metadata::Metadata;

///
/// The benchmark element.
///
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Element {
/// Associated metadata.
pub metadata: Metadata,
/// The contract size, `Some` for contracts deploys.
pub size: Option<usize>,
/// The number of cycles.
Expand All @@ -24,8 +31,15 @@ impl Element {
///
/// A shortcut constructor.
///
pub fn new(size: Option<usize>, cycles: usize, ergs: u64, gas: u64) -> Self {
pub fn new(
metadata: Metadata,
size: Option<usize>,
cycles: usize,
ergs: u64,
gas: u64,
) -> Self {
Self {
metadata,
size,
cycles,
ergs,
Expand Down
39 changes: 39 additions & 0 deletions benchmark_analyzer/src/benchmark/group/element/selector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//!
//! Test selector, unambiously locating a test suite, or a specific input.
//!
use serde::Deserialize;
use serde::Serialize;

use crate::benchmark::group::element::input::Input;

///
/// Test selector, unambiously locating a test suite, case, or input.
///
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Selector {
/// Path to the file containing test.
pub path: String,
/// Name of the case, if any. `None` means nameless case.
pub case: Option<String>,
/// Identifier of the specific input.
pub input: Option<Input>,
}

impl std::fmt::Display for Selector {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self {
path: filename,
case: case_name,
input,
} = self;
f.write_fmt(format_args!("{filename}"))?;
if let Some(case_name) = case_name {
f.write_fmt(format_args!("::{case_name}"))?;
}
if let Some(input) = input {
f.write_fmt(format_args!("[{input}]"))?;
}
Ok(())
}
}
27 changes: 27 additions & 0 deletions benchmark_analyzer/src/benchmark/metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//!
//! Information associated with the benchmark element.
//!
use serde::Deserialize;
use serde::Serialize;

use crate::benchmark::group::element::selector::Selector;

///
/// Encoded compiler mode. In future, it can be expanded into a structured type
/// shared between crates `benchmark_analyzer` and `compiler_tester`.
///
pub type Mode = String;

///
/// Information associated with the benchmark element.
///
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Metadata {
/// Test selector.
pub selector: Selector,
/// Compiler mode.
pub mode: Option<Mode>,
/// Test group
pub group: String,
}
1 change: 1 addition & 0 deletions benchmark_analyzer/src/benchmark/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
pub mod format;
pub mod group;
pub mod metadata;

use std::collections::BTreeMap;
use std::path::PathBuf;
Expand Down
3 changes: 3 additions & 0 deletions benchmark_analyzer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ pub(crate) mod benchmark;

pub use self::benchmark::format::csv::Csv as CsvSerializer;
pub use self::benchmark::format::json::Json as JsonSerializer;
pub use self::benchmark::group::element::input::Input;
pub use self::benchmark::group::element::selector::Selector as TestSelector;
pub use self::benchmark::group::element::Element as BenchmarkElement;
pub use self::benchmark::group::Group as BenchmarkGroup;
pub use self::benchmark::metadata::Metadata;
pub use self::benchmark::Benchmark;
///
/// The all elements group name.
Expand Down
27 changes: 27 additions & 0 deletions compiler_tester/src/summary/benchmark_adapters/input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//!
//! Converts `[InputIdentifier]` to the representation used by the benchmark.
//!
use crate::test::case::input::identifier::InputIdentifier;

///
/// Converts `[InputIdentifier]` to the representation used by the benchmark.
///
pub fn convert_input(input: InputIdentifier) -> benchmark_analyzer::Input {
match input {
InputIdentifier::Deployer {
contract_identifier,
} => benchmark_analyzer::Input::Deployer {
contract_identifier,
},
InputIdentifier::Runtime { input_index, name } => {
benchmark_analyzer::Input::Runtime { input_index, name }
}
InputIdentifier::StorageEmpty { input_index } => {
benchmark_analyzer::Input::StorageEmpty { input_index }
}
InputIdentifier::Balance { input_index } => {
benchmark_analyzer::Input::Balance { input_index }
}
}
}
30 changes: 30 additions & 0 deletions compiler_tester/src/summary/benchmark_adapters/metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//!
//! Converts `[TestDescription]` to the representation used by the benchmark.
//!
use crate::test::description::TestDescription;

use super::selector::convert_selector;

///
/// Converts `[TestSelector]` to the representation used by the benchmark.
///
pub fn convert_description(
description: &TestDescription,
default_group: &str,
) -> benchmark_analyzer::Metadata {
let TestDescription {
group,
mode,
selector,
} = description.clone();
let selector = convert_selector(selector);
let mode = mode.map(|m| m.to_string());
let group = group.unwrap_or(default_group.to_string());
benchmark_analyzer::Metadata {
selector,
mode,
group,
}
}
8 changes: 8 additions & 0 deletions compiler_tester/src/summary/benchmark_adapters/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//!
//! Adapters to convert the test information defined in `compiler_tester` to the
//! representation used by `benchmark_analyzer`.
//!
pub mod input;
pub mod metadata;
pub mod selector;
16 changes: 16 additions & 0 deletions compiler_tester/src/summary/benchmark_adapters/selector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//!
//! Converts `[TestSelector]` to the representation used by the benchmark.
//!
use crate::test::selector::TestSelector;

use super::input::convert_input;

///
/// Converts `[TestSelector]` to the representation used by the benchmark.
///
pub fn convert_selector(selector: TestSelector) -> benchmark_analyzer::TestSelector {
let TestSelector { path, case, input } = selector;
let input = input.map(convert_input);
benchmark_analyzer::TestSelector { path, case, input }
}
8 changes: 7 additions & 1 deletion compiler_tester/src/summary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
//! The compiler tester summary.
//!
pub mod benchmark_adapters;
pub mod element;

use std::sync::Arc;
use std::sync::Mutex;

use benchmark_adapters::metadata::convert_description;
use colored::Colorize;

use crate::test::case::input::output::Output;
Expand Down Expand Up @@ -143,8 +145,12 @@ impl Summary {
.as_ref()
.and_then(|mode| mode.llvm_optimizer_settings().cloned());

let metadata = {
let default_group = group.clone().unwrap_or_default();
convert_description(&element.test_description, &default_group)
};
let benchmark_element =
benchmark_analyzer::BenchmarkElement::new(size, cycles, ergs, gas);
benchmark_analyzer::BenchmarkElement::new(metadata, size, cycles, ergs, gas);
if let Some(group) = group {
let group_key = match mode {
Some(ref mode) => format!("{group} {mode}"),
Expand Down

0 comments on commit 40324a6

Please sign in to comment.